指纹模式识别算法源码及其测试和应用方法

指纹算法需求

指纹特征值生成、比对API库需求:

  1. 可输出指纹图像。图像格式为bmp,小于等于500DPI,不大于50K。
  2. 可输出指纹模板。生成模板需要至少采集几次指纹需说明,建议不超过三次。模板大小不超过1K。模板生成时间不大于1秒。
  3. 可输出指纹特征值(可以是非字符串格式)。特征值大小不超过512B。
  4. 可输出指纹特征值字符串。字符串为可见字符,长度不超1024。
  5. 指纹比对时,支持输入指纹特征值字符串比对。
  6. 指纹比对时,支持输入指纹图像进行比对。
  7. 指纹比对API支持多线程模式,支持大并发调用。
  8. 指纹比对支持1:1,即指纹验证。
  9. 指纹比对支持1:N,即指纹辨识。
  10. 指纹比对时每枚比对速度要求小于0.1秒。
  11. 认假率小于0.0001% 。
  12. 拒真率小于0.75% 。
  13. 库要求32位,但支持在64位操作系统运行。
  14. 可提供dll、jar两种形式API的库。
  • 环境要求

系统列表

Windows

2003 server/xp/win7

Linux

>=内核2.6

Aix unix

>=5.2

Android

 

废话不多说,直接上干货,先附上一张指纹算法项目的思路流程图:

点击这里:指纹项目的算法及其测试完整Github链接

一、先讲解一下指纹算法源码的思路

从指纹图像中提取指纹特征:

int __stdcall Analyze(BYTE *lpImage, int Width, int Height, BYTE *lpFeature, int *lpSize)
{
	///
	//  Width:	[in] 指纹图像宽度
	//  Height:	[in] 指纹图像高度
	//  lpImage:    [in] 指纹图像数据指针
	//  Resolution:	[in] 指纹图像分辨率,默认500
	//  lpFeature:	[out] 提取的指纹特征数据指针
	//  lpSize:	[out] 指纹特征数据大小
	
	// TODO: Add your implementation code here
	VF_RETURN	re;

	// 导入指纹图像数据
	VF_ImportFinger(lpImage, Width, Height);

	// 处理指纹图像,提取指纹特征
	re = VF_Process();
	if (re != VF_OK)
		return re;

	// 对指纹特征进行编码
	re = VF_FeatureEncode(&g_Feature, lpFeature, lpSize);
	if (re != VF_OK)
		return re;

	return 0;
}

对两个指纹进行特征比对:

int __stdcall PatternMatch(BYTE *lpFeature1, BYTE *lpFeature2, int *lpScore)
{
	//	lpFeature1:		[in] 第一个指纹特征
	//	lpFeature2:		[in] 第二个指纹特征
	//	lpScore:		[out] 比对的相似度
	//	FastMode:		[in] 是否进行快速模式比对
	VF_RETURN	re1,re2;
	MATCHRESULT mr;
	FEATURE		feat1, feat2;

	// 第一个指纹特征的解码
	re1 = VF_FeatureDecode(lpFeature1, &feat1);
	if (re1 != VF_OK)
	{
		printf("图像1解码失败\n");
		return 0;
		//return re1;
	}

	// 第二个指纹特征的解码
	re2 = VF_FeatureDecode(lpFeature2, &feat2);
	if (re2 != VF_OK)
	{
		printf("图像2解码失败\n");
		return 0;
		//return re2;
	}

	*lpScore = 0;

	bool FastMode = true;

	if (FastMode)
	{
		// 快速模式的比对
		VF_VerifyMatch(&feat1, &feat2, &mr, VF_MATCHMODE_IDENTIFY);
	}
	else
	{
		// 精确模式的比对
		VF_VerifyMatch(&feat1, &feat2, &mr, VF_MATCHMODE_VERIFY);
	}

	// 匹配的相似度
	//*lpScore = mr.Similarity/10;
	*lpScore = mr.Similarity;
	/*if (mr.MMCount < 8)
	{
		*lpScore = 0;
	}
	else
	{
		*lpScore = mr.Similarity;
	}*/

	return 0;
}

 

二、怎么调用该源码算法库

在此不进行过多重复叙述,请移步我的另外一篇博文:https://blog.csdn.net/yanxiaolx/article/details/78730291

三、测试该算法识别率的测试demo

测试指纹算法的效果好坏,有3个指标:拒真率,认假率和识别率

测试的指纹库github已经上传:点击这里

正样本:所有指纹全部来自同一手指

负样本:所有指纹均来自不同手指

拒真率:正样本测试不通过的比率

认假率:负样本测试通过的比率

识别率:1 -(拒真率 + 认假率) / 2

第一个函数,对两个指纹图片的识别进行测试:

void test3()
{
	char ImagePathName1[100] = "D:\\c++code\\test\\1 (1).BMP";
	char ImagePathName2[100] = "D:\\c++code\\test\\1 (1).BMP";

	BYTE lpFeature1[500] = { 0 };
	BYTE lpFeature2[500] = { 0 };

	int lpSize1 = 0, lpSize2 = 0, score = 0;
	int iReturn = 0;
	
	sprintf(ImagePathName1, "D:\\c++code\\test\\1 (13).BMP");
	sprintf(ImagePathName2, "D:\\c++code\\test\\1 (14).BMP");
			iReturn = AnalyzeFromFile(ImagePathName1, lpFeature1, &lpSize1);
			if (iReturn != 0)
			{
				printf("从BMP文件中读取图像1失败\n");
			}

			iReturn = AnalyzeFromFile(ImagePathName2, lpFeature2, &lpSize2);
	    	if (iReturn != 0)
			{
				printf("从BMP文件中读取图像2失败\n");
			}

			PatternMatch(lpFeature1, lpFeature2, &score);//对指纹进行比对

			if (score >35)//原来是60
			{
				printf("Same Fingerprint!   \n");
			}
			else
			{
				printf("Different Fingerprint!  \n");
			}
	
	return;

}

测试认假率:

int count1 = 0, Arr_score1[11476] = { 0 };

void test1(double *Arr1)//测试认假率
{
	char ImagePathName1[100] = "E:\\c++code\\指纹测试资料\\SyntFingerDLL\\测试分类指纹库图片\\0.正常\\1 (1).BMP";
	char ImagePathName2[100] = "E:\\c++code\\指纹测试资料\\SyntFingerDLL\\测试分类指纹库图片\\0.正常\\1 (1).BMP";

	BYTE lpFeature1[500] = { 0 };
	BYTE lpFeature2[500] = { 0 };

	int lpSize1=0, lpSize2=0, score=0;
	int iReturn = 0;

	//DWORD start_time = GetTickCount();
	for (int i = 1; i <152; i++)//注意修改循环后面的值
	{
		sprintf(ImagePathName1, "E:\\c++code\\指纹测试资料\\SyntFingerDLL\\测试分类指纹库图片\\0.正常\\1 (%d).BMP", i);
		for (int j = i+1; j <=152; j++)//尽量保证假样本多,(n-1)*n/2
		{
			sprintf(ImagePathName2, "E:\\c++code\\指纹测试资料\\SyntFingerDLL\\测试分类指纹库图片\\0.正常\\1 (%d).BMP", j);
			iReturn = AnalyzeFromFile(ImagePathName1, lpFeature1, &lpSize1);
			if (iReturn != 0)
			{
				printf("从BMP文件中读取图像%d失败\n", i);
				break;
			}

			iReturn = AnalyzeFromFile(ImagePathName2, lpFeature2, &lpSize2);
			if (iReturn != 0)
			{
				printf("从BMP文件中读取图像%d失败\n", j);
				continue;
			}

			PatternMatch(lpFeature1, lpFeature2, &score);//对指纹进行比对

				Arr_score1[count1] = score;
				count1++;	
				cout << count1 <<",i=" << i << ",j=" << j << endl;
		}
		
	}
	//DWORD end_time = GetTickCount();
	
	//cout << "The run time is:" << (end_time - start_time)/23436 << "ms!" << endl;

		FILE *f; 
		f = fopen("D:\\c++code\\指纹测试资料\\认假test1\\score.txt", "w"); 
		if (f == NULL)
		{
			printf("ERROR!");
			return;
		}
		
		for (int i = 1; i <= 1000; i++)
		{
			int Y_count = 0, N_count = 0;

			for (int j = 0; j < count1; j++)
			{
				if (Arr_score1[j]>=i-1)
				{
					Y_count++;
				}
				else
				{
					N_count++;
				}
			}

			fprintf(f, "序号=%d,Y_count=%d,N_count=%d,sum=%d,认假率=%lf\n", i, Y_count, N_count, Y_count + N_count, Y_count*1.0 / (Y_count + N_count));
			Arr1[i - 1] = Y_count*1.0 / (Y_count + N_count);
		}

		for (int j = 0; j < count1; j++)
		{
			fprintf(f, "序号=%d,score=%d\n", j + 1, Arr_score1[j]);
		}

		fclose(f);

		return ;
}

