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) Da muss ich später nochmal in mich gehen, bin momentan fertig...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;
}
}