
import java.awt.AWTException;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import javax.swing.JFrame;
public class FindTemplate {
    public static class HoughLine {
        private double theta;
        private int r;
        public HoughLine(double theta, int r) {
            this.theta = theta;
            this.r = r;
        }
        public double getTheta() {
            return theta;
        }
        public void setTheta(double theta) {
            this.theta = theta;
        }
        public int getR() {
            return r;
        }
        public void setR(int r) {
            this.r = r;
        }
        public void drawLine(Graphics2D g2d, Color col, int w) {
            double startX = 0;
            double startY = r;
            double endX = startX + w * Math.sin(theta);
            double endY = startY + w * Math.cos(theta);
            g2d.setColor(col);
            g2d.drawLine((int) startX, (int) startY, (int) endX, (int) endY);
        }
    }
    public static void main(String[] args) throws AWTException, InterruptedException {
        Robot robot = new Robot();
        Rectangle rect = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
        Thread.sleep(10_000);
        BufferedImage img = robot.createScreenCapture(rect);
        ArrayList<FindTemplate.HoughLine> lines = getLines(img, 30);
        JFrame f = new JFrame();
        Canvas c = new Canvas() {
            private static final long serialVersionUID = 1L;
            @Override
            public void paint(Graphics g) {
                Graphics2D g2d = (Graphics2D) g;
                for (HoughLine houghLine : lines) {
                    houghLine.drawLine(g2d, Color.red, this.getWidth());
                }
            }
        };
        f.add(c);
        f.setSize(rect.getSize());
        f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        f.setVisible(true);
    }
    public static ArrayList<HoughLine> getLines(BufferedImage img, int threshold) {
        // The size of the neighbourhood in which to search for other local maxima
        final int neighbourhoodSize = 4;
        // Calculate the maximum height the hough array needs to have
        final int houghHeight = (int) (Math.sqrt(2) * Math.max(img.getHeight(), img.getWidth())) / 2;
        // Double the height of the hough array to cope with negative r values
        final int doubleHeight = 2 * houghHeight;
        // How many discrete values of theta shall we check?
        final int maxTheta = 180;
        // Using maxTheta, work out the step
        final double thetaStep = Math.PI / maxTheta;
        // Create the hough array
        final int[][] houghArray = new int[maxTheta][doubleHeight];
        // Find edge points and vote in array
        final int centerX = img.getWidth() / 2;
        final int centerY = img.getHeight() / 2;
        // cache the values of sin and cos for faster processing
        final double[] sinCache = new double[maxTheta];
        final double[] cosCache = sinCache.clone();
        for (int t = 0; t < maxTheta; t++) {
            double realTheta = t * thetaStep;
            sinCache[t] = Math.sin(realTheta);
            cosCache[t] = Math.cos(realTheta);
        }
        // Now find edge points and update the hough array
        for (int x = 0; x < img.getWidth(); x++) {
            for (int y = 0; y < img.getHeight(); y++) {
                // Go through each value of theta
                for (int t = 0; t < maxTheta; t++) {
                    // Work out the r values for each theta step
                    int r = (int) (((x - centerX) * cosCache[t]) + ((y - centerY) * sinCache[t]));
                    // this copes with negative values of r
                    r += houghHeight;
                    if (r < 0 || r >= doubleHeight)
                        continue;
                    // Increment the hough array
                    houghArray[t][r]++;
                }
            }
        }
        // Initialise the vector of lines that we'll return
        ArrayList<HoughLine> lines = new ArrayList<HoughLine>(20);
        // Only proceed if the hough array is not empty
        // if (numPoints == 0) return lines;
        // Search for local peaks above threshold to draw
        for (int t = 0; t < maxTheta; t++) {
            loop: for (int r = neighbourhoodSize; r < doubleHeight - neighbourhoodSize; r++) {
                // Only consider points above threshold
                if (houghArray[t][r] > threshold) {
                    int peak = houghArray[t][r];
                    // Check that this peak is indeed the local maxima
                    for (int dx = -neighbourhoodSize; dx <= neighbourhoodSize; dx++) {
                        for (int dy = -neighbourhoodSize; dy <= neighbourhoodSize; dy++) {
                            int dt = t + dx;
                            int dr = r + dy;
                            if (dt < 0)
                                dt = dt + maxTheta;
                            else if (dt >= maxTheta)
                                dt = dt - maxTheta;
                            if (houghArray[dt][dr] > peak) {
                                // found a bigger point nearby, skip
                                continue loop;
                            }
                        }
                    }
                    // calculate the true value of theta
                    double theta = t * thetaStep;
                    // add the line to the vector
                    lines.add(new HoughLine(theta, r));
                }
            }
        }
        return lines;
    }
}// Find non-black pixels
if ((image.getRGB(x, y) & 0x000000ff) != 0) {import java.awt.*;
import java.awt.color.*;
import java.awt.image.*;
import java.io.File;
import javax.imageio.*;
public class Test {
    private BufferedImage laplace(BufferedImage source) {
        ConvolveOp op = new ConvolveOp(new Kernel(3, 3, new float[] {
             0f,  -1f,  0f,
            -1f,   4f,  -1f,
             0f,  -1f,  0f
        }));
        return op.filter(source, null);
    }
    private BufferedImage grayscale(BufferedImage source) {
        ColorConvertOp op = new ColorConvertOp(
                ColorSpace.getInstance(ColorSpace.CS_GRAY), null);
        return op.filter(source, null);
    }
    public static void main(String[] args) throws Exception {
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        GraphicsDevice screen = ge.getDefaultScreenDevice();
        GraphicsConfiguration config = screen.getDefaultConfiguration();
        Rectangle bounds = config.getBounds();
        Robot r = new Robot(screen);
        BufferedImage img = r.createScreenCapture(bounds);
        Test t = new Test();
        
        ImageIO.write(t.laplace(t.grayscale(img)), "jpg", new File("test.jpg"));
    }
}Wenn die Größe, Farben und Helligkeiten fix sind, kannst Du einfach Punkt für Punkt vergleichen.Hallo, wie (also mit welchem Algorithmus) kann ich die Position dieses charakteristischen Musters auf dem Bildschirm:
Also ich habe letztens viel an einem OCR-Programm gearbeitet.// Find non-black pixels if ((image.getRGB(x, y) & 0x000000ff) != 0)
Lieber andersOder anders, wie ich die Linien einzeichnen kann.
Wärst du so freundlich, und würdest das bitte erläutern?x*cos(t) + y*sin(t) = r
<=> x = (r-y*sin(t)) / cos(t)
für y = 0 ist dann x = r/cos(t) und für y = height gilt x = (r-height*sin(t)) / cos(t)
        public void drawLine(Graphics2D g2d, Color col, int h) {
            double x1 = r * Math.sin(theta);
            double y1 = r * Math.cos(theta);
            double x2 = x1 + h * Math.sin(-theta);
            double y2 = y1 + h * Math.cos(-theta);
            // (x1,y1), (x2,y2) sind zwei Punkte auf der Geraden
//            double endX = startX + w * Math.sin(theta);
//            double endY = startY + w * Math.cos(theta);
            g2d.setColor(col);
            g2d.drawLine((int) ?, (int) 0, (int) ?, (int) h);
        }Örks, das dürfte falsch gewesen sein (=> Kreislinie)Wärst du so freundlich, und würdest das bitte erläutern?
Hrhrhr, ich auch... mein Gehirn ist im Moment gebraten 😬bin momentan fertig
        public void drawLine(Graphics2D g2d, Color col, int w, int h) {
            double x1 = r * Math.sin(theta) - w / 2;
            double y1 = r * Math.cos(theta) - h / 2;
            double a = -x1 / Math.sin(-theta);
            double b = -y1 / Math.cos(-theta);
            double x2 = x1 + a * Math.sin(-theta);
            double y2 = y1 + b * Math.cos(-theta);
            g2d.setColor(col);
            g2d.drawLine((int) x2, (int) y2, (int) w, (int) h);
        }    BufferedImage img2 = new ConvolveOp(new Kernel(3, 3, new float[] { 0f, -1f, 0f, -1f, 4f, -1f, 0f, -1f, 0f })).filter(new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_GRAY), null).filter(img, null), null);
    try {
        ImageIO.write(img2, "png", new File("testimg1.png"));
    } catch (IOException e) {
        e.printStackTrace();
    }
Ich hätte jetzt einfach malEhrlich gesagt, hilft mir das überhaupt nicht weiter...
int y(int x) {
   return (int)((r - x*Math.cos(theta)) / Math.sin(theta));
}g.drawLine(0, y(0), width, y(width));Aber nicht jede Linie beginnt bei x=0 (denke an horizontale oder vertikale Linien...)g.drawLine(0, y(0),
Und nicht jede Linie geht bis ganz nach untenwidth, y(width)
Hab schon alles durchprobiert, aber ich komme da auf keinen grünen Zweig.Dann zieh es halt von der Bildhöhe ab.
import java.awt.AWTException;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.awt.image.ConvolveOp;
import java.awt.image.Kernel;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
public class FindTemplate {
    public static class HoughLine {
        private double theta;
        private int r;
        public HoughLine(double theta, int r) {
            this.theta = theta;
            this.r = r;
        }
        public double getTheta() {
            return theta;
        }
        public void setTheta(double theta) {
            this.theta = theta;
        }
        public int getR() {
            return r;
        }
        public void setR(int r) {
            this.r = r;
        }
        private int y(int x) {
            return (int) ((r - x * Math.cos(theta)) / Math.sin(theta));
        }
        public void drawLine(Graphics2D g2d, Color col, int w, int h) {
            double x1 = r * Math.sin(theta) - h / 2;
            double y1 = r * Math.cos(theta) - h / 2;
//            double a = -x1 / -Math.sin(t);
//            double b = -y1 / -Math.cos(t);
            double x2 = x1 + 10 * -Math.sin(theta);
            double y2 = y1 + 10 * -Math.cos(theta);
            g2d.setColor(col);
            g2d.drawLine((int) x1, (int) y1, (int) x2, (int) y2);
        }
    }
    public static void main(String[] args) throws AWTException, InterruptedException {
        Robot robot = new Robot();
        Rectangle rect = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
        Thread.sleep(10_000);
        BufferedImage img = robot.createScreenCapture(rect);
        ArrayList<FindTemplate.HoughLine> lines = getLines(img, 175);
        JFrame f = new JFrame();
        Canvas c = new Canvas() {
            private static final long serialVersionUID = 1L;
            @Override
            public void paint(Graphics g) {
                Graphics2D g2d = (Graphics2D) g;
                for (HoughLine houghLine : lines) {
                    houghLine.drawLine(g2d, Color.red, this.getHeight(), this.getHeight());
                }
            }
        };
        f.add(c);
        f.setSize(rect.getSize());
        f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        f.setVisible(true);
    }
    public static ArrayList<HoughLine> getLines(BufferedImage img, int threshold) {
        // The size of the neighbourhood in which to search for other local maxima
        final int neighbourhoodSize = 4;
        // Calculate the maximum height the hough array needs to have
        final int houghHeight = (int) (Math.sqrt(2) * Math.max(img.getHeight(), img.getWidth())) / 2;
        // Double the height of the hough array to cope with negative r values
        final int doubleHeight = 2 * houghHeight;
        // How many discrete values of theta shall we check?
        final int maxTheta = 180;
        // Using maxTheta, work out the step
        final double thetaStep = Math.PI / maxTheta;
        // Create the hough array
        final int[][] houghArray = new int[maxTheta][doubleHeight];
        // Find edge points and vote in array
        final int centerX = img.getWidth() / 2;
        final int centerY = img.getHeight() / 2;
        // cache the values of sin and cos for faster processing
        final double[] sinCache = new double[maxTheta];
        final double[] cosCache = sinCache.clone();
        for (int t = 0; t < maxTheta; t++) {
            double realTheta = t * thetaStep;
            sinCache[t] = Math.sin(realTheta);
            cosCache[t] = Math.cos(realTheta);
        }
        BufferedImage img2 = new ConvolveOp(new Kernel(3, 3, new float[] { 0f, -1f, 0f, -1f, 4f, -1f, 0f, -1f, 0f })).filter(new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_GRAY), null).filter(img, null), null);
        try {
            ImageIO.write(img2, "png", new File("testimg1.png"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        // Now find edge points and update the hough array
        for (int x = 0; x < img2.getWidth(); x++) {
            for (int y = 0; y < img2.getHeight(); y++) {
                // Find non-black pixels
                if ((img2.getRGB(x, y) & 0x000000ff) != 0) {
                    // Go through each value of theta
                    for (int t = 0; t < maxTheta; t++) {
                        // Work out the r values for each theta step
                        int r = (int) (((x - centerX) * cosCache[t]) + ((y - centerY) * sinCache[t]));
                        // this copes with negative values of r
                        r += houghHeight;
                        if (r < 0 || r >= doubleHeight)
                            continue;
                        // Increment the hough array
                        houghArray[t][r]++;
                    }
                }
            }
        }
        // Initialise the vector of lines that we'll return
        ArrayList<HoughLine> lines = new ArrayList<HoughLine>(20);
        // Only proceed if the hough array is not empty
        // if (numPoints == 0) return lines;
        // Search for local peaks above threshold to draw
        for (int t = 0; t < maxTheta; t++) {
            loop: for (int r = neighbourhoodSize; r < doubleHeight - neighbourhoodSize; r++) {
                // Only consider points above threshold
                if (houghArray[t][r] > threshold) {
                    int peak = houghArray[t][r];
                    // Check that this peak is indeed the local maxima
                    for (int dx = -neighbourhoodSize; dx <= neighbourhoodSize; dx++) {
                        for (int dy = -neighbourhoodSize; dy <= neighbourhoodSize; dy++) {
                            int dt = t + dx;
                            int dr = r + dy;
                            if (dt < 0)
                                dt = dt + maxTheta;
                            else if (dt >= maxTheta)
                                dt = dt - maxTheta;
                            if (houghArray[dt][dr] > peak) {
                                // found a bigger point nearby, skip
                                continue loop;
                            }
                        }
                    }
                    // calculate the true value of theta
                    double theta = t * thetaStep;
                    // add the line to the vector
                    lines.add(new HoughLine(theta, r));
                }
            }
        }
        return lines;
    }
}Am besten, direkt mit einer Lösung.OK, schau ich mir später mal an.
import java.awt.AWTException;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.awt.image.ConvolveOp;
import java.awt.image.Kernel;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
public class FindTemplate {
    public static class HoughLine {
        private double theta;
        private int r;
        public HoughLine(double theta, int r) {
            this.theta = theta;
            this.r = r;
        }
        public double getTheta() {
            return theta;
        }
        public void setTheta(double theta) {
            this.theta = theta;
        }
        public int getR() {
            return r;
        }
        public void setR(int r) {
            this.r = r;
        }
        private int y(int x, int realR) {
            return (int) ((realR - x * Math.cos(theta)) / Math.sin(theta));
        }
        public void drawLine(Graphics2D g2d, Color col, int w, int h) {
            final int houghHeight = (int) (Math.sqrt(2) * Math.max(w, h)) / 2;
            int realR = r - houghHeight;
            double x1, y1, x2, y2;
            if (theta != 0.0) {
                x1 = 0;
                y1 = h/2 + y(0, realR);
                x2 = w;
                y2 = h/2 + y(w, realR);
            } else {
                System.out.println("r" +  r);                
                
                x1 = x2 = w/2 + realR;
                y1 = 0;
                y2 = h;
            }
            g2d.setColor(col);
            g2d.drawLine((int) x1, (int) y1, (int) x2, (int) y2);
        }
        public String toString() {
            return String.format("(\u03b8,r)=(%f,%d)", theta, r);
        }
        public String toString(int width, int height) {
            final int houghHeight = (int) (Math.sqrt(2) * Math.max(width, height)) / 2;
            return String.format("(\u03b8,r)=(%f,%d)", theta, r - houghHeight);
        }
    }
    public static void main(String[] args) throws Exception {
/*
        Robot robot = new Robot();
        Rectangle rect = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
        Thread.sleep(10_000);
        BufferedImage img = robot.createScreenCapture(rect);
        Rectangle rect = new Rectangle(500, 500);
        BufferedImage img = new BufferedImage(rect.width, rect.height, BufferedImage.TYPE_INT_RGB);
        Graphics g = img.createGraphics();
        g.setColor(Color.BLACK);
        g.fillRect(0, 0, img.getWidth(), img.getHeight());
        int size = 200;
        g.setColor(Color.WHITE);
        g.fillRect((rect.width - size)/2, (rect.height - size)/2, size, size);
        g.setColor(Color.YELLOW);
        g.fillRect((rect.width - size)/2 - 59, (rect.height - size)/2 - 50, size, size);
        g.dispose();
*/
        BufferedImage img = ImageIO.read(new File("testinput.png"));
        Rectangle rect = new Rectangle(0, 0, img.getWidth(), img.getHeight());
        ArrayList<FindTemplate.HoughLine> lines = getLines(img, 30);
        BufferedImage img2 = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_INT_RGB);
        Graphics g = img2.createGraphics();
        Graphics2D g2d = (Graphics2D) g;
        g.drawImage(img, 0, 0, null);
        for (HoughLine houghLine : lines) {
            houghLine.drawLine(g2d, Color.red, rect.width, rect.height);
        }
        g.dispose();
        ImageIO.write(img2, "png", new File("testoutput.png"));
        JFrame f = new JFrame();
        Canvas c = new Canvas() {
            private static final long serialVersionUID = 1L;
            @Override
            public void paint(Graphics g) {
                g.drawImage(img2, 0, 0, null);
            }
        };
        f.add(c);
        f.setSize(rect.getSize());
        f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        f.setVisible(true);
    }
    public static ArrayList<HoughLine> getLines(BufferedImage img, int thresholdPct) {
        // The size of the neighbourhood in which to search for other local maxima
        final int neighbourhoodSize = 4;
        // Calculate the maximum height the hough array needs to have
        final int houghHeight = (int) (Math.sqrt(2) * Math.max(img.getHeight(), img.getWidth())) / 2;
        // Double the height of the hough array to cope with negative r values
        final int doubleHeight = 2 * houghHeight;
        // How many discrete values of theta shall we check?
        final int maxTheta = 180;
        // Using maxTheta, work out the step
        final double thetaStep = Math.PI / maxTheta;
        // Create the hough array
        final int[][] houghArray = new int[maxTheta][doubleHeight];
        // Find edge points and vote in array
        final int centerX = img.getWidth() / 2;
        final int centerY = img.getHeight() / 2;
        // cache the values of sin and cos for faster processing
        final double[] sinCache = new double[maxTheta];
        final double[] cosCache = sinCache.clone();
        for (int t = 0; t < maxTheta; t++) {
            double realTheta = t * thetaStep;
            sinCache[t] = Math.sin(realTheta);
            cosCache[t] = Math.cos(realTheta);
        }
        BufferedImage img2 = new ConvolveOp(new Kernel(3, 3, new float[] { 0f, -1f, 0f, -1f, 4f, -1f, 0f, -1f, 0f })).filter(new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_GRAY), null).filter(img, null), null);
        try {
            ImageIO.write(img2, "png", new File("testimg1.png"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        // Now find edge points and update the hough array
        int maxIntensity = 0;
        for (int x = 0; x < img2.getWidth(); x++) {
            for (int y = 0; y < img2.getHeight(); y++) {
                // Find non-black pixels
                if ((img2.getRGB(x, y) & 0x000000ff) != 0) {
                    // Go through each value of theta
                    for (int t = 0; t < maxTheta; t++) {
                        // Work out the r values for each theta step
                        int r = (int) (((x - centerX) * cosCache[t]) + ((y - centerY) * sinCache[t]));
                        // this copes with negative values of r
                        r += houghHeight;
                        if (r < 0 || r >= doubleHeight)
                            continue;
                        // Increment the hough array
                        houghArray[t][r]++;
                        maxIntensity = Math.max(maxIntensity, houghArray[t][r]);
                    }
                }
            }
        }
        BufferedImage img3 = new BufferedImage(maxTheta, doubleHeight, BufferedImage.TYPE_INT_RGB);
        for (int y = 0; y < doubleHeight; y++) {
            for (int x = 0; x < maxTheta; x++) {
                int intensity = (int)(houghArray[x][y] * 255L / maxIntensity);
                int rgb = intensity << 16 | intensity << 8 | intensity;
                img3.setRGB(x, y, rgb);
            }
        }
        try {
            ImageIO.write(img3, "png", new File("testimg2.png"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        
        // Initialise the vector of lines that we'll return
        ArrayList<HoughLine> lines = new ArrayList<HoughLine>(20);
        // Only proceed if the hough array is not empty
        // if (numPoints == 0) return lines;
        double threshold = maxIntensity * thresholdPct / 100.0;
        // Search for local peaks above threshold to draw
        for (int t = 0; t < maxTheta; t++) {
            loop: for (int r = neighbourhoodSize; r < doubleHeight - neighbourhoodSize; r++) {
                // Only consider points above threshold
                if (houghArray[t][r] > threshold) {
                    int peak = houghArray[t][r];
                    // Check that this peak is indeed the local maxima
                    for (int dx = -neighbourhoodSize; dx <= neighbourhoodSize; dx++) {
                        for (int dy = -neighbourhoodSize; dy <= neighbourhoodSize; dy++) {
                            int dt = t + dx;
                            int dr = r + dy;
                            if (dt < 0)
                                dt = dt + maxTheta;
                            else if (dt >= maxTheta)
                                dt = dt - maxTheta;
                            if (houghArray[dt][dr] > peak) {
                                // found a bigger point nearby, skip
                                continue loop;
                            }
                        }
                    }
                    // calculate the true value of theta
                    double theta = t * thetaStep;
                    if (t < 5 || t > 88 && t < 92) {
                        lines.add(new HoughLine(theta, r));
                    }
                }
            }
        }
        return lines;
    }
}
