aircv是网易放出的小开源我的项目,应该也是当初做简略图像匹配被援用最多的我的项目了。上一篇做了如何应用aircv之find_template的形容,然而,它并不算是一个成熟的我的项目,外面的小坑不少,有待改良。明天先做个代码逻辑的解析。
外围函数find_template 与 find_all_template
find_template函数是返回第一个最匹配的后果(地位未必在最下面),而find_all_template是返回所有大于指定置信度的后果。
比方要在思否页面截图中找
后果如如下图所示:
咱们深刻进去看一下代码,就会发现find_template是这样写的:
def find_template(im_source, im_search, threshold=0.5, rgb=False, bgremove=False): ''' @return find location if not found; return None ''' result = find_all_template(im_source, im_search, threshold, 1, rgb, bgremove) return result[0] if result else None
好家伙! 间接调用find_all_template,而后取返回值的第一个。。。
所以find_all_template才是真正的外围,咱们排除掉无关代码,来看一下最要害的局部:
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
其中cv2.matchTemplate
是opencv的办法,它的返回值是个矩阵,相当于用小图在大图上滑动,从左上角开始,每次挪动一个像素,而后计算一个匹配后果,最终造成后果矩阵。
后果矩阵大小应该是: (W - w + 1) x (H - h + 1),其中W,H是大图的宽高, w和h是小图的宽高。
这个矩阵中最大值的那个点,就示意小图的左上角对在这个地位时,匹配度最高,由此失去第一个匹配后果。
最初cv2.floodFill
的作用,是把后果矩阵最大值这块区域用别的数字填充掉,这样就能够查找下一个最大值了,而且也防止了区域重叠的景象(要不然下一个最大值,有可能在刚刚找到的区域外面)。
几个小问题
- 不反对灰度图和带通明通道的图
其实opencv的matchTemplate原本只反对灰度图,但大多数状况下,咱们都是查找黑白图,所以aircv封装的时候,把bgr三个黑白通道做了拆散,别离调用matchTemplate,而后再合并后果。
但这个封装没有兼容原本就是灰度图的状况,居然会出错,而且如果源图带通明通道也会出错,为此,我专门提交了一个PR,但始终没有解决,看来我的项目曾经没人保护了。
- floodFill貌似有点调兵遣将了,numpy的切片应该能够实现
这个回头写段小代码验证一下 - 不能解决图片的缩放
模板图片和原图中的内容,并不一定大小严格统一的,那么就须要做一些缩放解决,反复尝试。 - 图像匹配成果不现实
如果是完全一致的图,find_template的成果十分好,但当须要含糊匹配时,某些人眼一看就雷同的图像,是无奈被辨认进去的,有点时候又会误辨认,这可能须要从两方面改良:
-- 调整算法:采纳SIFT之类的特色点检测算法,能够解决大小和角度都不统一的图像匹配问题;Halcon等商业软件,采纳了shape based matching,匹配成果更佳。
-- 退出信息:有时候除了模板图像自身,咱们兴许晓得更多的信息,比方图像可能呈现的地位范畴,图像周边区域的款式等等,来帮忙晋升辨认准确度,缩小误识和漏识。