测试拒真率:

int count2 = 0;
int Arr_score2[12000] = { 0 };
void test2(double *Arr2)//测试拒真率
{
	char ImagePathName1[100] = "D:\\c++code\\指纹测试资料\\指纹采集2014.7.3-bmp\\1 (1)\\1 (1).BMP";
	char ImagePathName2[100] = "D:\\c++code\\指纹测试资料\\指纹采集2014.7.3-bmp\\1 (1)\\1 (1).BMP";

	BYTE lpFeature1[500] = { 0 };
	BYTE lpFeature2[500] = { 0 };

	int lpSize1 = 0, lpSize2 = 0, score = 0;
	int iReturn = 0;
	int N=10;//修改文件夹方便
	
	//DWORD start_time = GetTickCount();
	for (int k =1; k <= 232; k++)
	{
		for (int i = 1; i <= N; i++)//注意修改循环后面的值
		{
			sprintf(ImagePathName1, "D:\\c++code\\指纹测试资料\\指纹采集2014.7.3-bmp\\1 (%d)\\1 (%d).BMP", k, i);
			for (int j = i; j <= N; j++)//不考虑比对过的重复,尽量保证真样本多,n*(n+1)/2
			{
				//count++;
				sprintf(ImagePathName2, "D:\\c++code\\指纹测试资料\\指纹采集2014.7.3-bmp\\1 (%d)\\1 (%d).BMP", k, j);
				iReturn = AnalyzeFromFile(ImagePathName1, lpFeature1, &lpSize1);
				if (iReturn != 0)
				{
					printf("从BMP文件中读取图像%d失败\n", i);
					break;
				}

				iReturn = AnalyzeFromFile(ImagePathName2, lpFeature2, &lpSize2);
				if (iReturn != 0)
				{
					printf("从BMP文件中读取图像%d失败\n", j);
					continue;
				}

				PatternMatch(lpFeature1, lpFeature2, &score);//对指纹进行比对

				Arr_score2[count2] = score;
				count2++;
				cout << count2 << ",k=" << k << ",i="<<i<<",j=" << j << endl;
			}
		}
	}

	//DWORD end_time = GetTickCount();

	FILE *f; 
	f = fopen("D:\\c++code\\指纹测试资料\\拒真test2\\score.txt", "w"); 

	if (f == NULL) 
	{ 
		printf("ERROR!"); 
		return ; 
	} 
	
	for (int i = 1; i <= 1000; i++)
	{
		int Y_count = 0, N_count = 0;

		for (int j = 0; j < count2; j++)
		{
			if (Arr_score2[j]>=i-1)
			{
				Y_count++;
			}
			else
			{
				N_count++;
			}
		}
		fprintf(f, "score=%d,Y_count=%d,N_count=%d,sum=%d,拒真率=%lf\n", i, Y_count, N_count, Y_count + N_count, N_count*1.0 / (Y_count + N_count));
		Arr2[i - 1] = N_count*1.0 / (Y_count + N_count);
	}

	for (int j = 0; j < count2; j++)
	{
		fprintf(f, "序号=%d,score=%d\n", j + 1, Arr_score2[j]);
	}

	fclose(f);
	return ;
}

