快速&在屏幕上快速模板匹配。也需要坐标。 Java的

时间:2015-06-01 16:53:25

标签: java opencv

我需要一种在屏幕上查找图像的方法。我已经在SO上搜索了这样做的方法,但有些需要花费很长时间。我需要它快速有效,不需要准确。基本上我打算在屏幕上比较或搜索一个小的像素化图像,例如11x10像素。

我还需要一种方法来了解屏幕上小图像的x和y坐标。

虽然我已经查看了很多像JavaCV和OpenCV这样的工具,但我只是想知道是否有其他方法可以做到这一点。

TL; DR

我需要一种快速的方法来在屏幕上搜索一个小的(11x10示例。)图像并知道它的x,y坐标。

2 个答案:

答案 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;
}

结果:

enter image description here

模板:

enter image description here