加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

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

发布时间: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;  
}  

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读