前言
本文仅为个人学习使用,使用python中的opencv库进行图像模板匹配,如有不对,还望指正
opencv进行图像匹配
第一步,导入相关的包
如果没有的话,请在终端执行pip install opencv-python
进行安装
import cv2 as cv
第二步,使用opencv中的函数imread()
导入图片,得到实例,这个实例其实就是一个矩阵
img = cv.imread("图片路径")
第三步,我们随意将原图片进行切割,得到切割下下来的图,后面我们将使用这个切割下来的图进行模板匹配,注意,原图并未改变,此处为值传递
代码语言:txt复制img2 = img[100:150,100:150]
第四步,使用匹配锁定函数matchTemplate()
mt = cv.matchTemplate(img,img2,1)
解释一下这个函数,第一个参数是原图,第二个参数为匹配图,感觉有点没说清楚,就是拿img2到img上去匹配,注意img2要小于img,最后一个参数是模式选择,这个模式选择我们需要着重讲一下:
matchTemplate
函数的常用可选模式有
- cv.TM_SQDIFF_NORMED 平方差匹配法
cv.TM_SQDIFF_NORMED方法是一种匹配模板的方法,它计算目标图像和模板图像之间的差异,并返回最小差异的位置。它计算目标图像和模板图像的差的平方,并将差的平方和作为匹配结果。匹配结果越小,表示匹配程度越好。可以在传参时缩写为数字1,在上面的例子中就是写的缩写形式1。
- cv.TM_CCORR_NORMED 相关匹配法
它计算目标图像和模板图像的像素值相关系数,并将相关系数作为匹配结果。
相关系数越大,表示匹配程度越好。 可以缩写为3。
- cv.TM_CCOEFF_NORMED 相关系数匹配法
相关系数匹配法也是一种基于像素值相关性的匹配方法,但与相关匹配法不同,它使用的是归一化的相关系数。
归一化的相关系数在-1和1之间,表示匹配程度的相似度。
归一化相关系数越接近1,表示匹配程度越好 , 缩写为数字5。
这个函数返回的结果是还是一个矩阵,但是里面的值,根据模式的选择就不一样了
第五步,根据模式的选择,进行相关数据的提取,此处我们用minMaxLoc()
函数来进行相关数据的提取。
min,max,minLocation,maxlocation = minMaxLoc(mt) # mt为前面匹配锁定函数得到的
然后minLocation
是最小值的位置,maxLocation
是最大值的位置,就是都有x和y
第六步,根据得到的x和y进行相关数据的计算,方便我们在原图像上画出矩形,进行图像展示,此处主要考验思维能力。
如果是模式选择为1的话,也就是平方差匹配法,那我们应该选择最小的值,最小的地方,就是匹配度最高的,具体原因看上面的模式的介绍。
然后我们就进行相关数据的计算,我们先提取所查找区域的高度和宽度。
代码语言:txt复制w,h = img2.shape[:2]
然后再最小点加上最高宽度和高度,得到的就是我们所查找的区域
代码语言:txt复制br = (w minLocation[0],h minLocation[1])
然后我们在原图形上画矩形,用的是rectangle函数,我们将所匹配到的区域,画一个矩形框起来
代码语言:txt复制cv.rectangle(img,minLocation,br,(0,0,255),2)
第一个参数是原图片,第二个和第三个是矩形的两点,第四个参数是矩形的宽度
然后我们再展示图片,最后面的那两个是用来指定关闭的。
代码语言:txt复制cv.imshow("img",img)
cv.imshow("img2",img2)
cv.waitKey(0)
cv.destroyAllWindows()
效果如下图
完整代码如下
代码语言:txt复制import cv2 as cv
if __name__ == '__main__':
img = cv.imread("../images/lena-raw.jpeg")
img2 = img[100:150,100:150]
xishu = cv.matchTemplate(img,img2,3)
print("xishu",xishu)
min,max,minlocation,maxlocation = cv.minMaxLoc(xishu)
h,w = img2.shape[:2]
tr = (w maxlocation[0],h maxlocation[1])
print("tr",tr)
cv.rectangle(img,maxlocation,tr,(0, 0, 255),2)
cv.imshow("img",img)
cv.imshow("img2",img2)
cv.waitKey(0)
cv.destroyAllWindows()
总结
使用opencv进行图像匹配,其实最重要的就是matchTemplate
函数的使用,我们需要根据匹配模式的不同,进行相关后续的操作。