上篇文章介绍了模板匹配的效果,下面讲述一下模板匹配的一些其他情况,例如下图,有可能会有两个缺口滑块,需要匹配其中一个,或者是匹配的缺口奇形怪状,背景奇形怪状等等,这里只讲一下基本的处理方法,大致流程和上篇其实差不多,注意,此篇文章可能有点水
那么第一步,和上篇文章也是一样的处理情况,首先处理小滑块周围的空白填充像素,这里依然贴一下上篇的代码
# -*- coding: utf-8 -*-
import cv2
import numpy as np
import os
def cv_show(img): # 展示图片
cv2.imshow("img", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 转换颜色通道,保持颜色准确
# image = cv2.imread(r"1_1.jpg")
gap = cv2.imread(r"1_2.jpg")
# image_gray = cv2.cvtColor(image.copy(), cv2.COLOR_BGR2GRAY)
gap_gray = cv2.cvtColor(gap.copy(), cv2.COLOR_BGR2GRAY)
h, w = gap_gray.shape
w_start_index, h_start_index = 0, 0
w_end_index, h_end_index = w, h
# 缺口图去除背景
for i in range(h):
if not any(gap_gray[i, :]):
h_start_index = i
else:
break
for i in range(h - 1, 0, -1):
if not any(gap_gray[i, :]):
h_end_index = i
else:
break
for i in range(w):
if not any(gap_gray[:, i]):
w_start_index = i
else:
break
for i in range(w - 1, 0, -1):
if not any(gap_gray[:, i]):
w_end_index = i
else:
break
# 取出完整的缺口图
gap_gray = gap_gray[h_start_index:h_end_index+1, w_start_index:w_end_index+1]
cv_show(gap_gray)
上述的代码其实意图很明显,循环四次,分别是从上到下,从下到上,从左到右,从右到左,依次循环,当循环到,一行或者一列区域不相同的话,那么就视为已经接近缺口滑块,然后再根据索引进行分割,下面是展示灰度效果图
然后这边将根据上述的滑块一组一组处理,首先第一组,依然是使用常规的模板匹配处理方法,具体步骤原理,也可以查看上篇文章。
# -*- coding: utf-8 -*-
import cv2
import numpy as np
import os
def cv_show(img): # 展示图片
cv2.imshow("img", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 转换颜色通道,保持颜色准确
image = cv2.imread(r"1_1.jpg")
gap = cv2.imread(r"1_2.jpg")
image_gray = cv2.cvtColor(image.copy(), cv2.COLOR_BGR2GRAY)
gap_gray = cv2.cvtColor(gap.copy(), cv2.COLOR_BGR2GRAY)
h, w = gap_gray.shape
w_start_index, h_start_index = 0, 0
w_end_index, h_end_index = w, h
# 缺口图去除背景
for i in range(h):
if not any(gap_gray[i, :]):
h_start_index = i
else:
break
for i in range(h - 1, 0, -1):
if not any(gap_gray[i, :]):
h_end_index = i
else:
break
for i in range(w):
if not any(gap_gray[:, i]):
w_start_index = i
else:
break
for i in range(w - 1, 0, -1):
if not any(gap_gray[:, i]):
w_end_index = i
else:
break
# 取出完整的缺口图
gap_gray = gap_gray[h_start_index:h_end_index+1, w_start_index:w_end_index+1]
image_gray = cv2.adaptiveThreshold(image_gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY_INV, 5, 0)
gap_gray = cv2.adaptiveThreshold(gap_gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY_INV, 5, 0)
image_v1 = cv2.Canny(image_gray, 0, 500)
gray_v1 = cv2.Canny(gap_gray, 0, 500)
# cv_show(gray_v1)
result = cv2.matchTemplate(image_v1, gray_v1, cv2.TM_CCOEFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
x, y = max_loc
h, w = gap_gray.shape
result = np.array(image.copy())
color = (0, 0, 255)
# print(check_box)
cv2.rectangle(result, (x, y), (x + w, y + h), color, 2)
# res = np.hstack([image_gray,gray_v1, image_v1, result])
cv_show(result)
第三组效果成功
总结上述,模板匹配,如果背景图针对小图缺口有很多干扰的情况下,不一定次次都成功,像第三组,反而匹配到一个较为离谱的缺口去了,这里跟代码也相关,因为模板匹配最终匹配的是全局效果,从全局来看,算法认为第一个小缺口反而更匹配。