归一化积相关是一种典型的基于灰度相关的算法,具有不受比例因子误差影响和抗白噪声干扰能力强等优点。
它使用的相似性度量定义如下:
R即为相似性的度量值,该值越大,代表相似性越大。T是模板,S是搜索图。将模板图T放在搜索图S上平移,模板覆盖下的那块搜索图叫做Sij,(i,j)为这块子图左上角像点在S图中 的坐标,称为参考点。式中分子位置的项是子图像和模板的互相关,随(i,j)的改变而改变,分母的第二项表示的是模板的总能量,第一项表示的是子图S的总能量。当T和Sij匹配时,R即为最大值。
我用opencv在VS2008中编写了一段程序,程序如下:
#include "stdafx.h"
#include
#include "highgui.h"
#include
IplImage *src_gray1, *src_gray2, *src_gray3;
IplImage *T_gray1, *T_gray2, *T_gray3;
IplImage* S_img,*Match_image;
void AllocateImage(IplImage* I,IplImage* T) //给图像分配大小
{
CvSize sz = cvGetSize(I);
CvSize sz_T = cvGetSize(T);
src_gray1 = cvCreateImage( sz, IPL_DEPTH_8U, 1); //原图的三个通道
src_gray2 = cvCreateImage( sz, IPL_DEPTH_8U, 1);
src_gray3 = cvCreateImage( sz, IPL_DEPTH_8U, 1);
T_gray1 = cvCreateImage( sz_T, IPL_DEPTH_8U, 1); //模板的三个通道
T_gray2 = cvCreateImage( sz_T, IPL_DEPTH_8U, 1);
T_gray3 = cvCreateImage( sz_T, IPL_DEPTH_8U, 1);
S_img = cvCreateImage( sz_T, IPL_DEPTH_8U, 1); //模板覆盖下的子图
Match_image = cvCreateImage( sz, IPL_DEPTH_8U, 1); //匹配位置图,图中的白点即为匹配得到的位置
cvSetZero(Match_image);
}
int main(int argc, char* argv[])
{
IplImage* img = cvLoadImage("image/归一化.bmp"); //加载图像 原图
IplImage* T_img = cvLoadImage("image/归一化模板.bmp"); //模板图
int i,j,m,n,Max_width,Max_height;
double MatchValue=0,MaxValue=0;
unsigned int src_width = img->width;
unsigned int src_height = img->height;
unsigned int T_width = T_img->width;
unsigned int T_height = T_img->height;
unsigned long InterRelateValue=0, S_energy=0, T_energy=0;
AllocateImage( img, T_img);
cvNamedWindow("my picture",CV_WINDOW_AUTOSIZE);
cvNamedWindow("my model",CV_WINDOW_AUTOSIZE);
cvNamedWindow("result",CV_WINDOW_AUTOSIZE);
cvSplit( img, src_gray1, src_gray2, src_gray3, 0);
cvSplit( T_img, T_gray1, T_gray2, T_gray3, 0);
for( i= 0; i<(src_height-T_height); i++) //模板图在搜索图上平移
{
for( j= 0; j<(src_width-T_width); j++)
{
cvSetImageROI(src_gray1,
cvRect( j, i, T_img->width, T_img->height )
);
cvCopy( src_gray1, S_img, 0 );
cvResetImageROI(src_gray1);
///计算相似度
for( m=0; mimageData + m*S_img->widthStep;
unsigned char* T_ptr = (unsigned char*)T_gray1->imageData + m*T_gray1->widthStep;
for( n=0; n MaxValue) //找最大值
{
MaxValue = MatchValue;
Max_width = j;
Max_height = i;
}
InterRelateValue = 0;
S_energy = 0;
T_energy = 0;
}
}
cvSet2D( Match_image, Max_height, Max_width, cvScalar( 255, 0, 0, 0) );
cvRectangle(img, cvPoint(Max_width, Max_height), cvPoint(Max_width+T_width, Max_height+T_height), cvScalar(0, 0, 255, 0), 1,8,0);
cvShowImage("my picture",img); //原图,图中红色矩形区域即为匹配的位置
cvShowImage("my model",T_gray1); //模板图
cvShowImage("result",Match_image); //匹配的位置
cvWaitKey(0);
cvReleaseImage(&img);
cvReleaseImage(&T_img);
cvReleaseImage(&src_gray1);
cvReleaseImage(&src_gray2);
cvReleaseImage(&src_gray3);
cvReleaseImage(&T_gray1);
cvReleaseImage(&T_gray2);
cvReleaseImage(&T_gray3);
cvReleaseImage(&Match_image);
cvReleaseImage(&S_img);
cvDestroyWindow("my picture");
cvDestroyWindow("my model");
cvDestroyWindow("result");
return 0;
}