基于相关系数影像匹配实习报告.docx
《基于相关系数影像匹配实习报告.docx》由会员分享,可在线阅读,更多相关《基于相关系数影像匹配实习报告.docx(13页珍藏版)》请在冰豆网上搜索。
基于相关系数影像匹配实习报告
基于相关系数影像匹配实习报告
一、实习内容与目的
通过上机编程实现基于相关系数算法的影像匹配,从而更加熟练的掌握书本上关于影像
匹配及相关系数算法的理论知识,并熟悉上机编程的操作。
、实习原理
影像匹配实质上是在两幅或是多幅影像之间识别同名点,其中基于相关系数的算法是实
现影像匹配的基本算法之一。
相关系数是标准化的协方差函数,协方差函数除以两信号的方差即得相关系数。
计算相
关系数的公式如下:
g(x,y)与g'x',y'的相关系数为:
C(p,q)
.CggCgg(p'q)
其中:
2
Cgg={g(x,y)-E[g(x,y)]}dxdy
(x,y)申
2
Cgg(p,q)二..{g(xp,yq)-E[g(xp,yq)]}dxdy
(x,y)申
若(p0,qO)>(p,q),(p丰p0,q丰q0),贝Up0,q0为搜索区影像相对于目标区影像的位移参数。
由离散灰度数据对相关系数的估计为
:
(c,r)
mn
、、(gi,j-g)(gi.r,jc-g)
i丄j丄
mn
:
一二(gi,ji二j
-gr,c)2
9c,r
gi
j
=1
考虑到计算工作量,相关系数的实用公式为
Rc,r)=,
Imn
Ii=1j=1
mn
Ui,jgi-r,jc^mn
mn
(、、gi,j
idj
n
X二二gi':
:
;r,j:
:
;c)
j7
i=1
mnmn
——(送送gij][送送g%十,j七
mniji4j4
mni=1
n
(„gi'.r,j.c)2]
jT
三、实习步骤及相关代码
在第一次点特征点实习的基础上我们组进行了第二次基于相关系数的影像匹配实习。
所以程序实现的部分操作直接利用前次实习的中的程序。
(1)读入左右影像
FILE*pSrcFileLeft=NULL;
pSrcFileLeft=fopen(srcFileLeft,"rb");
if(pSrcFileLeft==NULL)
{
printf("原始左片影像打开失败\n");
returnFAILURE;
}
FILE*pSrcFileRight=NULL;
pSrcFileRight=fopen(srcFileRight,"rb");
if(pSrcFileRight==NULL)
{
printf("原始右片影像打开失败\n");
returnFAILURE;
}
(2)确定目标窗口大小
通过老师课堂上的讲授和我们在编程过程中的不断尝试,我们默认使用的窗口的尺
寸为11*11。
(3)确定目标点的位置
由前次的实习中得到左相片中的特征点作为这次实习的目标点。
(4)预测右影像搜索范围
本程序中也在左相片中计算出了特征点,然后将左右两相片中的特征点进行计算相
关系数。
(5)逐窗口计算相关系数并保存相应的储存单元
将左相片中的目标点与右相片中的特征点进行相关系数的计算。
(6)比较相关系数,取最大相关系数作为匹配点
对于分别比较上一步骤中计算出的相关系数,选取出最大的一个相关系数作为匹配
点。
程序操作如下:
在程序主界面中点击Extend中选取ImageMatch选项,然后进入参数设置界面。
设置读取和保存影像路径和窗口大小等参数后,点击Progress进行运算。
ImageMatchcompon忙nt
四、实习结果及分析
作为数据源的左右影像如些图所示:
左相片右相片
经过计算后得到的目标点左右图像分别如下所示:
左相片右相片
显示匹配点号:
寸rrbatchitKt-5土
廿同■&点对敵:
5
114
5-5
104
0-9E42EB
103
^90
441
0.917248
783
5S7
0,012^58
520
0.1^04723
138
G47
^0202^
通过老师得到的图片可以看出在左相片中得到的五个目标点中有四个在右相片中找到了同名点,由此可以看出本程序基本满足实习要求,并得到理想的结果。
不足的地方就是选取
的特征点的数量不够多,这样就无法判断本程序的“误判”的情况如何。
五、实习体会
在学习到相关系数的时候,一看到计算相关系数的公式的时候我就有种被折服的感觉,那个公式实在是太复杂,它使我感觉我怎么也不能记住这个复杂的公式。
不过经过这次实习
后,我觉得这个公式又不是当初认为的那样无法记忆。
我想这次实习我最大的收获就是对于
之前在学习过程中遇到不懂知识以及难以记忆的知识都得到了加强,方便了我对他们的理解
与记忆。
其次,在编程过程中更加锻炼自己动手编程的能力,使得我编程能力较之前有着一定的提高。
每次编程实习都是一个积累经验的过程,然后通过一次次的实习后,我最终的能力就
能够得到很好的体现。
附件:
height,
voidMoravec(BYTE*pSrcBits,vector*FeaturePoint,
intm_threshold,intm_window1,intm_window2,intwidth,intint*Count1)
{
oooooooo此部分程序与点特征程序中代码一样,因此不再重复粘贴
}
vectorRemoveReplicative(vectorv)
{
vectorret;
vector:
:
iteratoriter=v.begin();
ret.clear();
ret.push_back(*iter);
vector:
:
iteratoriter2;
BOOLb(FALSE);
for(iter=v.begin();iter!
=v.end();++iter)
{
b=false;
for(iter2=ret.begin();iter2!
=ret.end();++iter2)
{
if(iter->x==iter2->x&&iter->y==iter2->y)
{
b=TRUE;//存在
break;
}
}
if(b==FALSE)
{
ret.push_back(*iter);
}
}
returnret;
}
voidSaveBand(intwidth,intheight,intbyteCount,intbiBitCount,LPBYTEpBits,
CStringSavePath)
{
BITMAPFILEHEADERbmfh;
BITMAPINFOHEADERbmih;
bmfh.bfType=0x4d42;//0x42="B"0x4d="M"
bmfh.bfReserved1=0;
bmfh.bfReserved2=0;
if(biBitCount==8)
{
bmfh.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+
256*4;
bmfh.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+256*4+byteCount;
}
elseif(biBitCount==24)
{
bmfh.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
bmfh.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+byteCount;
}
else
{
MessageBox(NULL,"8bitor24bitaccepted","错误",MB_ICONERROR);
return;
}
bmih.biBitCount=biBitCount;
bmih.biWidth=width;
bmih.biHeight=height;
bmih.biSize=40;
bmih.biPlanes=1;
bmih.biCompression=BI_RGB;
bmih.biSizelmage=bmfh.bfSize;
bmih.biCIrlmportant=0;
bmih.biCIrUsed=0;
bmih.biXPelsPerMeter=0;
bmih.biYPelsPerMeter=0;
CFilef;
//保存位图
if(f.Open(SavePath,CFile:
:
modeCreate|CFile:
:
modeWrite))
{
f.Write(&bmfh,sizeof(bmfh));
f.Write(&bmih,sizeof(bmih));
if(biBitCount==8)
{
RGBQUADrgb[256];
inti(0);
for(;i<256;++i)
{
rgb[i].rgbBlue=i;
rgb[i].rgbGreen=i;
rgb[i].rgbRed=i;
rgb[i].rgbReserved=0;
}
//修改颜色表255对应的颜色
rgb[255].rgbBlue=0;
rgb[255].rgbGreen=0;
rgb[255].rgbRed=255;
f.Write(rgb,sizeof(RGBQUAD)*256);
}
f.Write(pBits,byteCount);
f.Close();
}
else
{
MessageBox(NULL,"保存图像失败","错误",MB_ICONERROR);return;
}
}
voidDrawCross(BYTE*pBits,vectorFeaturePoint,int_width,intbyteCount)
{
vector:
:
iteratoriter;
inti(0),j(0);
for(i=0;i{
if(pBits[i]==255)
pBits[i]=254;
}
for(iter=FeaturePoint.begin();iter!
=FeaturePoint.end();++iter)
{
i=iter->y;
j=iter->x;
pBits[i*_width切=255;
pBits[i*_width+j+1]=255;
pBits[i*_width+j-1]=255;
pBits[(i+1)*_width切=255;
pBits[(i-1)*_width+j]=255;pBits[i*_width+j+2]=255;
pBits[i*_width+j-2]=255;
pBits[(i+2)*_width切=255;
pBits[(i-2)*_width+j]=255;
}
}
voidDrawCross(BYTE*pBitsI,BYTE*pBits2,vectorMatchedPoints,int_width1,int_width2,intbyteCount1,intbyteCount2)
{
vector:
:
iteratoriter;
inti(0),j(0);
for(i=0;i{
if(pBits1[i]==255)pBits1[i]=254;
}
for(j=0;j{
if(pBits2[j]==255)pBits2[j]=254;
}
for(iter=MatchedPoints.begin();iter!
=MatchedPoints.end();++iter)
{
i=iter->y1;
j=iter->x1;
pBits1[i*_width1+j]=255;
pBits1[i*_width1+j+1]=255;pBits1[i*_width1+j-1]=255;
pBits1[(i+1)*_width1+j]=255;pBits1[(i-1)*_width1切=255;
pBits1[i*_width1+j+2]=255;pBits1[i*_width1+j-2]=255;
pBits1[(i+2)*_width1+j]=255;pBits1[(i-2)*_width1切=255;
i=iter->y2;
j=iter->x2;
pBits2[i*_width2+j]=255;//
pBits2[i*_width2+j+1]=255;
pBits2[i*_width2+j-1]=255;pBits2[(i+1)*_width2+j]=255;
pBits2[(i-1)*_width2切=255;pBits2[i*_width2+j+2]=255;
pBits2[i*_width2+j-2]=255;pBits2[(i+2)*_width2+j]=255;
pBits2[(i-2)*_width2切=255;
}
}voidSaveList(vectorFeaturePoint,CStringtxtFile)
{
FILE*pTxtFile=fopen(txtFile,"wt");
if(!
pTxtFile)
return;
fprintf(pTxtFile,"#\t特征点数:
%d\n\n",FeaturePoint.size());
fprintf(pTxtFile,"坐标X\t坐标Y\t兴趣值\n");
vector:
:
iteratoriter;
for(iter=FeaturePoint.begin();iter!
=FeaturePoint.end();++iter)
fprintf(pTxtFile,"%d\t%d\t%d\n",iter->x,iter->y,(int)iter->IV);fclose(pTxtFile);
}
voidSaveList(vectorMatchedPoints,CStringtxtFile)
{
FILE*pTxtFile=fopen(txtFile,"wt");
if仲TxtFile)
return;
fprintf(pTxtFile,"#同名点对数:
%d\n\n",MatchedPoints.size());
vector:
:
iteratoriter;
for(iter=MatchedPoints.begin();iter!
=MatchedPoints.end();++iter)
fprintf(pTxtFile,"%d\t%d\t%d\t%d\t%f\n",
iter->x1,iter->y1,iter->x2,iter->y2,iter->coefficient);fclose(pTxtFile);
}
int_tmain(intargc,TCHAR*argv[],TCHAR*envp[])
{
if(argc!
=15)
{
:
:
MessageBox(NULL,"启动参数不正确,请从GUI.exe或命令行参数启动
",””,MB_ICONASTERISK);
returnFAILURE;
}
system("Modecon:
COLS=50LINES=150");
system("titleImage_Match");
intnRetCode=0;
if(!
AfxWinlnit(:
:
GetModuleHandle(NULL),NULL,:
:
GetCommandLine(),0))
{
cerr<<_T("FatalError:
MFCinitializationfailed")<nRetCode=1;
returnnRetCode;
}
CStringsrcFileLeft,srcFileRight,dstFileLeft,dstFileRight,txtFile;
CStringthreshold_Left,window1_Left,window2_Left;
CStringthreshold_Right,window1_Right,window2_Right;
CStringCoRelated,window3,flag1;//启动参数
srcFileLeft=argv[1];
srcFileRight=argv[2];
dstFileLeft=argv[3];
dstFileRight=argv[4];
txtFile=argv[5];
threshold_Left=argv[6];//阈值
window1_Left=argv[7];
window2_Left=argv[8];
threshold_Right=argv[9];
window1_Right=argv[10];
window2_Right=argv[11];
CoRelated=argv[12];
window3=argv[13];
flag1=argv[14];//判断是否在创建结果文件后显示
intm_threshold_L=atoi(threshold_Left);
intm_window1_L=atoi(window1_Left);
intm_window2_L=atoi(window2_Left);
intm_threshold_R=atoi(threshold_Right);
intm_window1_R=atoi(window1_Right);
intm_window2_R=atoi(window2_Right);
doublem_CoRelated=(double)atoi(CoRelated)/100;
intm_window3=atoi(window3);
intm_flag1=atoi(flag1);
if(GetFileAttributes(srcFileLeft)==-1)
{
CStringerr;
err.Format(”文件:
%s不存在",srcFileLeft);
:
:
MessageBox(NULL,err,"Error",MB_ICONERROR);returnFAILURE;
}
if(GetFileAttributes(srcFileRight)==-1)
{
CStringerr;
err.Format(”文件:
%s不存在",srcFileRight);
:
:
MessageBox(NULL,err,"Error",MB_ICONERROR);returnFAILURE;
}
//打开2幅影像
FILE*pSrcFileLeft=NULL;
pSrcFileLeft=fopen(srcFileLeft,"rb");
if(pSrcFileLeft==NULL)
{
printf("原始左片影像打开失败\n");