圆投影匹配算法描述及实现

解决模板图和基准图之间存在任意角度旋转的景象匹配问题的关键是找到一个旋转不变量, 圆投影匹配算法就是利用“圆”的各向同性和投影特征提出来的。传统的图像匹配算法,如归一化交叉互相关算法,主要利用像素点与像素点之间的相关性计算匹配图像与模板之间的相关度。这种方法在匹配图像与模板之间存在一定选择角度的时候,正确率会随着旋转角度的增加而迅速下降。当旋转角度大于5度的时候就会完全失效。于是圆投影算法被提出。

应用到实际中基于圆投影矢量和的旋转不变量检测(点击进入查看文献)

上面基于圆投影矢量和的模板匹配文献算法实现代码如下:

//圆投影void CircularProjection(int rectW, int rectH){//模板大小为TW*TW,TW为奇数// 用于存放模板中每个像素点距离模板中心的距离int *r=new int[TW*TW];#define r(ROW,COL) r[TW*(ROW)+(COL)]//相关变量int y,x;double dis;//离散数字圆for (y=0; y<TW; y++){for (x=0; x<TW; x++){dis=(x-TW/2)*(x-TW/2)+(y-TW/2)*(y-TW/2);r(y,x)=(int)(sqrt(dis)+0.5);}}//统计半径为r的圆上有多少个点int i,j;int R=(TW-1)/2;int *Sr=new int[R+1];memset(Sr,0,(R+1)*sizeof(int));//存放实部模板double *tepReal=new double[TW*TW];//存放虚部模板double *tepVirtual=new double[TW*TW];#define PI 3.1415926 #define tepReal(ROW,COL) tepReal[TW*(ROW)+(COL)]#define tepVirtual(ROW,COL) tepVirtual[TW*(ROW)+(COL)]//统计半径为r的圆上有多少个点for(i=0; i<TW; i++){for (j=0; j<TW; j++){if (r(i,j)<=R){Sr[r(i,j)]++;}}}//创建模板for(i=0; i<TW; i++){for (j=0; j<TW; j++){if (r(i,j)>R){tepReal(i,j)=0;tepVirtual(i,j)=0;}else{tepReal(i,j)=cos(-2*PI*r(i,j)/(R+1))/Sr[r(i,j)];tepVirtual(i,j)=sin(-2*PI*r(i,j)/(R+1))/Sr[r(i,j)];}}}//模板圆投影向量和unsigned char *lpSrc;// 计算灰度图像每行的字节数long LineBytes = (m_imgWidth*m_nBitCount/8+3)/4*4;double *It=new double[TW*TW];double *Itreal=new double[TW*TW];double *Itvirtual=new double[TW*TW];#define It(ROW,COL) It[TW*(ROW)+(COL)]#define Itreal(ROW,COL) Itreal[TW*(ROW)+(COL)]#define Itvirtual(ROW,COL) Itvirtual[TW*(ROW)+(COL)]//将模板图像copy至It存储for (i=0; i<TW; i++){for (j=0; j<TW; j++){//pTop为模板左上角坐标int y=pTop.y+i;int x=pTop.x+j;lpSrc=m_pImgData+LineBytes*(m_imgHeight-1-y)+x;It(i,j)=double(*lpSrc);}}Itreal=Template(It,TW,TW,tepReal,TW,TW);Itvirtual=Template(It,TW,TW,tepVirtual,TW,TW);//原目标图像含有多个目标,,先图像分割,然后匹配子图,imgNum为目标个数for (int n=0; n<imgNum; n++){//子图宽imgW=seg.Vrect[n].right-seg.Vrect[n].left;//子图高imgH=seg.Vrect[n].bottom-seg.Vrect[n].top;//储存子图灰度值double *I=new double[imgW*imgH];double *Ireal=new double[imgW*imgH];double *Ivirtual=new double[imgW*imgH];#define I(ROW,COL) I[imgW*(ROW)+(COL)]#define Ireal(ROW,COL) Ireal[imgW*(ROW)+(COL)]#define Ivirtual(ROW,COL) Ivirtual[imgW*(ROW)+(COL)]POINT ptcenter; //将图像灰度值复制到I中 for(i = 0; i <imgH; i++) {for(j = 0; j <imgW; j++){int ptY=seg.Vrect[n].top+i;int ptX=seg.Vrect[n].left+j;lpSrc=m_pImgData+LineBytes*(m_imgHeight-1-ptY)+ptX;//将256级灰度图像转化为double型I(i,j)=double(*lpSrc);} }Ireal=Template(I,imgW, imgH, tepReal, TW, TW);Ivirtual=Template(I, imgW, imgH, tepVirtual, TW, TW);double distance=0;double Mindis=9000000;for (i=TW/2; i<imgH-TW/2; i++){for (j=TW/2; j<imgW-TW/2; j++){//圆投影矢量和distance=pow((Ireal(i,j)-Itreal(TW/2,TW/2)),2)+pow((Ivirtual(i,j)-Itvirtual(TW/2,TW/2)),2);if (distance<Mindis){Mindis=distance;ptcenter.y=seg.Vrect[n].top+i;ptcenter.x=seg.Vrect[n].left+j;}}}//粗定位中心roughcenter.push_back(ptcenter);}}转载请注明出处!

失败是什么?没有什么,只是更走近成功一步;

圆投影匹配算法描述及实现

相关文章:

你感兴趣的文章:

标签云: