当前位置:   article > 正文

Opencv——图像模板匹配_opencv图像匹配算法

opencv图像匹配算法

引言

什么是模板匹配呢?

327df6f91bdc433caeb0aaf4ebabd539.pngeabc19158f064318a92b93837724b0b8.pngf41146f204fa4a7a8327a0d6571f9347.pngb42ef5a65f354673be7ebfeb592a4764.png676da60d94b244059893fdacb3f6932c.png

看到这里大家是否会觉得很熟悉的感觉涌上心头!在人脸识别是不是也会看见 等等。

模板匹配可以看作是对象检测的一种非常基本的形式。使用模板匹配,我们可以使用包含要检测对象的“模板”来检测输入图像中的对象。

一、匹配方法:cv2.matchTemplate(img, templ, method)


参数:(img: 原始图像、temple: 模板图像、method: 匹配度计算方法)

方法如下: 

cv2.TM_SQDIFF: 计算平方差,计算结果越小,越相关

公式:

f2d42349cb3044af8a3b1de3e95b3224.png

cv2.TM_CCORR: 计算相关性,计算出来的值越大,越相关

公式:

5959580199b14d46bacfd017385eb220.png

cv2.TM_CCOEFF: 计算相关系数,计算出的值越大,越相关

公式:30e0fcf913844c6eaccca4535fe54e87.png

cv2.TM_SQDIFF_NORMED: 计算归一化平方差,计算结果越接近0,越相关

公式:

3843088607e547a4b6888c4a937b9c4f.png

 

cv2.TM_CCORR_NORMED: 计算归一化相关性,计算结果越接近1,越相关

公式:

c9dfee05a780452ca4c8136d284a57f8.png

cv2.TM_CCOEFF_NORMED: 计算归一化相关系数,计算结果越接近1,越相关

 公式:

9c9800d317044e61a05554357d1a93ba.png

 二、匹配单个对象

img代表原始图像,template代表模板窗口,1默认为cv2.TM_SQDIFF方法

res = cv2.matchTemplate(img, template, 1) 

 获取结果的最值和最值位置(最值位置是左上角的坐标位置,通过模板的宽和高可以在原图上把模板位置画出来)

min_val,max_val,min_loc,max_loc = cv2.minMaxLoc(res)

 完整的代码:

  1. import cv2
  2. import numpy as np
  3. import matplotlib.pyplot as plt
  4. def cv_show(name,img):
  5. cv2.imshow(name,img)
  6. cv2.waitKey(0)
  7. cv2.destroyAllWindows()
  8. img=cv2.imread('C:/Users/bwy/Desktop/7.png',0)
  9. template=cv2.imread('C:/Users/bwy/Desktop/8.png',0)
  10. methods=['cv2.TM_CCOEFF','cv2.TM_CCOEFF_NORMED','cv2.TM_CCORR','cv2.TM_CCORR_NORMED'
  11. ,'cv2.TM_SQDIFF','cv2.TM_SQDIFF_NORMED']
  12. for meth in methods:
  13. img3=img.copy()
  14. method=eval(meth)
  15. print(meth)
  16. res1=cv2.matchTemplate(img,template,method)
  17. min_val,max_val,min_loc,max_loc = cv2.minMaxLoc(res1)
  18. if method in [cv2.TM_SQDIFF,cv2.TM_SQDIFF_NORMED]:
  19. top_left=min_loc
  20. else:
  21. top_left=max_loc
  22. bottom_right=(top_left[0]+w,top_left[1]+h)
  23. #俩矩形
  24. cv2.rectangle(img3,top_left,bottom_right,255,2)
  25. plt.subplot(121),plt.imshow(res1,cmap='gray')
  26. plt.xticks([]),plt.yticks([])#隐藏坐标轴
  27. plt.subplot(122),plt.imshow(img3,cmap='gray')
  28. plt.xticks([]),plt.yticks([])#隐藏坐标轴
  29. plt.suptitle(meth)
  30. plt.show()

结果如图所示:

13a1be4fdea64e6382e1c1e0b82c9d80.pngfe77e11b39e64761bae6cf6fbb1a1250.png4f055790fd904bbf80ab91223a37d920.png

 20657b44e5e24fe9acd907b607c2ca2e.png5485509ad50c486a90903b8743026810.png4ee91d973af94636925b4d5b2543ec88.png

 多次实验你会发现归一的方法更准确。

 三、匹配多个对象

 1.导包构建函数

  1. import cv2
  2. import numpy as np
  3. import matplotlib.pyplot as plt
  4. def cv_show(name,img):
  5. cv2.imshow(name,img)
  6. cv2.waitKey(0)
  7. cv2.destroyAllWindows()

 2.读入图像转灰度图,改大小。

  1. im=cv2.imread('C:/Users/bwy/Desktop/9.png')
  2. TE=cv2.imread('C:/Users/bwy/Desktop/10.png',cv2.IMREAD_GRAYSCALE)
  3. im1=cv2.resize(im,(600,337))
  4. cv_show('im',im1)
  5. img_=cv2.cvtColor(im1,cv2.COLOR_BGR2GRAY)
  6. TE=cv2.resize(TE,(60,60))
  7. TE.shape

 3.图像匹配

  1. h,w=TE.shape[:2]
  2. r=cv2.matchTemplate(img_,TE,cv2.TM_CCOEFF_NORMED)
  3. cv_show('r',r)

 结果如图所示:

d569f0886ef64efc96598b1709c49889.png

4.取匹配程度大于75%的坐标 ,画在原图上

其中:zip(*) 可理解为解压,返回二维矩阵式。loc中loc[0]是高,loc[1]是宽,[::-1]表示倒序。p[0]代表宽,p[1]代表高

  1. threshold=0.75
  2. loc=np.where(r>=threshold)
  3. for pt in zip(*loc[::-1]):#*代表可选参数
  4. bottom_right=(pt[0]+w,pt[1]+h)
  5. cv2.rectangle(im1,pt,bottom_right,(0,0,255),1)
  6. cv_show('im1',im1)

 结果如图所示:

ccbaae548edb4889bde8b3244bdb05bf.png

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/79103
推荐阅读
相关标签
  

闽ICP备14008679号