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; 
	} 
 
	  
 
}