www.pudn.com > fingerprint.rar > funcs.cpp
#include "stdafx.h"
#include "dibapi.h"
#include "types.h"
#include "math.h"
#include "string.h"
#include "Commdlg.h"
/////8领域的的各个变化值
const int dirs[8][2]={{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1},{-1,0},{-1,1}};
#define DISTH 1.4142135623730950488016887242097
/////方向图中8个方向对应的8领域方向优先数组
const int gsearchdir[8][4]=
{
{0,1,3,2},//0
{1,0,2,3},//1
{1,0,2,3},//2
{1,2,0,3},//3
{3,2,0,1},//4
{3,2,0,1},//5
{3,0,2,1},//6
{3,0,2,1}//7
};
///方向图中8个方向对应的角度
const int gAngle[8]={0,27,45,63,90,117,135,153};
/////8领域中8同对应的角度
const int dAngle[8]={0,45,90,135,180,225,270,315};
char szOpenFile[MAX_PATH];
char szFileTitle[MAX_PATH];
OPENFILENAME ofn={sizeof(OPENFILENAME),NULL,NULL,
"位图文件(*.bmp)\0*.bmp\0所有文件(*.*)\0*.*\0\0",
(LPSTR)NULL,0L,1,szOpenFile,sizeof(szOpenFile),szFileTitle,sizeof(szFileTitle),
NULL,(LPSTR)NULL,OFN_FILEMUSTEXIST|OFN_ENABLESIZING|OFN_READONLY
,0,0,"bmp",
NULL,NULL,NULL,
};
//////生成256级灰度的位图数据
HDIB CreateIntensityDIB(UINT dwWidth,UINT dwHeight){
HDIB hDIB=CreateDIB(dwWidth,dwHeight,8);
LPBITMAPINFO lpbi=(LPBITMAPINFO)::GlobalLock(hDIB);
//////生成256级灰度的颜色表
for(int i=0;i<256;i++)
{
lpbi->bmiColors[i].rgbBlue =i;
lpbi->bmiColors[i].rgbGreen =i;
lpbi->bmiColors[i].rgbRed =i;
lpbi->bmiColors[i].rgbReserved =0;
}
GlobalUnlock(hDIB);
return hDIB;
}
/////将24位真彩色转换成256级灰度
HDIB ConvertToIntensityDIB(HDIB hDIB){
LPSTR lpbi=(LPSTR)GlobalLock(hDIB);
LPBYTE lpBit=(LPBYTE)FindDIBBits((LPSTR)lpbi);
int w,h,bpl,ibpl;
w=DIBWidth(lpbi);h=DIBHeight(lpbi);
bpl=BytesPerLine((LPBITMAPINFOHEADER)lpbi);
HDIB hIDIB=CreateIntensityDIB(w,h);
LPSTR lpibi=(LPSTR)GlobalLock(hIDIB);
LPBYTE lpiBit=(LPBYTE)FindDIBBits(lpibi);
ibpl=BytesPerLine((LPBITMAPINFOHEADER)lpibi);
int iw,ih;
LPBYTE lpLineBits=lpBit;
LPBYTE lpiLineBits=lpiBit;
for(ih=0;ihGMean[k+4])
GDiff[k]=GMean[k]-GMean[k+4];
else
GDiff[k]=GMean[k+4]-GMean[k];
DMax=0;DiffMax=GDiff[0];
for(k=1;k<4;k++)
{
if(GDiff[k]>DiffMax)
{
DMax=k;
DiffMax=GDiff[k];
}
}
///该点的方向
dk=BLine[j][i]-GMean[DMax];if(dk<0)dk=-dk;
dk4=BLine[j][i]-GMean[DMax+4];if(dk4<0)dk4=-dk4;
if(dk180)d1=360-d1;
int d2=mp.rAngle+180-dAngle[isearch];
d2=(d2+360)%360;
if(d2>180)d2=360-d2;
if(d1>d2)mp.rAngle+=180;
if(mp.rAngle>=360)mp.rAngle-=360;
}
int i=im,j=jm;
int m,n,is,js;
double dist=0;
vectorrpt;
RPOINT pt;
int mcount=1;
while(1)
{
if(isearch&0x01)///45方向的话距离加根号2
dist+=DISTH;
else ///垂直与水平方向的话距离加1
dist+=1.0f;
///该方向上下一点
m=i+dirs[isearch][1];
n=j+dirs[isearch][0];
dir=(isearch+5)%8;
isearch=-1;
///计算一下点的位置
if(DLine[n][m].lc==0)
{
///如果还没有计算过这一点的连通数
////在另外7个方向找黑点
DLine[n][m].lc=1;
for(id=0;id<7;id++)
{
js=n+dirs[dir][0];
is=m+dirs[dir][1];
if(BLine[js][is]==0)
{
///连通数加1
DLine[n][m].lc++;
isearch=dir;
}
///下一方向
dir++;
dir%=8;
}
/////连通数为2时找到下一个点的位置
}else if(DLine[n][m].lc==2)
{
///已经计算过连通数
///而且连通数为2
///就搜索下一个点
for(id=0;id<7;id++)
{
js=n+dirs[dir][0];
is=m+dirs[dir][1];
if(BLine[js][is]==0)
{
isearch=dir;
break;
}
dir++;
dir%=8;
}
}
///如果达到采样距离,就记录该点
///如果到下一个细节点,就记录该点
if(dist>=mcount*SAMPLE_DISTANCE||DLine[n][m].lc!=2)
{
////坐标
pt.x=m;
pt.y=n;
///该采样点到起点的距离
pt.d=(int)sqrt((n-jm)*(n-jm)+(m-im)*(m-im));
///极角
pt.e=180*atan2(n-jm,m-im)/PI;
pt.e-=mp.rAngle;
pt.e=(pt.e+360)%360;
if(pt.e>180)pt.e=360-pt.e;
rpt.push_back(pt);
mcount++;
}
if(DLine[n][m].lc==2)
{
i=m;
j=n;
}else
{
////脊线结束
break;
}
}
if(mcount<4)return FALSE;
mp.rpCount=--mcount;
mp.rPoint=new RPOINT[mcount];
///拷贝数组
memcpy(mp.rPoint,&(rpt[0]),sizeof(RPOINT)*mcount);
rpt.resize(0);
return TRUE;
}
void EmptyFingerPrint(FINGER_PRINT&fPrint){
for(int i =0;iee)return -1;
else if(p1->e>p2->e)return 1;
else return 0;
}
////指纹图与模板图进行匹配
////参数
////fMatch 要匹配的指纹
////fpTemplate 模板指纹
////szOutput 输出匹配结果的字串
BOOL MatchFingerPrint(FINGER_PRINT&fpMatch,FINGER_PRINT&fpTemplate,LPTSTR szOutput)
{
int i,k,imax=fpMatch.size();
int j,l,jmax=fpTemplate.size();
int nMatch,nTemplate;
double Diff_Dist,Diff_Angle,diff;
MPOINT*mpMatch,*mpTemplate;
RPOINT*rpMatch,*rpTemplate;
mpMatch=&fpMatch[0];
mpTemplate=&fpTemplate[0];
int** rotate=new int*[imax];
for(i=0;inMatch)nTemplate=nMatch;
/////统计极径差与角度差的平均
for(k=0;k0)Diff_Dist+=diff;
else Diff_Dist-=diff;
diff=rpMatch[k].e-rpTemplate[k].e;
if(diff<0)diff=-diff;
if(diff>180)diff=360-diff;
Diff_Angle+=diff;
}
/* for(;k0)Diff_Dist+=diff;
else Diff_Dist-=diff;
diff=rpMatch[k].e-rpTemplate[k].e;
if(diff<0)diff=-diff;
if(diff>180)diff=360-diff;
Diff_Angle+=diff;
}*/
Diff_Dist/=nTemplate;
Diff_Angle/=nTemplate;
if(Diff_Dist=180)rotate[i][j]=360-rotate[i][j];
continue;
}
}
}
//////不可匹配
rotate[i][j]=400;
}
}
/////计算匹配度
int dx,dy,da;double asize;
int ibest=0,jbest=0,scorebest=0,score;
POPOINT *mpop=new POPOINT[imax];
POPOINT *tpop=new POPOINT[jmax];
MATCHBOX*box =new MATCHBOX[jmax];
for(j=0;jA_MAX)box[l].hasize=A_MAX;
else box[l].hasize=asize;
}else
{
//////对应相同一占点,角窗可以最大
box[l].hasize=180;
}
}
for(i=0;i180)da=360-da;
if(da>DIFF_DT_MAX)continue;
/////在界限盒内
if(mpop[k].rtpop[l].r-box[l].hrsize
&& mpop[k].e>tpop[l].e-box[l].hasize
)score++;
}
}
////记录最佳匹配
if(score>=scorebest)
{
ibest=i;
jbest=j;
scorebest=score;
}
}
}
////释放内存
delete[] box;
delete[] mpop;
delete[] tpop;
for(i=0;ijmax)vmatch=((double)scorebest)/jmax;
else vmatch=((double)scorebest)/imax;
/////匹配结果输出
if(vmatch>MATCH_LOWBOUND)
{
sprintf(szOutput,"匹配:\n\n待配图细节点%d,\n模板图细节点%d,\n匹配积分%d",jmax,imax,scorebest);
return TRUE;
}else
{
sprintf(szOutput,"不匹配:\n\n待配图细节点%d,\n模板图细节点%d,\n匹配积分%d",jmax,imax,scorebest);
return FALSE;
}
}