1 理论介绍
模板匹配是在一幅图像中寻找一个特定目标的方法之一,这种方法的原理非常简单,遍历图像中的每一个可能的位置,比较各处与模板是否“相似”,当相似度足够高时,就认为找到了我们的目标。OpenCV提供了6种模板匹配算法:
- 平方差匹配法CV_TM_SQDIFF
- 归一化平方差匹配法CV_TM_SQDIFF_NORMED
- 相关匹配法CV_TM_CCORR
- 归一化相关匹配法CV_TM_CCORR_NORMED
- 相关系数匹配法CV_TM_CCOEFF
- 归一化相关系数匹配法CV_TM_CCOEFF_NORMED
用T表示模板图像,I表示待匹配图像,切模板图像的宽为w高为h,用R表示匹配结果,匹配过程如下图所示:
上述6中匹配方法可用以下公式进行描述:
2 示例代码
下面给出方法6的python代码
1 import numpy as np 2 import cv2 3 4 def EM(pModel, width, height): 5 sum = np.double(0.0) 6 for i in range(0,height): 7 for j in range(0,width): 8 sum += pModel[i][j] 9 return sum 10 11 def EM2(pModel, width, height): 12 sum = np.double(0.0) 13 for i in range(0,height): 14 for j in range(0,width): 15 sum += pModel[i][j]*1.0*pModel[i][j] 16 return sum 17 18 def EI(pToSearch, l, h, u, v, pModel, width, height): 19 sum = np.double(0.0) 20 roi = pToSearch[v:v+height, u:u+width] 21 for i in range(0,height): 22 for j in range(0,width): 23 sum += roi[i][j] 24 return sum 25 26 def EI2(pToSearch, l, h, u, v, pModel, width, height): 27 sum = np.double(0.0) 28 roi = pToSearch[v:v+height, u:u+width] 29 for i in range(0,height): 30 for j in range(0,width): 31 sum += roi[i][j]*1.0*roi[i][j] 32 return sum 33 34 def EIM(pToSearch, l, h, u, v, pModel, width, height): 35 sum = np.double(0.0) 36 roi = pToSearch[v:v+height, u:u+width] 37 for i in range(0,height): 38 for j in range(0,width): 39 sum += pModel[i][j]*1.0*roi[i][j] 40 return sum 41 42 def Match(pToSearch, l, h, pModel, width, height): 43 uMax = l-width 44 vMax = h-height 45 N = width*height 46 len = (uMax+1)*(vMax+1) 47 MatchRec = [0.0 for x in range(0, len)] 48 k = 0 49 50 M = EM(pModel,width,height) 51 M2 = EM2(pModel,width,height) 52 for p in range(0, uMax+1): 53 for q in range(0, vMax+1): 54 I = EI(pToSearch,l,h,p,q,pModel,width,height) 55 I2 = EI2(pToSearch,l,h,p,q,pModel,width,height) 56 IM = EIM(pToSearch,l,h,p,q,pModel,width,height) 57 58 numerator=(N*IM-I*M)*(N*IM-I*M) 59 denominator=(N*I2-I*I)*(N*M2-M*M) 60 61 ret = numerator/denominator 62 MatchRec[k]=ret 63 k+=1 64 65 val = 0 66 k = 0 67 x = y = 0 68 for p in range(0, uMax+1): 69 for q in range(0, vMax+1): 70 if MatchRec[k] > val: 71 val = MatchRec[k] 72 x = p 73 y = q 74 k+=1 75 print "val: %f"%val 76 return (x, y) 77 78 def main(): 79 img = cv2.imread('niu.jpg', cv2.IMREAD_GRAYSCALE) 80 temp = cv2.imread('temp.png', cv2.IMREAD_GRAYSCALE) 81 82 print temp.shape 83 imgHt, imgWd = img.shape 84 tempHt, tempWd = temp.shape 85 #print EM(temp, tempWd, tempHt) 86 (x, y) = Match(img, imgWd, imgHt, temp, tempWd, tempHt) 87 cv2.rectangle(img, (x, y), (x+tempWd, y+tempHt), (0,0,0), 2) 88 cv2.imshow("temp", temp) 89 cv2.imshow("result", img) 90 cv2.waitKey(0) 91 cv2.destroyAllWindows() 92 93 if __name__ == '__main__': 94 main()