2D-Grafik Einfachster Ansatz, um sich wiederholende Figur in einem 2D-Image zu erkennen

abc66

Top Contributor
UseCase: Location (x,y,w,h...) des Schachbrettmusters (8*8 Schachfelder) in einem Bildschirmfoto erkennen.

Possible Approaches: Perceptual hashing, Patch correlation analysis, SIFT- oder RANSAC Algorithmus oder ?

Habt ihr (andere) Ideen dazu?
 
Naiver Ansatz:
Java:
import java.awt.AWTException;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;

public class App {
    static Loc getLoc(BufferedImage b) {
        for (int i = 0; i < b.getHeight(); i++) {
            for (int j = 0; j < b.getWidth(); j++) {
                Loc l = getLoc(b, j, i);
                if (l != null) {
                    return l;
                }
            }
        }
        return null;
    }

    static Loc getLoc(BufferedImage b, int x, int y) {
        if (x + 20 * 8 >= b.getWidth() || y + 20 * 8 >= b.getHeight())
            return null;

        int i = 1;
        int rgb = b.getRGB(x + 2, y + 2);
        while (    x + i + 2 < b.getWidth()
                && y + i + 2 < b.getHeight()
                && rgb == b.getRGB(x + i + 2, y + 2)
                && rgb == b.getRGB(x + 2, y + i + 2)) {
            i++;
        }
        i += 2;

        if (i < 20 || i > 150)
            return null;

        if (x + i * 8 >= b.getWidth() || y + i * 8 >= b.getHeight())
            return null;

        Loc l = getLoc(b, x, y, i);
        if (l != null) {
            return l;
        }

        return null;
    }

    static Loc getLoc(BufferedImage b, int x, int y, int len) {
        int rgb1 = b.getRGB(getX(x, len, 0), getY(y, len, 0));
        int rgb2 = b.getRGB(getX(x, len, 1), getY(y, len, 0));
        if (rgb1 == rgb2) {
            return null;
        }

        int failure = 0;
        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                int xa = getX(x, len, j);
                int ya = getY(y, len, i);
                int rgb = i % 2 == 0 ? (j % 2 == 0 ? rgb1 : rgb2) : (j % 2 == 0 ? rgb2 : rgb1);
                for (int k = 0; k < len - 2; k++) {
                    if (rgb != b.getRGB(xa + k, ya) || rgb != b.getRGB(xa, ya + k)) {
                        failure++;
                        if (failure > 4) {
                            return null;
                        }
                        break;
                    }
                }
            }
        }

        Loc l = new Loc();
        l.r = new Rectangle(x, y, len, len);
        return l;
    }

    static int getX(int x, int len, int i) {
        return x + (len) * i + 2;
    }

    static int getY(int y, int len, int j) {
        return y + (len) * j + 2;
    }

    public static void main(String[] args) throws AWTException, InterruptedException {
        Thread.sleep(5000);
        Robot r = new Robot();
        Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
        Rectangle rec = new Rectangle(d);
        BufferedImage b = r.createScreenCapture(rec);
        Loc l = getLoc(b);
       
    }
}

class Loc {
    Rectangle r;

    @Override
    public String toString() {
        return String.format("Loc [r=%s]", r);
    }
}

Laufzeit n²*² und nicht sehr robust!
 

Zurück
Oben