⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vf_getminutia.h

📁 指纹模式识别算法接口
💻 H
📖 第 1 页 / 共 2 页
字号:
			if(n != 3)
			{
				continue;
			}
			// 找到叉点三个方向纹线上距离为8的点
			for(k = 0; k < 3; k++)
			{
				GetByDis(tempPtr[k+1], &disPtr[k], 8);
			}
			for(k = 0; k < 4; k++)
			{
				*tempPtr[k] = 0;
			}
			// 求该三个点两两间的距离
			d0 = sqrt((double)((PX(disPtr[1]) - PX(disPtr[2]))*(PX(disPtr[1]) - PX(disPtr[2])) +
				(PY(disPtr[1]) - PY(disPtr[2]))*(PY(disPtr[1]) - PY(disPtr[2]))));
			d1 = sqrt((double)((PX(disPtr[0]) - PX(disPtr[2]))*(PX(disPtr[0]) - PX(disPtr[2])) +
				(PY(disPtr[0]) - PY(disPtr[2]))*(PY(disPtr[0]) - PY(disPtr[2]))));
			d2 = sqrt((double)((PX(disPtr[1]) - PX(disPtr[0]))*(PX(disPtr[1]) - PX(disPtr[0])) +
				(PY(disPtr[1]) - PY(disPtr[0]))*(PY(disPtr[1]) - PY(disPtr[0]))));

			// 距离最短的边对应的是叉线方向
			if(d0 < d1 && d0 < d2)
			{
				x11 = PX(disPtr[1]);
				y11 = PY(disPtr[1]);
				x21 = PX(disPtr[2]);
				y21 = PY(disPtr[2]);
				lpDis = disPtr[0];
			}
			else if(d1 < d0 && d1 < d2)
			{
				x11 = PX(disPtr[0]);
				y11 = PY(disPtr[0]);
				x21 = PX(disPtr[2]);
				y21 = PY(disPtr[2]);
				lpDis = disPtr[1];
			}
			else
			{
				x11 = PX(disPtr[0]);
				y11 = PY(disPtr[0]);
				x21 = PX(disPtr[1]);
				y21 = PY(disPtr[1]);
				lpDis = disPtr[2];
			}
			// 求最短边中点与叉点连线的方向与该点方向场方向的夹角
			angle1 = GetAngle(ForkArr[i].x, ForkArr[i].y, (x11+x21)/2, (y11+y21)/2);
			angle2 = *(g_lpOrient + ForkArr[i].y*IMGW + ForkArr[i].x);
			angle3 = GetAngleDis(angle1, angle2);
			// 如果成钝角,则表示该特征点方向与该点方向场方向相反
			if(angle3 > 90 && angle3 < 270)
			{
				g_Feature.MinutiaArr[EndNum + j].Direction = angle2 + 180;
			}
			else // 如果成锐角,则表示该特征点方向与该点方向场方向相同
			{
				g_Feature.MinutiaArr[EndNum + j].Direction = angle2;
			}
			// 纪录以特征点为中心外接圆半径为trilen的正三角形三个顶点的方向
			a = g_Feature.MinutiaArr[EndNum + j].Direction / EPI + PI/4.0;
			x11 = EndArr[i].x + (sint32)(trilen*cos(a)+ 0.5);
			y11 = EndArr[i].y + (sint32)(trilen*sin(a)+ 0.5);
			g_Feature.MinutiaArr[EndNum + j].Triangle[0] = *(g_lpOrient + y11*IMGW + x11);
			a += PI*2/3.0;
			x11 = EndArr[i].x + (sint32)(trilen*cos(a)+ 0.5);
			y11 = EndArr[i].y + (sint32)(trilen*sin(a)+ 0.5);
			g_Feature.MinutiaArr[EndNum + j].Triangle[1] = *(g_lpOrient + y11*IMGW + x11);
			a += PI*2/3.0;
			x11 = EndArr[i].x + (sint32)(trilen*cos(a)+ 0.5);
			y11 = EndArr[i].y + (sint32)(trilen*sin(a)+ 0.5);
			g_Feature.MinutiaArr[EndNum + j].Triangle[2] = *(g_lpOrient + y11*IMGW + x11);

			g_Feature.MinutiaArr[EndNum + j].x = ForkArr[i].x; //横坐标
			g_Feature.MinutiaArr[EndNum + j].y = ForkArr[i].y; //纵坐标
			g_Feature.MinutiaArr[EndNum + j].Type = VF_MINUTIA_FORK; // 类型


			j++;
		}
		ForkNum = j; // 叉点数目


	}

	// 如果循环32次都不能得到理想结果,则表示图像质量差,返回错误
	if(loopnum >= 32)
	{
		EndNum = 0;
		ForkNum = 0;
		return 1;
	}
	// 特征点数目等于端点数加叉点数
	g_Feature.MinutiaNum = (uint8)(EndNum+ForkNum);

	//  特征点数目太少则返回错误
	if(ForkNum + EndNum < 8)
	{
		EndNum = 0;
		ForkNum = 0;
		return 1;
	}

	return 0;
}

