图像匹配(大图中找小图)之find_template源码解析续
今天把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
【图像匹配(大图中找小图)之find_template源码解析续】
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个匹配位置了。
你肯定能看出来这个逻辑性能不佳,所以我以后会优化一下。
推荐阅读
- 我要做大厨
- 《真与假的困惑》???|《真与假的困惑》??? ——致良知是一种伟大的力量
- 知识
- 三十年后的广场舞大爷
- 奔向你的城市
- 村里的故事|村里的故事 --赵大头
- 期刊|期刊 | 国内核心期刊之(北大核心)
- 华为旁!大社区、地铁新盘,佳兆业城市广场五期!
- 汇讲-勇于突破
- 每日一话(49)——一位清华教授在朋友圈给大学生的9条建议