最后输出各种识别率,存在记事本中:

int main()
{
	double Arr1[1000] = { 0 }, Arr2[1000] = { 0 }, Arr3[1000] = { 0 };
	test2(Arr2);//测试拒真率
	test1(Arr1);//测试认假率

	for (int i = 0; i < 1000; i++)
	{
		Arr3[i] = 1 - (Arr1[i] + Arr2[i]) / 2;
	}

	FILE *f;
	f = fopen("D:\\c++code\\指纹测试资料\\识别率4.txt", "w");
	if (f == NULL)
	{
		printf("ERROR!");
		return 0;
	}

	for (int i = 0; i <1000; i++)
	{
		fprintf(f, "score=%d,认假率=%lf,拒真率=%lf,识别率=%lf\n", i , Arr1[i],Arr2[i],Arr3[i]);
		printf("score=%d,认假率=%lf,拒真率=%lf,识别率=%lf\n", i , Arr1[i], Arr2[i], Arr3[i]);
	}
	fclose(f);

	//test3();
	system("pause");
	return 0;
}

本人一共测试了正副样本大概各10万对左右,在不同的阈值下,指纹的识别率分布大概呈现正态分布,其中score表示阈值,如下图数据记录:

由上图可以看出,当score=19时,识别率=0.965707达到最优峰值。

下面举例聊聊指纹算法在银行的业务应用流程:

  1. 指纹采集

(1)柜员到支行以上的部门进行指纹集中采集;

(2)采集时需要同时运行并打开平台、客户端、设备,同时完成联接;

(3)采集时至少采集柜员的三枚手指,优先采集左手手指,同时优先采集食指、中指、大拇指;

(4)采集指纹功能由客户端、设备完成。指纹在设备上获取后,由客户端完成模板的处理,再由客户端上传平台;

(5)平台将客户端上传的柜员号、指纹图像、指纹特征值模板、指头标记进行处理,完成平台用户、柜员、指纹的绑定。

     2.指纹比对

(一)柜员签到流程

(1)柜员签到过程中的指纹验证是在系统平台上完成;

(2)首先从终端柜面输入柜员号,然后柜员将注册过的手指在设备上按压来实时采集指纹;

(3)设备对实时采集的指纹图像进行处理并生成指纹特征值,同时上传到平台;

(4)平台将指纹特征值与已采集的指纹模板进行比对,判断合法性;

(5)比对不成功,则返回错误值。比对成功,则平台将柜员关联的用户密码返回给终端;终端柜面根据此密码登录前端系统。

(二)业务授权流程

(1)柜员授权过程中的指纹验证是在系统平台上完成;

(2)在等待输入授权柜员号时,具有授权权限的柜员将注册过的手指按压到设备进行采集指纹;

(3)设备对实时采集的指纹图像进行处理并生成指纹特征值,同时上传到平台;

(4)平台将指纹特征值与已采集的指纹模板进行比对,判断合法性;

(5)比对不成功,则返回错误值。比对成功,则平台将柜员关联的用户密码返回给终端,终端柜面根据此密码完成授权过程。

该项目是传统指纹识别算法,当然识别率不是最优的,至于更优的指纹识别算法版本出于商业机密,暂时不能开源,哈哈,好气是不是,不要打我。

未完待续,空了再继续完善博文

  • 14
    点赞
  • 120
    收藏
    觉得还不错? 一键收藏
  • 14
    评论
### 回答1: Matlab指纹识别系统源码主要有以下几个关键步骤: 1. 预处理:在该步骤中,使用Matlab对原始指纹图像进行一系列的预处理操作,如去噪、增强图像对比度等。可以使用方法如中值滤波、高斯滤波和直方图均衡化来实现。 2. 特征提取:在该步骤中,使用一些特征提取算法从预处理过的指纹图像中提取出关键的特征信息。常用的方法有方向梯度直方图(Directional Gradient Histogram,DGH)和小波变换(Wavelet Transform)等。这些特征可以代表指纹在局部和全局上的几何和纹理特性。 3. 特征匹配:在该步骤中,将提取到的特征信息与数据中的已知指纹进行比较,找到最佳匹配。常用的方法有基于相似性度量的匹配算法,如欧几里得距离、余弦相似度等。可以使用数据索引技术来快速检索匹配指纹。 4. 性能评估:在该步骤中,对指纹识别系统的性能进行评估。常用的评估指标包括识别率、误识率、查准率和查全率等。可以使用交叉验证等技术来评估系统的鲁棒性和准确性。 综上所述,Matlab指纹识别系统源码主要包括图像预处理、特征提取、特征匹配和性能评估等关键步骤。具体的实现会涉及到各种图像处理和模式识别算法,如滤波、特征选择、相似性度量等。通过这些源码,可以实现一个基于Matlab的指纹识别系统,实现指纹图像的自动识别和比对。 ### 回答2: 基于MATLAB的指纹识别系统源码主要包括以下几个模块:图像预处理、特征提取、特征匹配和识别。 图像预处理模块主要用于对原始指纹图像进行一系列的预处理操作,以提高后续特征提取和匹配的准确性和效果。预处理过程包括图像增强、图像去噪和图像增强。 特征提取模块是指从预处理后的指纹图像中提取出用于表示指纹特征的关键信息。常用的特征提取方法有针对指纹纹线和纹谷的方向图像、频域处理等。这些特征用于构建指纹特征向量,以实现指纹的唯一性和可区分性。 特征匹配模块将待识别的指纹特征与数据中存储的已知指纹特征进行比对。匹配算法的主要目标是寻找相似度最高的指纹特征,并判断两个指纹是否属于同一个人。 识别模块是整个系统的核心部分,它通过将待识别的指纹特征与数据中存储的指纹特征进行匹配,判断该指纹是否是已知指纹中的某一个,并输出相应的识别结果。 基于MATLAB的指纹识别系统源码需要综合运用图像处理、特征提取和匹配算法等知识,实现对指纹图像的全面分析和处理,并最终完成指纹的识别任务。这些源码可以通过MATLAB工具的函数调用、算法实现等方式来实现,以期达到高准确性和高性能的指纹识别效果。 ### 回答3: 基于MATLAB的指纹识别系统源码是一个用于识别和验证人类指纹的计算机程序。该源码使用MATLAB编程语言,结合指纹图像处理和模式识别算法,实现指纹的自动识别和比对。 源码的主要功能包括以下几个方面: 1. 图像预处理:源码首先通过读取指纹图像文件,将其转为灰度图像,并进行图像增强处理,以提高指纹的清晰度和对比度。 2. 特征提取:源码通过一系列特征提取算法,从指纹图像中提取出有代表性的特征,例如小岭值、方向和纹线等,并进行编码。 3. 特征匹配:源码通过比对提取出的特征,使用匹配算法来判断两个指纹是否匹配。常用的匹配算法包括最邻近匹配、哈希匹配等。 4. 数据管理:源码可以根据不同的识别需求,包括指纹的录入、存储和管理,以及指纹的更新、删除和查询。 5. 用户界面:源码还包含了较为友好的用户界面,用于指纹的录入、匹配和结果展示等操作,使得系统更易于使用。 通过合理利用这些功能,基于MATLAB的指纹识别系统能够实现高效准确的指纹识别和比对,广泛应用于身份验证、安全门禁和犯罪侦查等领域。用户可以根据需要对源码进行修改和优化,以满足特定的应用需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值