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
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()
归一化相关系数匹配法
IPCVAPI_IMPL( CvStatus, icvMatchTemplate_CoeffNormed_32f_C1R,
(const float *pImage, int imageStep, CvSize roiSize,
const float *pTemplate, int templStep, CvSize templSize,
float *pResult, int resultStep, void *pBuffer) )
{
float *imgBuf = 0;
float *templBuf = 0;
double *sumBuf = 0;
double *sqsumBuf = 0;
double *resNum = 0;
double *resDenom = 0;
double templCoeff = 0;
double templSum = 0;
int winLen = templSize.width * templSize.height;
double winCoeff = 1. / (winLen + DBL_EPSILON);
CvSize resultSize = cvSize( roiSize.width - templSize.width + 1,
roiSize.height - templSize.height + 1 );
int x, y;
CvStatus result = icvMatchTemplateEntry( pImage, imageStep, roiSize,
pTemplate, templStep, templSize,
pResult, resultStep, pBuffer,
cv32f, 1, 1,
(void **) &imgBuf, (void **) &templBuf,
(void **) &sumBuf, (void **) &sqsumBuf,
(void **) &resNum, (void **) &resDenom );
if( result != CV_OK )
return result;
imageStep /= sizeof_float;
templStep /= sizeof_float;
resultStep /= sizeof_float;
{
const float *rowPtr = (const float *) imgBuf;
double templSqsum = icvCrossCorr_32f_C1( templBuf, templBuf, winLen );
templSum = icvSumPixels_32f_C1( templBuf, winLen );
templCoeff = (double) templSqsum - ((double) templSum) * templSum * winCoeff;
templCoeff = icvInvSqrt64d( fabs( templCoeff ) + FLT_EPSILON );
for( y = 0; y < roiSize.height; y++, rowPtr += templSize.width )
{
sumBuf[y] = icvSumPixels_32f_C1( rowPtr, templSize.width );
sqsumBuf[y] = icvCrossCorr_32f_C1( rowPtr, rowPtr, templSize.width );
}
}
for( x = 0; x < resultSize.width; x++ )
{
double sum = 0;
double sqsum = 0;
float *imgPtr = imgBuf + x;
if( x > 0 )
{
const float *src = pImage + x + templSize.width - 1;
float *dst = imgPtr - 1;
float out_val = dst[0];
dst += templSize.width;
for( y = 0; y < roiSize.height; y++, src += imageStep, dst += templSize.width )
{
float in_val = src[0];
sumBuf[y] += in_val - out_val;
sqsumBuf[y] += (in_val - out_val) * (in_val + out_val);
out_val = dst[0];
dst[0] = (float) in_val;
}
}
for( y = 0; y < templSize.height; y++ )
{
sum += sumBuf[y];
sqsum += sqsumBuf[y];
}
for( y = 0; y < resultSize.height; y++, imgPtr += templSize.width )
{
double res = icvCrossCorr_32f_C1( imgPtr, templBuf, winLen );
if( y > 0 )
{
sum -= sumBuf[y - 1];
sum += sumBuf[y + templSize.height - 1];
sqsum -= sqsumBuf[y - 1];
sqsum += sqsumBuf[y + templSize.height - 1];
}
resNum[y] = res;
resDenom[y] = sum;
resDenom[y + resultSize.height] = sqsum;
}
for( y = 0; y < resultSize.height; y++ )
{
double sum = ((double) resDenom[y]);
double wsum = winCoeff * sum;
double res = ((double) resNum[y]) - wsum * templSum;
double nrm_s = ((double) resDenom[y + resultSize.height]) - wsum * sum;
res *= templCoeff * icvInvSqrt64d( fabs( nrm_s ) + FLT_EPSILON );
pResult[x + y * resultStep] = (float) res;
}
}
return CV_OK;
}
转自:模板匹配算法详细解说