乐趣区

关于python:图像匹配大图中找小图之findtemplate源码解析续

明天把 matchTemplate 的返回值 res 再具体解释一下,这次把源图放大一点,便于调试数据。

源图

模板图

外围源码还是这段:

def find_all_template(im_source, im_search, threshold=0.5, maxcnt=0, rgb=False, bgremove=False):
    # 匹配算法,aircv 实际上在代码里写死了用 CCOEFF_NORMED,大部分测试的成果,也的确是这个算法更好
    method = cv2.TM_CCOEFF_NORMED
    # 获取匹配矩阵
    res = cv2.matchTemplate(im_source, im_search, method)
    w, h = im_search.shape[1], im_search.shape[0]
    result = []
    while True:
        # 找到匹配最大最小值
        min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
        top_left = max_loc
        if max_val < threshold:
            break
        # 计算中心点
        middle_point = (top_left[0]+w/2, top_left[1]+h/2)
        # 计算四个角的点,存入后果集
        result.append(dict(
            result=middle_point,
            rectangle=(top_left, (top_left[0], top_left[1] + h), (top_left[0] + w, top_left[1]), (top_left[0] + w, top_left[1] + h)),
            confidence=max_val
        ))
        # 把最匹配区域填充掉,再持续查找下一个
        cv2.floodFill(res, None, max_loc, (-1000,), max_val-threshold+0.1, 1, flags=cv2.FLOODFILL_FIXED_RANGE)
    return result

res = cv2.matchTemplate(im_source, im_search, method)这句执行之后,返回的 res 是什么样呢?咱们用 pycharm 社区版的 debug 调试性能,抉择“view as array”看一下:

四周一片蓝色的都是正数,两头越红的色彩数值越大,其中 10 行 10 列对应的一个像素值是 1,示意如果 image_template 对在这个点上,会齐全匹配。

由此找到第一个匹配的地位, 那么大图里还没有其余匹配地位呢? 当然有。察看 res 数组发现 (50,10) 像素的值也是 1,但 minMaxLoc 办法只能找到最大值和最小值,不能找到前面的数值,aircv 为了解决这个问题,是找到一个后,用 floodFill 填充它左近像素,再循环找下一个,填充之后的像素值为 -1000,间接变最小值:

这样下一次循环就能找到第 2 个匹配地位了。

你必定能看进去这个逻辑性能不佳,所以我当前会优化一下。

退出移动版