0

我正在尝试按照此处所述进行操作:在 Numpy 图像中查找子图像,以便能够在屏幕截图中搜索图像。

代码如下所示:

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),如示例所示。

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

4

1 回答 1

0

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

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 返回的结果转换为您想要的信息。如果您想知道模板在哪里匹配最差,或者结果在最佳和最差匹配时保持什么值,您也可以使用这些值。

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

于 2013-08-08T22:52:28.520 回答