opencv学习(单模块匹配)
目录
1.什么是模块匹配
2.常见的函数(cv2.matchTemplate()和cv2.minMaxLoc())
(1)cv2.matchTemplate(img,template,method)
(2)cv2.minMaxLoc(result)
3.输入要求
4.绘制模板匹配的矩形
参数说明:
5.示例
1.什么是模块匹配
用于在一张源图像中寻找与模板图像(已知的小图像)最相似的区域。
算法通过在源图像上滑动模板图像,逐一计算模板与每个位置的子区域的相似度,最终找到相似度最高的区域,即为模板在源图像中的匹配位置。
在 OpenCV 中,cv2.matchTemplate()
函数就是实现模板匹配的工具,配合cv2.minMaxLoc()
可以快速找到最佳匹配位置。
2.常见的函数(cv2.matchTemplate()和cv2.minMaxLoc())
(1)cv2.matchTemplate(img,template,method)
通过在源图像上滑动模板图像,计算模板与源图像各子区域的匹配程度,从而找出源图像中与模板最相似的位置。常用于目标检测、图像定位等场景,例如在一张照片中寻找特定物体的位置。
返回值:该函数返回一个单通道灰度图像(数组),即图像尺寸大小是(原图像H-模板h+1,原图像W-模板w+1),表示表示模板图像与源图像中以(原图像H-模板h+1,原图像W-模板w+1) 为左上角的子区域的匹配程度。并且可以通过 cv2.minMaxLoc()
可以快速找到最佳匹配位置。
匹配方法(method):
cv2.TM_CCOEFF:相关系数匹配,值越大匹配越好。
cv2.TM_CCOEFF_NORMED:归一化相关系数匹配,取值范围[0,1],1表示完美匹配。
cv2.TM_SQDIFF:平方差匹配,值越小匹配越好。
cv2.TM_SQDIFF_NORMED:归一化平方差匹配,取值范围[0,1],0表示完美匹配。
(2)cv2.minMaxLoc(result)
其中result是cv2.matchTemplate()的返回值。
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(src[, mask])
- 参数:
src
:输入的单通道数组(如模板匹配的结果result
)。mask
(可选):掩码数组,用于指定只在掩码为非零的区域内查找极值。
- 返回值:
min_val
:数组中的最小值。max_val
:数组中的最大值。min_loc
:最小值所在的坐标 (x, y),若数组为空则返回None
。max_loc
:最大值所在的坐标 (x, y),若数组为空则返回None
。
3.输入要求
必须是单通道数组,若处理彩色图像,需先转为灰度图(如 cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
)。
4.绘制模板匹配的矩形
cv2.rectangle()用于在图像上绘制矩形的函数,常用于标记目标区域(如模板匹配后的结果、目标检测的边界框等)。
cv2.rectangle(img, pt1, pt2, color, thickness=None, lineType=None, shift=None)
参数说明:
-
img
:输入图像(需要在这张图上绘制矩形),会被直接修改(原地操作)。 -
pt1
:矩形的左上角顶点坐标,格式为(x1, y1)
(x 是水平方向坐标,y 是垂直方向坐标)。 -
pt2
:矩形的右下角顶点坐标,格式为(x2, y2)
。 -
color
:矩形的颜色。- 对于灰度图(单通道),是一个灰度值(如
255
表示白色)。 - 对于彩色图(BGR 格式),是一个三元组
(b, g, r)
(如(0, 255, 0)
表示绿色)。
- 对于灰度图(单通道),是一个灰度值(如
-
thickness
(可选):矩形边框的厚度(像素)。- 正数:边框的厚度(如
2
表示 2 像素宽的边框)。 cv2.FILLED
或-1
:表示填充矩形内部(实心矩形)。
- 正数:边框的厚度(如
-
lineType
(可选):边框的线型(如cv2.LINE_8
为默认的 8 连通线,cv2.LINE_AA
为抗锯齿线,绘制更平滑)。 -
shift
(可选):坐标点的小数位数(默认 0,即整数坐标)
该函数没有返回值,直接在输入图像上进行绘制矩形。
5.示例
import cv2
import matplotlib.pyplot as plt
import numpy as npimg1=cv2.imread('structure.png')
img=cv2.resize(img1,(0,0),fx=0.6,fy=0.6)
img=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
template=cv2.imread('structure1.png',cv2.IMREAD_COLOR)
template=cv2.cvtColor(template,cv2.COLOR_BGR2GRAY)
h,w=template.shape[:2]
print(img.shape,' ',template.shape)
def cv_show(name,img):cv2.imshow(name,img)cv2.waitKey(0)cv2.destroyAllWindows()
cv_show('img',img)
cv_show('template',template)#单模板匹配
'''
差值平方和匹配 CV_TM_SQDIFF
标准化差值平方和匹配 CV_TM_SQDIFF_NORMED
相关匹配 CV_TM_CCORR
标准相关匹配 CV_TM_CCORR_NORMED
相关匹配 CV_TM_CCOEFF
标准相关匹配 CV_TM_CCOEFF_NORMED
'''
#cv2.matchTemplate() 的工作方式是:将模板图像在原始图像上从左到右、从上到下滑动,每次滑动一个像素,就计算一次模板与当前位置的匹配程度
res=cv2.matchTemplate(img,template,cv2.TM_SQDIFF_NORMED)
print(res.shape)#res.shape = (H - h + 1, W - w + 1)H,W是原始图像高度和宽度,
min_val,max_val,min_loc,max_loc=cv2.minMaxLoc(res)
print(min_val)
print(max_val)
print(min_loc)
print(max_loc)#开始绘制模板匹配的矩形
top_left=min_loc#是坐标,当然有[0],[1]啦
bottom_right=(top_left[0]+w,top_left[1]+h)
draw_img=img.copy()
res=cv2.rectangle(draw_img,top_left,bottom_right,255,2)
cv_show('rea',res)
import cv2 as cv #用 cv 代替 cv2 调用函数,例如 cv.imread() 比 cv2.imread() 更简洁。
methods = ['cv.TM_CCOEFF', 'cv.TM_CCOEFF_NORMED', 'cv.TM_CCORR','cv.TM_CCORR_NORMED', 'cv.TM_SQDIFF', 'cv.TM_SQDIFF_NORMED']
for meth in methods:img2 = img.copy()#匹配方法的真值method =eval(meth)print(method)res = cv2.matchTemplate(img2,template,method)min_val1, max_val1, min_loc1, max_loc1 =cv2.minMaxLoc(res)#如果是平方差匹配TW SQDIFF或归一化平方差匹配TM SQDIFF NORMED,取最小值if method in [cv2.TM_SQDIFF,cv2.TM_SQDIFF_NORMED]:top_left1 =min_loc1else:top_left1= max_locbottom_right =(top_left[0]+ w, top_left[1]+ h)
#画矩形cv2.rectangle(img2, top_left1,bottom_right, (255,0,0),2)plt.subplot(121), plt.imshow(res)plt.title('result'), plt.xticks([]), plt.yticks([])plt.subplot(122), plt.imshow(img2)plt.title('spot'), plt.xticks([]), plt.yticks([])plt.suptitle(meth)plt.show()