图像匹配之序贯相似性检测法匹配
发布时间:2020-12-14 03:37:44 所属栏目:大数据 来源:网络整理
导读:图像匹配计算量大的原因在于搜索窗口在待匹配的图像上进行滑动,每滑动一次就要做一次匹配相关运算,在不匹配点做的运算就是'无用'的,从而导致计算量上升。序贯相似性检测法在计算匹配度的同时,不断累积模板和像元的灰度差,当累积值大于某一指定阈值时,
图像匹配计算量大的原因在于搜索窗口在待匹配的图像上进行滑动,每滑动一次就要做一次匹配相关运算,在不匹配点做的运算就是'无用'的,从而导致计算量上升。序贯相似性检测法在计算匹配度的同时,不断累积模板和像元的灰度差,当累积值大于某一指定阈值时,则说明该点为非匹配点,进行下一个位置的计算,这样大大减少了计算复杂度。 这里定义了一个绝对误差: 计算每一个子图像中像素点与模板中的像素点的绝对误差累积值,当该值大于设定阈值时,便可放弃计算该子图,进入下一子图的计算,并存下超出阈值时的累加次数。 opencv的编写的代码如下: #include "stdafx.h" #include <opencv2/opencv.hpp> #include "highgui.h" #include <math.h> 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,1); src_gray3 = cvCreateImage( sz,1); T_gray1 = cvCreateImage( sz_T,1); //模板的三个通道 T_gray2 = cvCreateImage( sz_T,1); T_gray3 = cvCreateImage( sz_T,1); S_img = cvCreateImage( sz_T,1); //模板覆盖下的子图 Match_image = cvCreateImage( sz,1); //匹配位置图,图中的白点即为匹配得到的位置 cvSetZero(Match_image); } long abs_value (long value) { if( value < 0 ) value = -value; return value; } int main(int argc,char* argv[]) { IplImage* img = cvLoadImage("Images/序贯相似性.bmp"); //加载图像 原图 IplImage* T_img = cvLoadImage("Images/序贯相似性模板.bmp"); //模板图 int i,j,m,n,Max_width,Max_height; 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 S_mean=0,T_mean=0,dbr=0,lR= 0,dbr_threshold = 5000,dbr_min = 5000; 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( m=0; m<T_height; m++) //计算模板T的均值 { unsigned char* T_ptr = (unsigned char*)T_gray1->imageData + m*T_gray1->widthStep; for( n=0; n<T_width; n++) { unsigned char T_value = T_ptr[n]; T_mean = T_mean + T_value*T_value; } } T_mean = T_mean/(T_width*T_height); for( i= 0; i<(src_height-T_height); i++) //模板图在搜索图上平移 { for( j= 0; j<(src_width-T_width); j++) { S_mean = 0; lR = 0; dbr = 0; cvSetImageROI(src_gray1,cvRect( j,i,T_img->width,T_img->height ) ); cvCopy( src_gray1,S_img,0 ); cvResetImageROI(src_gray1); for( m=0; m<T_height; m++) //计算子图S的均值 { unsigned char* S_ptr = (unsigned char*)S_img->imageData + m*S_img->widthStep; for( n=0; n<T_width; n++) { unsigned char S_value = S_ptr[n]; S_mean = S_mean + S_value*S_value; } } S_mean = S_mean/(T_width*T_height); for( m=0; m<T_height; m++) //计算误差dbr,lR { unsigned char* S_ptr = (unsigned char*)S_img->imageData + m*S_img->widthStep; unsigned char* T_ptr = (unsigned char*)T_gray1->imageData + m*T_gray1->widthStep; for( n=0; n<T_width; n++) { unsigned char S_value = S_ptr[n]; unsigned char T_value = T_ptr[n]; dbr += abs_value( (long)S_value - S_mean - T_value + T_mean ); if ( dbr>= dbr_threshold ) { lR = (m+1)*(n+1); break; //跳出一次循环 } } if ( dbr>= dbr_threshold ) { break; //再跳出一次循环 } } if ( dbr < dbr_min ) //找出误差最小的点,就是匹配点 { dbr_min = dbr; Max_height = i; Max_width = j; } } } cvSet2D( Match_image,Max_height,cvScalar( 255,0) ); cvRectangle(img,cvPoint(Max_width,Max_height),cvPoint(Max_width+T_width,Max_height+T_height),cvScalar(0,255,0),1,8,0); cvShowImage("my picture",img); //原图,图中红色矩形区域即为匹配的位置 cvShowImage("my model",T_img); //模板图 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; } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |