【问题标题】:Finding small image inside large (PIL + OpenCV)在大中寻找小图像(PIL + OpenCV)
【发布时间】:2013-06-29 22:05:29
【问题描述】:

我正在尝试按照此处所述进行操作:Finding a subimage inside a Numpy image 以便能够在屏幕截图中搜索图像。

代码如下:

import cv2
import numpy as np
import gtk.gdk
from PIL import Image

def make_screenshot():
    w = gtk.gdk.get_default_root_window()
    sz = w.get_size()
    pb = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8, sz[0], sz[1])
    pb = pb.get_from_drawable(w, w.get_colormap(), 0, 0, 0, 0, sz[0], sz[1])
    width, height = pb.get_width(), pb.get_height()
    return Image.fromstring("RGB", (width, height), pb.get_pixels())

if __name__ == "__main__":
    img = make_screenshot()
    cv_im = cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR)
    template = cv_im[30:40, 30:40, :]
    result = cv2.matchTemplate(cv_im, template, cv2.TM_CCORR_NORMED)
    print np.unravel_index(result.argmax(), result.shape)

根据选择的方法(而不是 cv2.TM_CCORR_NORMED),我得到完全不同的坐标,但它们都不是示例中的 (30, 30)。

请教我,这种方法有什么问题?

【问题讨论】:

  • matchtemplate 为您提供矩形周围对象的左上角。你检查了吗?
  • 是的,我知道,它给了我 (0, 0) 或 (256, 400) 或类似的东西。没有什么接近现实。

标签: python opencv numpy python-imaging-library


【解决方案1】:

简短回答:您需要使用以下行来定位最佳匹配的角:

minVal, maxVal, minLoc, maxLoc = cv2.minMaxLoc(result)

变量 maxLoc 将保存一个元组,其中包含最佳匹配左上角的 x、y 索引。

长答案:

cv2.matchTemplate() 返回一个单通道图像,其中每个索引处的数字对应于输入图像与该索引处模板的匹配程度。尝试通过在调用 matchTemplate 之后插入以下代码行来可视化结果,你会明白为什么 numpy 很难理解它。

cv2.imshow("Debugging Window", result)
cv2.waitKey(0)
cv2.destroyAllWindows()

minMaxLoc() 将 matchTemplate 返回的结果转换为您想要的信息。如果您想知道模板在哪里匹配最差,或者结果在最佳匹配和最差匹配中保持什么值,您也可以使用这些值。

此代码适用于我从文件中读取的示例图像。如果您的代码继续行为不端,您可能没有按照您想要的方式阅读图像。上面的 sn-p 代码对于使用 OpenCV 进行调试很有用。将 imshow 中的参数结果替换为任何图像对象(numpy 数组)的名称,以直观地确认您正在获取所需的图像。

【讨论】:

    猜你喜欢
    • 2021-08-01
    • 2012-12-01
    • 1970-01-01
    • 2015-07-02
    • 1970-01-01
    • 2017-04-01
    • 2012-10-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多