指纹算法需求

指纹特征值生成、比对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 hereVF_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)比对不成功,则返回错误值。比对成功,则平台将柜员关联的用户密码返回给终端,终端柜面根据此密码完成授权过程。

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

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

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

  1. Learning to Rank中Pointwise关于PRank算法源码实现

    [学习排序] Learning to Rank中Pointwise关于PRank算法源码实现 标签: 学习排序PRankPointwiseLearning to Rank代码实现 2015-01-28 ...

  2. 数据分析挖掘实验报告及算法源码

    数据分析挖掘实验报告及算法源码 四个实验21面,帮助你学习参考使用,帮助你取得更好成绩 报告地址:数据分析挖掘实验报告及其算法源码 1.Apriori关联规则算法 必修 实验类型 设计 Python3 ...

  3. 深度增强学习DDPG(Deep Deterministic Policy Gradient)算法源码走读

    原文链接:https://blog.csdn.net/jinzhuojun/article/details/82556127 本文是基于OpenAI推出deep reinforcement learn ...

  4. 海外某音x-gorgon算法原理分析及算法源码公布

    算法源码见附件 分享一个去年逆的一个海外版某音 1474版本 x-gorgon算法,这里简单介绍一下算法原理,首先malloc出来一个0x1A大小的空间,然后截取用户传入的byte数组中的参数,截取开 ...

  5. 基于新唐M0的XXTEA加密解密算法源码

    源:基于新唐M0的XXTEA加密解密算法源码 /*--------------------------------------------------------------------------- ...

  6. [转] GIS算法源码集合

    其他GIS相关代码下载索引 http://www.mygis.com.cn/codeindex10.htm 1.深度优先实现的路径分析源码 http://www.mygis.com.cn/codes/ ...

  7. 机器学习算法源码全解析(三)-范数规则化之核范数与规则项参数选择

    前言 参见上一篇博文,我们聊到了L0,L1和L2范数,这篇我们絮叨絮叨下核范数和规则项参数选择.知识有限,以下都是我一些浅显的看法,如果理解存在错误,希望大家不吝指正.谢谢. 机器学习算法源码全解析( ...

  8. 超像素SLIC算法源码阅读

    超像素SLIC算法源码阅读 超像素SLIC算法源码阅读 SLIC简介 源码阅读 实验结果 其他超像素算法对比 超像素SLIC算法源码阅读 SLIC简介 SLIC的全称Simple Linear Ite ...

  9. 跑腿同学校园小程序源码-已测试

    介绍: 跑腿同学校园小程序源码-已测试 1:推荐环境:coenots7+wdcp3.2 coenots7+宝塔 win2008+phpstudty2017 php版本gt;= 5.4推荐5.6 2:把 ...

  10. Java自动计算迷宫正确路线算法源码

    简介: Java自动计算迷宫正确路线算法源码,首先迷宫需要满足存在开始标识和结束标识与墙标识,然后设置好行数与列数就可以开始计算正确路线了,采用的是为二维数组然后走遍所有路线的方式. 网盘下载地址: ...

最新文章

  1. 分布式唯一id:snowflake算法思考
  2. MAX2323E - 原理图系列
  3. JPA时间注解(转)
  4. java制作安卓客户端,java做服务器,android干客户端,实现数据传输
  5. 重磅发布!36氪2020年度中国最具登陆科创板潜力企业TOP50榜单揭晓
  6. /usr/include/sys/types.h基本系统数据类型
  7. 开源许可协议,开源许可证GPL、BSD、MIT、Mozilla、Apache和LGPL的区别
  8. 用于安全连接 Microsoft 365 的 Mimecast 数字证书被盗
  9. DELMIA软件物流仿真:使用输送带输送物料的仿真操作方法
  10. 教孩子学编程 python 下载_教孩子学编程 python语言版
  11. JavaScript----事件
  12. TensorFlow镜像安装(Anaconda)
  13. Oracle 对表空间无操作权限
  14. java 获取明天12点日期
  15. 数字孪生|成熟度评价
  16. 郑州大学计算机考研944,2020年郑州大学944计算机技术专业基础综合考研复习资料...
  17. iPhone 邮件html设置,iphone手机邮件设置教程
  18. java公路车为什么会被喷,最全指南
  19. cmd命令下修复硬盘/U盘
  20. 电影《风雨哈佛路》经典台词

热门文章

  1. hadoop安装流程
  2. cc2530设计性实验代码五
  3. 扫码连wifi小程序源码
  4. kali wifi密码 破解
  5. mysql 递归查询子类_MySQL递归查询当前节点及子节点
  6. 电脑是否入侵,是否留有后门
  7. 清华数据结构c语言版严蔚敏pdf,清华数据结构习题集答案(C语言版严蔚敏).pdf
  8. 严数据结构c语言及答案,严蔚敏《数据结构(c语言版)习题集》全答案
  9. 怎样才能查到4S店保养记录,4S店维修保养记录怎样查询,Javascript学习指南
  10. linux两台电脑直连传数据,两台MAC电脑通过局域网快速传输文件