/*

//
//	getSingular: 提取中心点三角点
//
void  getSingular()
{
	sint32  x, y, i, j;
	sint32  DSite8[8][8];
	sint32  DSiteR1[8] = {-1, BOW-1, BOW, BOW+1, 1, -BOW+1, -BOW, -BOW-1};
	bool    flag, flag2, flag3, fg;
	sint32  temp;
	uint8   *lpDir;
	uint8	*lpCore;
	sint32  asum;
	sint32  mina;
	sint32  minindex;
	sint32  DAngleSum[8];
	sint32  ad;
	double  dis;
	VF_MINUTIAPTR    core;
	VF_MINUTIAPTR    delta;
	sint32	CoreNum, DeltaNum;
	//  半径为15的圆上100个点相对于圆心的地址偏移
	sint32 SiteR15[100] = {
		0*IMGW-15, 1*IMGW-15, 2*IMGW-15, 3*IMGW-15, 4*IMGW-15, 4*IMGW-14, 5*IMGW-14, 
		6*IMGW-14, 7*IMGW-13, 8*IMGW-13, 8*IMGW-12, 9*IMGW-12, 10*IMGW-11, 11*IMGW-11, 
		11*IMGW-10, 12*IMGW-9, 12*IMGW-8, 13*IMGW-8, 13*IMGW-7, 14*IMGW-6, 14*IMGW-5, 
		14*IMGW-4, 15*IMGW-4, 15*IMGW-3, 15*IMGW-2, 15*IMGW-1, 15*IMGW+0, 15*IMGW+1, 
		15*IMGW+2, 15*IMGW+3, 14*IMGW+3, 14*IMGW+4, 14*IMGW+5, 13*IMGW+6, 13*IMGW+7, 
		12*IMGW+7, 12*IMGW+8, 11*IMGW+9, 11*IMGW+10, 10*IMGW+10, 9*IMGW+11, 8*IMGW+11, 
		8*IMGW+12, 7*IMGW+12, 6*IMGW+13, 5*IMGW+13, 4*IMGW+13, 4*IMGW+14, 3*IMGW+14, 
		2*IMGW+14, 1*IMGW+14, 0*IMGW+14, -1*IMGW+14, -2*IMGW+14, -3*IMGW+14, -3*IMGW+13, 
		-4*IMGW+13, -5*IMGW+13, -6*IMGW+12, -7*IMGW+12, -7*IMGW+11, -8*IMGW+11, -9*IMGW+10, 
		-10*IMGW+10, -10*IMGW+9, -11*IMGW+8, -11*IMGW+7, -12*IMGW+7, -12*IMGW+6, -13*IMGW+5, 
		-13*IMGW+4, -13*IMGW+3, -14*IMGW+3, -14*IMGW+2, -14*IMGW+1, -14*IMGW+0, -14*IMGW-1, 
		-14*IMGW-2, -14*IMGW-3, -14*IMGW-4, -13*IMGW-4, -13*IMGW-5, -13*IMGW-6, -12*IMGW-7, 
		-12*IMGW-8, -11*IMGW-8, -11*IMGW-9, -10*IMGW-10, -10*IMGW-11, -9*IMGW-11, -8*IMGW-12, 
		-7*IMGW-12, -7*IMGW-13, -6*IMGW-13, -5*IMGW-14, -4*IMGW-14, -3*IMGW-14, -3*IMGW-15, 
		-2*IMGW-15, -1*IMGW-15
	};
	// 圆上100个点与圆心连线的角度(圆与水平线相交左边的交点为起始点)
	sint32    OriR15[100] = {
		180, 176, 172, 168, 165, 164, 160, 156, 151, 148, 146, 143, 137, 135, 
		132, 126, 123, 121, 118, 113, 109, 105, 104, 101, 97, 93, 90, 86, 
		82, 78, 77, 74, 70, 65, 61, 59, 56, 50, 47, 45, 39, 36, 
		33, 30, 24, 21, 17, 15, 12, 8, 4, 0, 355, 351, 347, 347, 
		342, 338, 333, 329, 327, 323, 318, 314, 311, 306, 302, 300, 296, 291, 
		287, 282, 282, 278, 274, 269, 265, 261, 257, 254, 252, 248, 245, 239, 
		236, 233, 230, 224, 222, 219, 213, 210, 208, 204, 199, 195, 192, 191, 
		187, 183
	};

	core = (VF_MINUTIAPTR)(g_lpMemory + sizeof(VF_FEATURE));
	delta = (VF_MINUTIAPTR)(g_lpMemory + sizeof(VF_FEATURE) + 
								sizeof(VF_MINUTIA)*5);

  // 量化的8个方向上的8个点的地址偏移
	for(i = 0; i < 8; i++)
	{
		DSite8[0][i] = i+1;
		DSite8[1][i] = (i+1)*(IMGW + 1);
		DSite8[2][i] = (i+1)*(IMGW);
		DSite8[3][i] = (i+1)*(IMGW - 1);
		DSite8[4][i] = -(i+1);
		DSite8[5][i] = -(i+1)*(IMGW + 1);
		DSite8[6][i] = -(i+1)*(IMGW);
		DSite8[7][i] = (i+1)*(-IMGW + 1);
	}

	CoreNum = 0;
	DeltaNum = 0;
	
	flag2 = true;
	flag3 = true;

	temp = VF_BW*IMGW;
	for(y = VF_BW; y <= IMGH-VF_BW; y++)
	{
		for(x = VF_BW; x <= IMGW-VF_BW; x++)
		{
			// 检查是否为边缘部分
			lpDir = g_lpBlockOrient + (y/VF_BW)*BOW + x/VF_BW;
			if(*lpDir == 255)
			{
				continue;
			}
			flag = true;
			for(i = 0; i < 8; i++)
			{
				if(*(lpDir + DSiteR1[i]) == 255)
				{
					flag = false;
					break;
				}				
			}
			if(!flag)
			{
				continue;
			}

			// 检查是否该点方向变化剧烈,变化剧烈才有可能是奇异点
			asum = 0;
			for(i = 0; i < 8; i++)
			{
				ad = GetJiajiao((sint32)(*(lpDir+DSiteR1[(i+1)%8])),
								(sint32)(*(lpDir+DSiteR1[i])));
				asum += ad;
			}
			if(abs(asum - 180) > 60)
			{
				continue;
			}
			
			// 检查8八个量化方向上的8个点是否为无效区域内
			lpDir = g_lpOrient + temp + x;
			if(*lpDir == 255)
			{
				continue;
			}
			flag = true;
			for(i = 0; i < 8 && flag; i++)
			{
				for(j = 0; j < 8 && flag; j++)
				{
					if(*(lpDir + DSite8[i][j]) == 255)
					{
						flag = false;
						break;
					}
				}
			}
			if(!flag)
			{
				continue;
			}
			// 检查第二圈上的夹角和是否比较大,如果是奇异点这个值应该较大
			asum = 0;
			for(i = 0; i < 8; i++)
			{
				asum += GetJiajiao((sint32)(*(lpDir+DSite8[(i+1)%8][2])),
					(sint32)(*(lpDir+DSite8[i][2])));
			}

			if(asum < 90)
			{
				continue;
			}
			
			// 求7个圈上8个方向上的角度变化和。中心点角度变化和应该为180,三角点为-180
			for(i = 0; i < 8; i++)
			{
				DAngleSum[i] = 0;
			}
			for(j = 1; j < 8; j++)
			{
				for(i = 0; i < 8; i++)
				{
					ad = AngleSub((sint32)(*(lpDir+DSite8[(i+1)%8][j])),
									(sint32)(*(lpDir+DSite8[i][j])));
					if(ad > 90 || ad < -90)
					{
						continue;
					}

					DAngleSum[j] += ad;
				}
			}
			// 判断是否为中心点。要求7个圈上的角度变化和都是180
			flag = true;
			for(i = 1; i < 8; i++)
			{
				if(DAngleSum[i] != 180)
				{
					flag = false;
					break;
				}
			}
			//是的话则记录下来其坐标
			if(flag && flag2)
			{
				if(CoreNum == 0)
				{
					core[CoreNum].x = x;
					core[CoreNum].y = y;
					core[CoreNum].Type = 1;
					CoreNum++;
				}
				else
				{
					// 检查在小距离内是否有中心点,有的话将它们坐标做平均做为中心点坐标
					fg = true;
					for(i = 0; i < CoreNum; i++)
					{
						dis = sqrt((double)((core[i].x/core[i].Type - x)*
							(core[i].x/core[i].Type - x) +
							(core[i].y/core[i].Type - y)*
							(core[i].y/core[i].Type - y)));
						if(dis < 8)
						{
							core[i].x += x;
							core[i].y += y;
							core[i].Type++;
							fg = false;
							break;
						}
					}
					if(fg)
					{
						core[CoreNum].x = x;
						core[CoreNum].y = y;
						core[CoreNum].Type = 1;
						CoreNum++;
						if(CoreNum > VF_MAXCORENUM)
						{
							flag2 = false;
						}

					}
				}
				continue;
			}
			// 判断是否为三角点。要求7个圈上的角度变化和都是-180

			flag = true;
			for(i = 1; i < 8; i++)
			{
				if(DAngleSum[i] != -180)
				{
					flag = false;
					break;
				}
			}
			if(flag && flag3)
			{
				//*lpTemp = 255;
				if(DeltaNum == 0)
				{
					delta[DeltaNum].x = x;
					delta[DeltaNum].y = y;
					delta[DeltaNum].Type = 1;
					DeltaNum++;
				}
				else
				{
					// 检查在小距离内是否有三角点,有的话将它们坐标做平均做为三角点坐标
					fg = true;
					for(i = 0; i < DeltaNum; i++)
					{
						dis = sqrt((double)((delta[i].x/delta[i].Type - x)*
							(delta[i].x/delta[i].Type - x) +
							(delta[i].y/delta[i].Type - y)*
							(delta[i].y/delta[i].Type - y)));
						if(dis < 8)
						{
							delta[i].x += x;
							delta[i].y += y;
							delta[i].Type++;
							fg = false;
							break;
						}
					}
					if(fg)
					{
						delta[DeltaNum].x = x;
						delta[DeltaNum].y = y;
						delta[DeltaNum].Type = 1;
						DeltaNum++;
						if(DeltaNum > VF_MAXDELTANUM)
						{
							flag3 = false;
						}

					}
				}
			}

		}
		temp += IMGW;
	}
	// 中心点太多则去掉多余的
	if(DeltaNum > VF_MAXDELTANUM)
	{
		DeltaNum = VF_MAXDELTANUM;
	}

	// 三角点太多则去掉多余的
	if(CoreNum > VF_MAXCORENUM)
	{
		CoreNum = VF_MAXCORENUM;
	}
	
	// 求中心点方向. 圆心与圆上所有点的连线与该点方向夹角最小,则中心点方向为该点方向
	for(i = 0; i < CoreNum; i++)
	{
		core[i].x /= core[i].Type;
		core[i].y /= core[i].Type;
		core[i].Type = VF_MINUTIA_CORE;
		lpCore = g_lpOrient + core[i].y*IMGW + core[i].x;
		mina = 360;
		for(j = 0; j < 100; j++)
		{
			lpDir = lpCore + SiteR15[j];
			temp = OriR15[j];
			if(temp >= 180)
				temp -=180;
			temp = GetJiajiao(temp, *lpDir);
			if(temp < mina)
			{
				mina = temp;
				minindex = j;
			}
		}
		// 夹角最小值要小于6度
		if(mina < 6)
		{
			lpDir = lpCore + SiteR15[minindex];
			if(OriR15[minindex] >= 180)
				core[i].Direction = (*lpDir + 180);
			else
				core[i].Direction = *lpDir;
		}
		else
		{
			core[i].Direction = 400;
		}
	}

	for(i = 0; i < DeltaNum; i++)
	{
		delta[i].x /= delta[i].Type;
		delta[i].y /= delta[i].Type;
		delta[i].Type = VF_MINUTIA_DELTA;
	}

	g_lpFeature->CoreNum = (uint8)CoreNum;
	g_lpFeature->DeltaNum = (uint8)DeltaNum;

	memcpy((void *)g_lpFeature->CoreArr, (void *)&core[0], CoreNum*sizeof(VF_MINUTIA));

	memcpy((void *)g_lpFeature->DeltaArr, (void *)&delta[0], DeltaNum*sizeof(VF_MINUTIA));

}


*/

#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -