视觉图像:模板匹配二
绪:
模板匹配是在一幅图像中寻找与另一幅模板图像最匹配(相似)部分的技术;
最常见的模板匹配方法:
(1)平方差匹配法 method=TM_SQDIFF
(2)归一化平方差匹配法 method=TM_SQDIFF_NORMED
(3)相关匹配法 method=TM_CCORR
(4)归一化相关匹配法 method=TM_CCORR_NORMED
(5)系数匹配法 method=TM_CCOEFF
(6)归一化相关系数匹配法 method=TM_CCOEFF_NORMED
本经验以归一化相关系数匹配方法为例,进行编写程序;
操作方法
- 01
相似性度量:归一化相关系数匹配法: 其公式如下所示: 进行变换得; 其中,I为待匹配图像;M为匹配图像; m和n分别为匹配图像的宽度和长度; N=m×n; r的值域范围在[-1,1],值为1.0表示待匹配图像和匹配图像完全匹配
- 02
代码编写: 先把公式中各分量的计算公式写成函数,总共有5个; //∑∑M(i,j) double MFun(Mat _mask_img) { int _width = _mask_img.cols; int _height = _mask_img.rows; double m_sum = 0.f; unsigned char* p_data = (unsigned char*)_mask_img.data; for (int j=0;j<_width;j++)//lie { for (int i=0;i<_height;i++)//hang { m_sum = p_data[i*_width+j]; } } return m_sum; }
- 03
//∑∑M(i,j)^2 double M2Fun(Mat _mask_img) { int _width = _mask_img.cols; int _height = _mask_img.rows; double m_sum = 0.f; unsigned char* p_data = (unsigned char*)_mask_img.data; for (int j=0;j<_width;j++) { for (int i=0;i<_height;i++) { double p_data_1 = p_data[i*_width+j]; m_sum = p_data_1 * p_data_1; } } return m_sum; }
- 04
//∑∑I(i,j) double IFun(Mat _raw_img,Mat _mask_img,int _u,int _v) { double m_sum; unsigned char* p_data = (unsigned char*)_raw_img.data; int _height = _mask_img.rows; int _width = _mask_img.cols; for (int j=0;j<_width;j++) { for (int i=0;i<_height;i++) { m_sum = p_data[(_u+i)*_width+(j+_v)]; } } return m_sum; }
- 05
//∑∑I(i,j)^2 double I2Fun(Mat _raw_img,Mat _mask_img,int _u,int _v) { double m_sum; unsigned char* p_data = (unsigned char*)_raw_img.data; int _height = _mask_img.rows; int _width = _mask_img.cols; for (int j=0;j<_width;j++) { for (int i=0;i<_height;i++) { double temp_data = p_data[(i+_u)*_width+(j+_v)]; m_sum = temp_data * temp_data; } } return m_sum; }
- 06
//∑∑IM double IMFun(Mat _raw_img,Mat _mask_img,int _u,int _v) { double m_sum; unsigned char* p_data_1 = (unsigned char*)_raw_img.data; unsigned char* p_data_2 = (unsigned char*)_mask_img.data; int _height = _mask_img.rows; int _width = _mask_img.cols; for (int j=0;j<_width;j++) { for (int i=0;i<_height;i++) { m_sum = p_data_1[(i+_u)*_width+(j+_v)] * p_data_2[i*_width+j]; } } return m_sum; }
- 07
匹配结果值进行保存, 程序如下: Mat MaskMatchFun(Mat _raw_img,Mat _mask_img) { int mask_width = _mask_img.cols; int mask_height = _mask_img.rows; int mask_big = mask_width * mask_height;//m*n int raw_width = _raw_img.cols; int raw_height = _raw_img.rows; int real_height = raw_height - mask_height + 1;//l-m+1 int real_width = raw_width - mask_height + 1; double M_Value = MFun(_mask_img);//m double M2_Value = M2Fun(_mask_img);//m^2 Mat dist_img(real_height,real_width,CV_32FC1); float* p_data = (float*) dist_img.data; for (int j=0;j<real_width;j++) { for (int i=0;i<real_height;i++) { double temp1 = IMFun(_raw_img,_mask_img,i,j); double temp2 = IFun(_raw_img,_mask_img,i,j); double fenzi = mask_big*temp1-temp2*M_Value; double temp3 = I2Fun(_raw_img,_mask_img,i,j); double temp4 = (mask_big*temp3-temp2*temp2)*(mask_big*M2_Value-M_Value*M_Value); double fenmu = sqrt(temp4); p_data[i*real_width+j] = fenzi/fenmu; } } return dist_img; }