我需要一种在屏幕上查找图像的方法。我已经在SO上搜索了这样做的方法,但有些需要花费很长时间。我需要它快速有效,不需要准确。基本上我打算在屏幕上比较或搜索一个小的像素化图像,例如11x10像素。
我还需要一种方法来了解屏幕上小图像的x和y坐标。
虽然我已经查看了很多像JavaCV和OpenCV这样的工具,但我只是想知道是否有其他方法可以做到这一点。
我需要一种快速的方法来在屏幕上搜索一个小的(11x10示例。)图像并知道它的x,y坐标。
答案 0 :(得分:1)
我认为你很多人发现this answer相关!但它适用于Windows&在c ++中。但我确信你可以很容易地将它转换成任何语言。
答案 1 :(得分:0)
这个问题已经很老了,但我试图在这里完成同样的事情。我发现结合这些答案可以解决问题:
Convert BufferedImage TYPE_INT_RGB to OpenCV Mat Object
OpenCV Template Matching example in Android
您需要进行转换的原因是因为当您使用awt.Robot类以INT_RGB格式获取屏幕截图时。匹配模板示例需要字节,您无法直接从此类图像中获取字节数据。
继承我对这两个答案的实施,但这是不完整的。输出全部搞砸了,我认为它可能与IntBuffer / ByteBuffers有关。
- 编辑 -
我添加了一个新的帮助方法,将INT_RGB转换为BYTE_BGR。我现在可以使用matchLoc在图像上获取模板的坐标。这似乎工作得很好,我能够使用这个机器人根据模板为我点击开始菜单。
private BufferedImage FindTemplate() {
System.out.println("\nRunning Template Matching");
int match_method = Imgproc.TM_SQDIFF;
BufferedImage screenShot = null;
try {
Robot rob = new Robot();
screenShot = rob.createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()));
} catch (AWTException ex) {
Logger.getLogger(MainGUI.class.getName()).log(Level.SEVERE, null, ex);
}
if(screenShot == null) return;
Mat img = BufferedImageToMat(convertIntRGBTo3ByteBGR(screenShot));
String templateFile = "C:\\Temp\\template1.JPG";
Mat templ = Highgui.imread(templateFile);
// / Create the result matrix
int result_cols = img.cols() - templ.cols() + 1;
int result_rows = img.rows() - templ.rows() + 1;
Mat result = new Mat(result_rows, result_cols, CvType.CV_32FC1);
// / Do the Matching and Normalize
Imgproc.matchTemplate(img, templ, result, match_method);
Core.normalize(result, result, 0, 1, Core.NORM_MINMAX, -1, new Mat());
Highgui.imwrite("out2.png", result);
// / Localizing the best match with minMaxLoc
MinMaxLocResult mmr = Core.minMaxLoc(result);
Point matchLoc;
if (match_method == Imgproc.TM_SQDIFF
|| match_method == Imgproc.TM_SQDIFF_NORMED) {
matchLoc = mmr.minLoc;
} else {
matchLoc = mmr.maxLoc;
}
Graphics2D graphics = screenShot.createGraphics();
graphics.setColor(Color.red);
graphics.setStroke(new BasicStroke(3));
graphics.drawRect(matchLoc.x, matchLoc.y, templ.width(), templ.height());
graphics.dispose();
return screenShot;
}
private Mat BufferedImageToMat(BufferedImage img){
int[] data = ((DataBufferInt) img.getRaster().getDataBuffer()).getData();
ByteBuffer byteBuffer = ByteBuffer.allocate(data.length * 4);
IntBuffer intBuffer = byteBuffer.asIntBuffer();
intBuffer.put(data);
Mat mat = new Mat(img.getHeight(), img.getWidth(), CvType.CV_8UC3);
mat.put(0, 0, byteBuffer.array());
return mat;
}`
private BufferedImage convertIntRGBTo3ByteBGR(BufferedImage img){
BufferedImage convertedImage = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_3BYTE_BGR);
Graphics2D graphics = convertedImage.createGraphics();
graphics.drawImage(img, 0, 0, null);
graphics.dispose();
return convertedImage;
}
结果:
模板: