Advertisement

图像匹配之序贯相似性检测法匹配

阅读量:

图像匹配计算量大的原因在于搜索窗口在待匹配的图像上进行滑动,每滑动一次就要做一次匹配相关运算,在不匹配点做的运算就是'无用'的,从而导致计算量上升。序贯相似性检测法在计算匹配度的同时,不断累积模板和像元的灰度差,当累积值大于某一指定阈值时,则说明该点为非匹配点,进行下一个位置的计算,这样大大减少了计算复杂度。

这里定义了一个绝对误差:

计算每一个子图像中像素点与模板中的像素点的绝对误差累积值,当该值大于设定阈值时,便可放弃计算该子图,进入下一子图的计算,并存下超出阈值时的累加次数。

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, 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);  
    
 }  
    
 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, 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_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;  
    
 }

全部评论 (0)

还没有任何评论哟~