在某些场景下,直接使用二值化,可能无法找到 ROI,基于投影的思路可以适当考虑,其原理如下:
对于以下图片,我们需要定位其中的金属部分,以下分别采样模板匹配、基于投影的思路去实现
![基于投影定位ROI-20250201155823]()
基于投影的思路
首先是制作模板,通过模板查找图片的 ROI
![基于投影定位ROI-20250201155823-1]()
这里分别尝试 6 种模板匹配方法,发现只有 3 种方法能正确匹配
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| template_img=cv2.imread('template.png',0)
methods = ['cv2.TM_CCOEFF', 'cv2.TM_CCOEFF_NORMED', 'cv2.TM_CCORR', 'cv2.TM_CCORR_NORMED', 'cv2.TM_SQDIFF', 'cv2.TM_SQDIFF_NORMED'] h, w = template_img.shape
all_result=[] for method in methods: res = cv2.matchTemplate(gray, template_img, eval(method)) min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res) if method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]: top_left = min_loc else: top_left = max_loc bottom_right = (top_left[0] + w, top_left[1] + h) img_copy=img.copy() cv2.rectangle(img_copy, top_left, bottom_right, 255, 4) all_result.append(img_copy)
show_images(all_result,titles=methods,nrows=2)
|
![基于投影定位ROI-20250201155823-2]()
如果选择其中有效的方法应用到其他图片时,发现有些图片无法定位到 ROI,因此模板匹配不适合本场景下的 ROI 提取
![基于投影定位ROI-20250201155824]()
基于投影定位 ROI
将图片转为灰度图,观察 ROI 所在目标区域
![基于投影定位ROI-20250201155824-1]()
首先目标所在区域的纵向是稳定的暗区域,假设我们统计所有纵向的灰度值等于 200 的像素,我们可以发现以下规律
![基于投影定位ROI-20250201155824-2]()
通过上图,很容易定位目标所在横向范围在 [1500,2500] 之间,将这个范围的区域取出后,得到以下结果,下图分别是原图、纵向定位图和对应的原始图片
![基于投影定位ROI-20250201155825]()
基于以上的定位图,再进行横向分析,得到以下统计图
![基于投影定位ROI-20250201155825-1]()
如此,就很容易定位到 ROI 所在的纵向位置了,后续如果我们想定位出白色文字的位置,也可以通过以上投影的方法分析