图像匹配之距离变换匹配法
来源:互联网 发布:cydia下载软件 编辑:程序博客网 时间:2024/06/05 07:31
距离变换是一种常见的二值图像处理算法,用来计算图像中任意位置到最近边缘点的距离,常见的距离测度函数有切削距离,街区距离和欧式距。切削距离和街区距离是欧式距离的一种近似。
基于距离变换的匹配的原理是计算模板图覆盖下的那块子图与模板图之间的距离,也就是计算子图中的边缘点到模板图中最近的边缘点的距离,这里采用欧式距离,并对欧式距离进行近似,认为与边缘4邻域相邻的点的距离为0.3,8邻域相邻的点的距离为0.7,不相邻的点的距离都为1。
opencv程序如下:
#include "stdafx.h" #include <opencv2/opencv.hpp> #include "highgui.h" #include <math.h> typedef unsigned long uint32;typedef unsigned int uint16;typedef unsigned char uint8;IplImage *src_gray1, *src_gray2, *src_gray3; IplImage *temp_gray1, *temp_gray2, *temp_gray3; IplImage *Dist;uint8 TemplatePixelm10 = 0;uint8 TemplatePixelm01 = 0;uint8 TemplatePixeln01 = 0;uint8 TemplatePixeln10 = 0;uint8 TemplatePixelm1n1 = 0;uint8 TemplatePixelm1n0 = 0;uint8 TemplatePixelm0n1 = 0;uint8 TemplatePixelm0n0 = 0;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); temp_gray1 = cvCreateImage( sz_T, IPL_DEPTH_8U, 1); //模板的三个通道 temp_gray2 = cvCreateImage( sz_T, IPL_DEPTH_8U, 1); temp_gray3 = cvCreateImage( sz_T, IPL_DEPTH_8U, 1); Dist = cvCreateImage(sz_T,IPL_DEPTH_8U,1); } void CalTemplateDist(IplImage* I,IplImage* Dist, long* Nb) //计算在模板图对应位置上的距离{int i,j;float dis;for ( i=0; i<I->height; i++ ){uint8* ptr = (uint8*)( I->imageData + i*I->widthStep );for ( j=0; j<I->width; j++ ){uint8 Pixel = ptr[j];if(Pixel==0){dis = 0;(*Nb)++;}else{if( i==0 && j==0 ) //第一行第一个点{TemplatePixelm10 = ptr[j+1];TemplatePixeln10 = *( I->imageData + (i+1)*I->widthStep + j );TemplatePixelm1n1 = *( I->imageData + (i+1)*I->widthStep + j+1 );if( TemplatePixelm10==0 || TemplatePixeln10==0 )dis = 0.3;else if( TemplatePixelm1n1==0 )dis = 0.7;elsedis = 1;}else if( i==0 && j>0 && j<(I->width-1) ) //第一行{TemplatePixelm10 = ptr[j+1];TemplatePixelm01 = ptr[j-1];TemplatePixeln10 = *( I->imageData + (i+1)*I->widthStep + j );TemplatePixelm1n1 = *( I->imageData + (i+1)*I->widthStep + j+1 );TemplatePixelm0n1 = *( I->imageData + (i+1)*I->widthStep + j-1 );if( TemplatePixelm10==0 || TemplatePixeln10==0 || TemplatePixelm01==0 )dis = 0.3;else if( TemplatePixelm1n1==0 || TemplatePixelm0n1==0 )dis = 0.7;elsedis = 1;} else if( i==0 && j==(I->width-1) ) //第一行最后一个点{TemplatePixelm01 = ptr[j-1];TemplatePixeln10 = *( I->imageData + (i+1)*I->widthStep + j );TemplatePixelm0n1 = *( I->imageData + (i+1)*I->widthStep + j-1 );if( TemplatePixeln10==0 || TemplatePixelm01==0 )dis = 0.3;else if( TemplatePixelm0n1==0 )dis = 0.7;elsedis = 1;}else if( j==0 && i>0 && i<(I->height-1) ) //第一列{TemplatePixelm10 = ptr[j+1];TemplatePixeln01 = *( I->imageData + (i-1)*I->widthStep + j );TemplatePixeln10 = *( I->imageData + (i+1)*I->widthStep + j );TemplatePixelm1n1 = *( I->imageData + (i+1)*I->widthStep + j+1 );TemplatePixelm1n0 = *( I->imageData + (i-1)*I->widthStep + j+1 );if( TemplatePixelm10==0 || TemplatePixeln10==0 || TemplatePixeln01==0 )dis = 0.3;else if( TemplatePixelm1n1==0 || TemplatePixelm1n0==0 )dis = 0.7;elsedis = 1;}else if( i>0 && i<(I->height-1) && j==(I->width-1) ) //最后一列{TemplatePixelm01 = ptr[j-1];TemplatePixeln01 = *( I->imageData + (i-1)*I->widthStep + j );TemplatePixeln10 = *( I->imageData + (i+1)*I->widthStep + j );TemplatePixelm0n1 = *( I->imageData + (i+1)*I->widthStep + j-1 );TemplatePixelm0n0 = *( I->imageData + (i-1)*I->widthStep + j-1 );if( TemplatePixeln10==0 || TemplatePixelm01==0 || TemplatePixeln01==0 )dis = 0.3;else if( TemplatePixelm0n1==0 || TemplatePixelm0n0==0 )dis = 0.7;elsedis = 1;}else if( j==0 && i==(I->height-1) ) //最后一行最后一个点{TemplatePixelm10 = ptr[j+1];TemplatePixeln01 = *( I->imageData + (i-1)*I->widthStep + j );TemplatePixelm1n0 = *( I->imageData + (i-1)*I->widthStep + j+1 );if( TemplatePixelm10==0 || TemplatePixeln01==0 )dis = 0.3;else if( TemplatePixelm1n0==0 )dis = 0.7;elsedis = 1;}else if( j>0 && j<(I->width-1) && i==(I->height-1) ) //最后一行{TemplatePixelm10 = ptr[j+1];TemplatePixelm01 = ptr[j-1];TemplatePixeln01 = *( I->imageData + (i-1)*I->widthStep + j );TemplatePixelm1n0 = *( I->imageData + (i-1)*I->widthStep + j+1 );TemplatePixelm0n0 = *( I->imageData + (i-1)*I->widthStep + j-1 );if( TemplatePixelm10==0 || TemplatePixeln01==0 || TemplatePixelm01==0 )dis = 0.3;else if( TemplatePixelm1n0==0 || TemplatePixelm0n0==0 )dis = 0.7;elsedis = 1;}else if( j==(I->width-1) && i==(I->height-1) ) //最后一行最后一个点{TemplatePixelm01 = ptr[j-1];TemplatePixeln01 = *( I->imageData + (i-1)*I->widthStep + j );TemplatePixelm0n0 = *( I->imageData + (i-1)*I->widthStep + j-1 );if( TemplatePixeln01==0 || TemplatePixelm01==0 )dis = 0.3;else if( TemplatePixelm0n0==0 )dis = 0.7;elsedis = 1;}else{TemplatePixelm10 = ptr[j+1];TemplatePixelm01 = ptr[j-1];TemplatePixeln01 = *( I->imageData + (i-1)*I->widthStep + j );TemplatePixeln10 = *( I->imageData + (i+1)*I->widthStep + j );TemplatePixelm1n0 = *( I->imageData + (i-1)*I->widthStep + j+1 );TemplatePixelm0n0 = *( I->imageData + (i-1)*I->widthStep + j-1 );TemplatePixelm1n1 = *( I->imageData + (i+1)*I->widthStep + j+1 );TemplatePixelm0n1 = *( I->imageData + (i+1)*I->widthStep + j-1 );if( TemplatePixeln01==0 || TemplatePixelm01==0 || TemplatePixelm10==0 || TemplatePixeln10==0 )dis = 0.3;else if( TemplatePixelm0n0==0 || TemplatePixelm1n0==0 || TemplatePixelm0n1==0 || TemplatePixelm1n1==0 )dis = 0.7;elsedis = 1;}}*(Dist->imageData + i*Dist->widthStep + j) = (uint8)(dis*255);}}}void dist_match(IplImage* src_img, IplImage* Dist,double MinMatch, CvPoint* pt, long* Na, long* Nb) //距离匹配{int i,j,m,n;double SigmaGT;uint8 SrcValue;double DistValue;double Match;for ( i=0; i<(src_img->height - Dist->height); i++ ){for ( j=0; j<( src_img->width - Dist->width ); j++ ){SigmaGT = 0;*Na = 0;for( m=0; m<Dist->height; m++ ){for( n=0; n<Dist->width; n++ ){SrcValue = *( src_img->imageData + (i+m)*src_img->widthStep +j+n );if(SrcValue==0){DistValue = (double)*( Dist->imageData +m*Dist->widthStep + n )/255;SigmaGT += DistValue;(*Na)++;}}}if( (*Na) > (*Nb) ){Match = ( SigmaGT + (*Na) - (*Nb) )/( (*Na) + (*Nb) );}else{Match = ( SigmaGT + (*Nb) - (*Na) )/( (*Na) + (*Nb) );}if( Match < MinMatch ){MinMatch = Match; //距离匹配的最小值就是匹配的位置pt->x = j;pt->y = i;}}}}int _tmain(int argc, _TCHAR* argv[]){IplImage* src_img, *temp_img; //定义变量double MinMatch = 1000;CvPoint MatchPoint = cvPoint(1,1);long Na=0,Nb=0;//像素0的个数src_img = cvLoadImage("Images/距离变换.bmp"); //读入两幅图temp_img = cvLoadImage("Images/距离变换模板.bmp");AllocateImage( src_img, temp_img );cvSplit( src_img, src_gray1, src_gray2, src_gray3, 0); //将两幅三通道图像分解为3幅单通道图像 cvSplit( temp_img, temp_gray1, temp_gray2, temp_gray3, 0);CalTemplateDist(temp_gray1, Dist, &Nb);dist_match(src_gray1, Dist, MinMatch, &MatchPoint, &Na, &Nb);cvRectangle(src_img, MatchPoint, cvPoint(MatchPoint.x+49, MatchPoint.y+39), cvScalar(0, 0, 255, 0), 1,8,0);cvNamedWindow("my picture",CV_WINDOW_AUTOSIZE); cvNamedWindow("my template",CV_WINDOW_AUTOSIZE);cvNamedWindow("my Dist",CV_WINDOW_AUTOSIZE);cvShowImage("my picture",src_img); cvShowImage("my template",temp_gray1);cvShowImage("my Dist",Dist);cvWaitKey(0); cvReleaseImage(&src_img); cvReleaseImage(&temp_img); cvReleaseImage(&src_gray1); cvReleaseImage(&src_gray2); cvReleaseImage(&src_gray3); cvReleaseImage(&temp_gray1); cvReleaseImage(&temp_gray2); cvReleaseImage(&temp_gray3); cvDestroyWindow("my picture"); cvDestroyWindow("my template"); return 0;}
0 0
- 图像匹配之距离变换匹配法
- 图像匹配之距离变换匹配法
- 基于距离变换的图像匹配
- 图像匹配之不变矩匹配法
- 图像匹配(欧式距离)
- 图像基础6 图像匹配--欧氏距离匹配
- 图像处理之距离变换
- 图像处理之------匹配
- 图像匹配之序贯相似性检测法匹配
- 图像匹配之序贯相似性检测法匹配
- 仿射变换应用于图像匹配
- 图像匹配之不变矩匹配
- OpenCV 基于距离变换的高精度轮廓匹配
- opencv例程之图像的距离变换
- 图像处理之倒角距离变换
- 图像匹配算法之初探尺度不变特征变换(SIFT)算法
- 图像处理之模板匹配
- 工业检测之图像匹配
- table 表格 细边框 最简单样式
- DWR高级主题之DWR与spring集成
- 挥汗如雨-WebService
- 实验8 Servlet事件监听
- android 4.3 修改默认壁纸
- 图像匹配之距离变换匹配法
- AS3.0 设置sprite的锚点,不改变注册点的的函数
- android fragmentStateViewPagerAdapter 介绍
- JavaScript插件——Bootstrap中的JavaScript
- android的按键处理
- vSphere高级功能(二)—— 分布式资源调度功能DRS实践
- Hadoop-2.2.0中文文档——Apache Hadoop 下一代 MapReduce (YARN)
- 细细聆听,生命留下的絮语
- 读《走出软件作坊》-三五个人十来条枪 如何成为开发正规军(一)