任务是需要在搜索图当中找到和模板图相似的位置,然后进行相减得到缺陷的位置(绿色区域)。但是在使用opencv的templatematch进行模板匹配时,最佳匹配值特别低而且匹配位置也不对。我数过像素了,其实搜索图和模板图的线路宽度差只有两三个像素,已经高度一致了。所以问题出在了哪里,应该怎么解决模板匹配的问题以及后续计算图像差异的方法是什么.
为了方便回答,我放入自己的代码和检测结果,但是结果很小,maxval只有0.3.应该怎么样提高这个准确率,一直对这个不满意。
import numpy as np
import argparse
import imutils
import glob
import cv2
import datetime
# 读取模板图片 matching4.png template_bina.jpg
template = cv2.imread("template1_bina.bmp")
# 转换为灰度图片
template = cv2.cvtColor(template, cv2.COLOR_BGR2GRAY)
# 执行边缘检测
template = cv2.Canny(template, 50, 200)
(tH, tW) = template.shape[:2]
# 显示模板
# cv2.imshow("Template", template)
# 读取测试图片并将其转化为灰度图片
image = cv2.imread("search4.jpg")
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
found = None
highest_matching_value = (0, 0)
window_size = (1640, 1360) # 滑动窗口的大小
step_size = 1000 # 步长
start_angle = 1.7
end_angle = 1.8
step = 0.001
scale_array = np.linspace(0.8, 1.0, 20)
scale_array = np.append((0.905, 0.91, 0.9103), scale_array)
for scale in scale_array[::-1]:
# 根据尺度大小对输入图片进行裁剪
resized = imutils.resize(gray, width=int(gray.shape[1] * scale))
r = gray.shape[1] / float(resized.shape[1])
# 如果裁剪之后的图片小于模板的大小直接退出
if resized.shape[0] < tH or resized.shape[1] < tW:
break
for angle in np.arange(start_angle, end_angle, step):
center = (resized.shape[1] // 2, resized.shape[0] // 2)
rotation_matrix = cv2.getRotationMatrix2D(center, angle, 1.0)
rotated_image = cv2.warpAffine(resized, rotation_matrix, (resized.shape[1], resized.shape[0]))
# 首先进行边缘检测,然后执行模板检测,接着获取最小外接矩形
edged = cv2.Canny(rotated_image, 50, 200)
result = cv2.matchTemplate(edged, template, cv2.TM_CCOEFF_NORMED)
(_, maxVal, _, maxLoc) = cv2.minMaxLoc(result)
# 如果发现一个新的关联值则进行更新
if found is None or maxVal > found[0]:
found = (maxVal, maxLoc, r, angle, scale)
print(maxVal, maxLoc, scale, angle)
(maxVal, maxLoc, r, angle, scale) = found
center = (image.shape[1] // 2, image.shape[0] // 2)
rotation_matrix = cv2.getRotationMatrix2D(center, angle, 1.0)
rotated_image = cv2.warpAffine(image, rotation_matrix, (gray.shape[1], gray.shape[0]))
# 计算测试图片中模板所在的具体位置,即左上角和右下角的坐标值,并乘上对应的裁剪因子
(startX, startY) = (int(maxLoc[0] * r) + highest_matching_value[0],
int(maxLoc[1] * r) + (highest_matching_value[1]))
(endX, endY) = (int((maxLoc[0] + tW) * r) + highest_matching_value[0],
int((maxLoc[1] + tH) * r) + highest_matching_value[1])
print(maxVal, scale, angle)
c = rotated_image[startY:endY, startX:endX]
cv2.imwrite('matching4.bmp', c)
cv2.rectangle(rotated_image, (startX, startY), (endX, endY), (0, 0, 255), 2)
cv2.imwrite('matching_rect4.bmp', rotated_image)
cv2.waitKey(0)