指纹识别算法c++实现

算法 专栏收录该内容
2 篇文章 0 订阅

指纹算法需求

指纹特征值生成、比对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链接

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

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


   
  1. int __stdcall Analyze(BYTE *lpImage, int Width, int Height, BYTE *lpFeature, int *lpSize)
  2. {
  3. ///
  4. // Width: [in] 指纹图像宽度
  5. // Height: [in] 指纹图像高度
  6. // lpImage: [in] 指纹图像数据指针
  7. // Resolution: [in] 指纹图像分辨率,默认500
  8. // lpFeature: [out] 提取的指纹特征数据指针
  9. // lpSize: [out] 指纹特征数据大小
  10. // TODO: Add your implementation code here
  11. VF_RETURN re;
  12. // 导入指纹图像数据
  13. VF_ImportFinger(lpImage, Width, Height);
  14. // 处理指纹图像,提取指纹特征
  15. re = VF_Process();
  16. if (re != VF_OK)
  17. return re;
  18. // 对指纹特征进行编码
  19. re = VF_FeatureEncode(&g_Feature, lpFeature, lpSize);
  20. if (re != VF_OK)
  21. return re;
  22. return 0;
  23. }

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


   
  1. int __stdcall PatternMatch(BYTE *lpFeature1, BYTE *lpFeature2, int *lpScore)
  2. {
  3. // lpFeature1: [in] 第一个指纹特征
  4. // lpFeature2: [in] 第二个指纹特征
  5. // lpScore: [out] 比对的相似度
  6. // FastMode: [in] 是否进行快速模式比对
  7. VF_RETURN re1,re2;
  8. MATCHRESULT mr;
  9. FEATURE feat1, feat2;
  10. // 第一个指纹特征的解码
  11. re1 = VF_FeatureDecode(lpFeature1, &feat1);
  12. if (re1 != VF_OK)
  13. {
  14. printf( "图像1解码失败\n");
  15. return 0;
  16. //return re1;
  17. }
  18. // 第二个指纹特征的解码
  19. re2 = VF_FeatureDecode(lpFeature2, &feat2);
  20. if (re2 != VF_OK)
  21. {
  22. printf( "图像2解码失败\n");
  23. return 0;
  24. //return re2;
  25. }
  26. *lpScore = 0;
  27. bool FastMode = true;
  28. if (FastMode)
  29. {
  30. // 快速模式的比对
  31. VF_VerifyMatch(&feat1, &feat2, &mr, VF_MATCHMODE_IDENTIFY);
  32. }
  33. else
  34. {
  35. // 精确模式的比对
  36. VF_VerifyMatch(&feat1, &feat2, &mr, VF_MATCHMODE_VERIFY);
  37. }
  38. // 匹配的相似度
  39. //*lpScore = mr.Similarity/10;
  40. *lpScore = mr.Similarity;
  41. /*if (mr.MMCount < 8)
  42. {
  43. *lpScore = 0;
  44. }
  45. else
  46. {
  47. *lpScore = mr.Similarity;
  48. }*/
  49. return 0;
  50. }

 

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

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

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

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

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

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

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

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

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

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

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


   
  1. void test3()
  2. {
  3. char ImagePathName1[ 100] = "D:\\c++code\\test\\1 (1).BMP";
  4. char ImagePathName2[ 100] = "D:\\c++code\\test\\1 (1).BMP";
  5. BYTE lpFeature1[ 500] = { 0 };
  6. BYTE lpFeature2[ 500] = { 0 };
  7. int lpSize1 = 0, lpSize2 = 0, score = 0;
  8. int iReturn = 0;
  9. sprintf(ImagePathName1, "D:\\c++code\\test\\1 (13).BMP");
  10. sprintf(ImagePathName2, "D:\\c++code\\test\\1 (14).BMP");
  11. iReturn = AnalyzeFromFile(ImagePathName1, lpFeature1, &lpSize1);
  12. if (iReturn != 0)
  13. {
  14. printf( "从BMP文件中读取图像1失败\n");
  15. }
  16. iReturn = AnalyzeFromFile(ImagePathName2, lpFeature2, &lpSize2);
  17. if (iReturn != 0)
  18. {
  19. printf( "从BMP文件中读取图像2失败\n");
  20. }
  21. PatternMatch(lpFeature1, lpFeature2, &score); //对指纹进行比对
  22. if (score > 35) //原来是60
  23. {
  24. printf( "Same Fingerprint! \n");
  25. }
  26. else
  27. {
  28. printf( "Different Fingerprint! \n");
  29. }
  30. return;
  31. }

测试认假率:


   
  1. int count1 = 0, Arr_score1[ 11476] = { 0 };
  2. void test1(double *Arr1)//测试认假率
  3. {
  4. char ImagePathName1[ 100] = "E:\\c++code\\指纹测试资料\\SyntFingerDLL\\测试分类指纹库图片\\0.正常\\1 (1).BMP";
  5. char ImagePathName2[ 100] = "E:\\c++code\\指纹测试资料\\SyntFingerDLL\\测试分类指纹库图片\\0.正常\\1 (1).BMP";
  6. BYTE lpFeature1[ 500] = { 0 };
  7. BYTE lpFeature2[ 500] = { 0 };
  8. int lpSize1= 0, lpSize2= 0, score= 0;
  9. int iReturn = 0;
  10. //DWORD start_time = GetTickCount();
  11. for ( int i = 1; i < 152; i++) //注意修改循环后面的值
  12. {
  13. sprintf(ImagePathName1, "E:\\c++code\\指纹测试资料\\SyntFingerDLL\\测试分类指纹库图片\\0.正常\\1 (%d).BMP", i);
  14. for ( int j = i+ 1; j <= 152; j++) //尽量保证假样本多,(n-1)*n/2
  15. {
  16. sprintf(ImagePathName2, "E:\\c++code\\指纹测试资料\\SyntFingerDLL\\测试分类指纹库图片\\0.正常\\1 (%d).BMP", j);
  17. iReturn = AnalyzeFromFile(ImagePathName1, lpFeature1, &lpSize1);
  18. if (iReturn != 0)
  19. {
  20. printf( "从BMP文件中读取图像%d失败\n", i);
  21. break;
  22. }
  23. iReturn = AnalyzeFromFile(ImagePathName2, lpFeature2, &lpSize2);
  24. if (iReturn != 0)
  25. {
  26. printf( "从BMP文件中读取图像%d失败\n", j);
  27. continue;
  28. }
  29. PatternMatch(lpFeature1, lpFeature2, &score); //对指纹进行比对
  30. Arr_score1[count1] = score;
  31. count1++;
  32. cout << count1 << ",i=" << i << ",j=" << j << endl;
  33. }
  34. }
  35. //DWORD end_time = GetTickCount();
  36. //cout << "The run time is:" << (end_time - start_time)/23436 << "ms!" << endl;
  37. FILE *f;
  38. f = fopen( "D:\\c++code\\指纹测试资料\\认假test1\\score.txt", "w");
  39. if (f == NULL)
  40. {
  41. printf( "ERROR!");
  42. return;
  43. }
  44. for ( int i = 1; i <= 1000; i++)
  45. {
  46. int Y_count = 0, N_count = 0;
  47. for ( int j = 0; j < count1; j++)
  48. {
  49. if (Arr_score1[j]>=i -1)
  50. {
  51. Y_count++;
  52. }
  53. else
  54. {
  55. N_count++;
  56. }
  57. }
  58. 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));
  59. Arr1[i - 1] = Y_count* 1.0 / (Y_count + N_count);
  60. }
  61. for ( int j = 0; j < count1; j++)
  62. {
  63. fprintf(f, "序号=%d,score=%d\n", j + 1, Arr_score1[j]);
  64. }
  65. fclose(f);
  66. return ;
  67. }

测试拒真率:


   
  1. int count2 = 0;
  2. int Arr_score2[ 12000] = { 0 };
  3. void test2(double *Arr2)//测试拒真率
  4. {
  5. char ImagePathName1[ 100] = "D:\\c++code\\指纹测试资料\\指纹采集2014.7.3-bmp\\1 (1)\\1 (1).BMP";
  6. char ImagePathName2[ 100] = "D:\\c++code\\指纹测试资料\\指纹采集2014.7.3-bmp\\1 (1)\\1 (1).BMP";
  7. BYTE lpFeature1[ 500] = { 0 };
  8. BYTE lpFeature2[ 500] = { 0 };
  9. int lpSize1 = 0, lpSize2 = 0, score = 0;
  10. int iReturn = 0;
  11. int N= 10; //修改文件夹方便
  12. //DWORD start_time = GetTickCount();
  13. for ( int k = 1; k <= 232; k++)
  14. {
  15. for ( int i = 1; i <= N; i++) //注意修改循环后面的值
  16. {
  17. sprintf(ImagePathName1, "D:\\c++code\\指纹测试资料\\指纹采集2014.7.3-bmp\\1 (%d)\\1 (%d).BMP", k, i);
  18. for ( int j = i; j <= N; j++) //不考虑比对过的重复,尽量保证真样本多,n*(n+1)/2
  19. {
  20. //count++;
  21. sprintf(ImagePathName2, "D:\\c++code\\指纹测试资料\\指纹采集2014.7.3-bmp\\1 (%d)\\1 (%d).BMP", k, j);
  22. iReturn = AnalyzeFromFile(ImagePathName1, lpFeature1, &lpSize1);
  23. if (iReturn != 0)
  24. {
  25. printf( "从BMP文件中读取图像%d失败\n", i);
  26. break;
  27. }
  28. iReturn = AnalyzeFromFile(ImagePathName2, lpFeature2, &lpSize2);
  29. if (iReturn != 0)
  30. {
  31. printf( "从BMP文件中读取图像%d失败\n", j);
  32. continue;
  33. }
  34. PatternMatch(lpFeature1, lpFeature2, &score); //对指纹进行比对
  35. Arr_score2[count2] = score;
  36. count2++;
  37. cout << count2 << ",k=" << k << ",i="<<i<< ",j=" << j << endl;
  38. }
  39. }
  40. }
  41. //DWORD end_time = GetTickCount();
  42. FILE *f;
  43. f = fopen( "D:\\c++code\\指纹测试资料\\拒真test2\\score.txt", "w");
  44. if (f == NULL)
  45. {
  46. printf( "ERROR!");
  47. return ;
  48. }
  49. for ( int i = 1; i <= 1000; i++)
  50. {
  51. int Y_count = 0, N_count = 0;
  52. for ( int j = 0; j < count2; j++)
  53. {
  54. if (Arr_score2[j]>=i -1)
  55. {
  56. Y_count++;
  57. }
  58. else
  59. {
  60. N_count++;
  61. }
  62. }
  63. 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));
  64. Arr2[i - 1] = N_count* 1.0 / (Y_count + N_count);
  65. }
  66. for ( int j = 0; j < count2; j++)
  67. {
  68. fprintf(f, "序号=%d,score=%d\n", j + 1, Arr_score2[j]);
  69. }
  70. fclose(f);
  71. return ;
  72. }

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


   
  1. int main()
  2. {
  3. double Arr1[ 1000] = { 0 }, Arr2[ 1000] = { 0 }, Arr3[ 1000] = { 0 };
  4. test2(Arr2); //测试拒真率
  5. test1(Arr1); //测试认假率
  6. for ( int i = 0; i < 1000; i++)
  7. {
  8. Arr3[i] = 1 - (Arr1[i] + Arr2[i]) / 2;
  9. }
  10. FILE *f;
  11. f = fopen( "D:\\c++code\\指纹测试资料\\识别率4.txt", "w");
  12. if (f == NULL)
  13. {
  14. printf( "ERROR!");
  15. return 0;
  16. }
  17. for ( int i = 0; i < 1000; i++)
  18. {
  19. fprintf(f, "score=%d,认假率=%lf,拒真率=%lf,识别率=%lf\n", i , Arr1[i],Arr2[i],Arr3[i]);
  20. printf( "score=%d,认假率=%lf,拒真率=%lf,识别率=%lf\n", i , Arr1[i], Arr2[i], Arr3[i]);
  21. }
  22. fclose(f);
  23. //test3();
  24. system( "pause");
  25. return 0;
  26. }

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

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

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

  1. 指纹采集

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

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

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

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

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

     2.指纹比对

(一)柜员签到流程

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

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

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

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

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

(二)业务授权流程

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

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

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

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

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

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

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

花了10块钱买的,希望对大家有帮助。/*############################################################################# * 文件名:file.c * 功能: 实现指纹相关文件的操作 * modified by PRTsinghua@hotmail.com #############################################################################*/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "file.h" /* 对象的这些接口实现是私有的,不必为用户所知 */ typedef struct iFvsFile_t { FILE *pf; /* 文件指针 */ } iFvsFile_t; /****************************************************************************** * 功能:创建一个新的文件对象,只有在创建之后,文件对象才能为其它函数所用。 * 参数:无 * 返回:若创建失败,返回NULL;否则返回新的对象句柄。 ******************************************************************************/ FvsFile_t FileCreate() { iFvsFile_t* p = NULL; p = (iFvsFile_t*)malloc(sizeof(iFvsFile_t)); if (p!=NULL) p->pf = NULL; return (FvsFile_t)p; } /****************************************************************************** * 功能:破坏一个已经存在的文件对象,在毁坏之后,文件对象不能再为其它函数所用。 * 参数:file 即将删除的文件对象指针 * 返回:无返回值 ******************************************************************************/ void FileDestroy(FvsFile_t file) { iFvsFile_t* p = NULL; if (file==NULL) return; /* 关闭文件,如果它还打开着 */ (void)FileClose(file); p = file; free(p); } /****************************************************************************** * 功能:打开一个新的文件。一个文件可以读打开,写打开,或者被创建。 * 参数:file 文件对象 * name 待打开文件的名字 * flags 打开标志 * 返回:错误编号 ******************************************************************************/ FvsError_t FileOpen(FvsFile_t file, const FvsString_t name, const FvsFileOptions_t flags) { iFvsFile_t* p = (iFvsFile_t*)file; char strFlags[10]; int nflags = (int)flags; /* 关闭文件,如果已经打开 */ (void)FileClose(p); strcpy(strFlags, ""); if ( (nflags & FvsFileRead)!=0 && (nflags & FvsFileWrite)!=0 ) strcat(strFlags, "rw"); else { if ((nflags & FvsFileRead)!=0) strcat(strFlags, "r"); if ((nflags & FvsFileWrite)!=0) strcat(strFlags, "w"); } strcat(strFlags, "b"); if ((nflags & FvsFileCreate)!=0) strcat(strFlags, "+"); p->pf = fopen(name, strFlags); if (FileIsOpen(file)==FvsTrue) return FvsOK; return FvsFailure; } /****************************************************************************** * 功能:关闭一个文件对象,文件关闭之后,文件不再可用。 * 参数:file 文件对象 * 返回:错误编号 ******************************************************************************/ FvsError_t FileClose(FvsFile_t file) { iFvsFile_t* p = (iFvsFile_t*)file; int nerr = -1; if (p->pf!=NULL) { nerr = fclose(p->pf); p->pf = NULL; } if (nerr==0) return FvsOK; return FvsFailure; } /****************************************************************************** * 功能:测试一个文件是否打开 * 参数:file 文件对象 * 返回:文件打开,则返回true;否则返回false ******************************************************************************/ FvsBool_t FileIsOpen(const FvsFile_t file) { iFvsFile_t* p = (iFvsFile_t*)file; return (p->pf!=NULL)?FvsTrue:FvsFalse; } /****************************************************************************** * 功能:测试是否到了文件结尾 * 参数:file 文件对象 * 返回:到了结尾,返回true;否则返回false ******************************************************************************/ FvsBool_t FileIsAtEOF(const FvsFile_t file) { iFvsFile_t* p = (iFvsFile_t*)file; if (FileIsOpen(p)==FvsFalse) return FvsFalse; return (feof(p->pf)!=0)?FvsTrue:FvsFalse; } /****************************************************************************** * 功能:提交对文件所作的更改 * 参数:file 文件对象 * 返回:错误编号 ******************************************************************************/ FvsError_t FileCommit(FvsFile_t file) { iFvsFile_t* p = (iFvsFile_t*)file; return (fflush(p->pf)==0)?FvsOK:FvsFailure; } /****************************************************************************** * 功能:跳到文件的开头 * 参数:file 文件对象 * 返回:错误编号 ******************************************************************************/ FvsError_t FileSeekToBegin(FvsFile_t file) { iFvsFile_t* p = (iFvsFile_t*)file; if (FileIsOpen(p)==FvsTrue) { if (fseek(p->pf, 0, SEEK_SET)!=0) return FvsFailure; return FvsOK; } return FvsFailure; } /****************************************************************************** * 功能:跳到文件的结尾 * 参数:file 文件对象 * 返回:错误编号 ******************************************************************************/ FvsError_t FileSeekToEnd(FvsFile_t file) { iFvsFile_t* p = (iFvsFile_t*)file; if (FileIsOpen(p)==FvsTrue) { if (fseek(p->pf, 0, SEEK_END)!=0) return FvsFailure; return FvsOK; } return FvsFailure; } /****************************************************************************** * 功能:得到当前的文件指针位置 * 参数:file 文件对象 * 返回:当前的指针位置 ******************************************************************************/ FvsUint_t FileGetPosition(FvsFile_t file) { iFvsFile_t* p = (iFvsFile_t*)file; if (FileIsOpen(p)==FvsTrue) return (FvsUint_t)ftell(p->pf); return 0; } /****************************************************************************** * 功能:跳到文件的指定位置 * 参数:file 文件对象 * position 指定的文件位置 * 返回:错误编号 ******************************************************************************/ FvsError_t FileSeek(FvsFile_t file, const FvsUint_t position) { iFvsFile_t* p = (iFvsFile_t*)file; if (FileIsOpen(p)==FvsTrue) { if (fseek(p->pf, (long int)position, SEEK_SET)!=0) return FvsFailure; return FvsOK; } return FvsFailure; } /****************************************************************************** * 功能:从文件中读数据,所读取的字节数由length决定。读取的数据保存于指针data。 * 参数:file 文件对象 * data 指向存储数据的数组 * length 要读取的字节数 * 返回:实际读取的字节数 ******************************************************************************/ FvsUint_t FileRead(FvsFile_t file, FvsPointer_t data, const FvsUint_t length) { iFvsFile_t* p = (iFvsFile_t*)file; return (FvsUint_t)fread(data, (size_t)1, (size_t)length, p->pf); } /****************************************************************************** * 功能:往文件中写数据,所写的字节数由length决定。要写入的数据保存于指针data。 * 参数:file 文件对象 * data 指向存储数据的数组 * length 要写入的字节数 * 返回:实际写入的字节数 ******************************************************************************/ FvsUint_t FileWrite(FvsFile_t file, const FvsPointer_t data, const FvsUint_t length) { iFvsFile_t* p = (iFvsFile_t*)file; return (FvsUint_t)fwrite(data, (size_t)1, (size_t)length, p->pf); } /****************************************************************************** * 功能:从文件中得到一个字节 * 参数:file 文件对象 * 返回:读取的字节 ******************************************************************************/ FvsByte_t FileGetByte(FvsFile_t file) { iFvsFile_t* p = (iFvsFile_t*)file; return (FvsByte_t)fgetc(p->pf); } /****************************************************************************** * 功能:从文件中读取一个字 * 参数:file 文件对象 * 返回:读取的字 ******************************************************************************/ FvsWord_t FileGetWord(FvsFile_t file) { iFvsFile_t* p = (iFvsFile_t*)file; FvsWord_t w = (FvsWord_t)fgetc(p->pf); return (w<<8)+fgetc(p->pf); }
本资源是以压缩包形式的,里面是一个pdf格式电子书(完整版)。有需要的朋友可以下载。 本书作者: 李昊 傅曦(编著); 本书出版社:人民邮电出版社 内容简介: 《精通VisualC++指纹模式识别系统算法及现实》共5篇。第一篇讲解指纹模式识别系统入门知识,包括指纹模式识别系统演示系统和指纹学基础,引导读者快速入门;第二篇讲解指纹模式识别系统算法,包括指纹模式识别预处理和指纹图像特征提取与比对的源代码实现;第三篇讲解如何亲手打造指纹模式识别系统,带领读者制作一个指纹模式识别系统的软硬件系统;第四篇讲解指纹模式识别应用技术基础,包括指纹模式识别技术各类应用的系统构造和源代码实现;第五篇讲解指纹电子产品技术和指纹电子产品的发展创业,包括指纹电子证件系统、指纹识别电子产品以及数字指纹技术的创业规划。 《精通VisualC++指纹模式识别系统算法及现实》适合指纹模式识别技术的初学者、指纹识别电子产品工程师以及打算投身指纹模式识别领域的创业者阅读。 推荐理由: 免费公开了VisualC++指纹模式识别系统源代码 带领读者一步一步亲手制作一个指纹识别系统 深度剖析真实的行业应用案例 业界专家强力推荐 部分章节目录: 目录: 第一篇 指纹模式识别系统入门 第1章 指纹模式识别演示轻松入门 3 1.1 体验VisualC++指纹模式识别演示系统 3 1.1.1 VisualC++指纹模式识别演示系统的安装与使用 3 1.1.2 VisualBasic指纹模式识别演示系统的安装与使用 5 1.2 指纹模式识别系统的市场应用前景 8 1.3 指纹模式识别系统的学习方法 10 第2章 轻松接触传统指纹学和数字指纹学 11 2.1 指纹学的历史 11 2.2 传统指纹学 13 2.2.1 指纹卡片 14 2.2.2 指纹分析 16 2.2.3 传统人工指纹比对 16 2.3 数字指纹学概述 18 2.3.1 计算机视觉原理 19 2.3.2 数字指纹学与传统指纹学的关系 21 2.3.3 数字指纹学的方法 23 第3章 轻松自创指纹模式识别演示 26 3.1 动手创建一个VisualC++程序 26 3.1.1 初步了解VisualC++工具环境 26 3.1.2 用VisualC++向导创建程序工程 27 3.2 编程接入VisualC++指纹算法程序代码 30 3.2.1 改造自建VisualC++程序界面 30 3.2.2 编程接入C++指纹算法程序代码实例 34 3.3 使用开发环境自创指纹模式识别演示系统 38 3.3.1 VisualC++指纹模式识别开发环境简介 38 3.3.2 自建VisualC++指纹模式识别演示系统 38 3.3.3 VisualC++指纹模式识别开发环境详细说明 40 3.3.4 指纹图像BMP位图的读取 42 3.3.5 指纹图像的灰度模型 49 3.4 编制可移植VisualC++指纹识别源代码的要点 51 第二篇 指纹模式识别系统算法 第4章 指纹模式识别系统算法总论 55 4.1 指纹模式和指纹模式识别的发展历程 55 4.1.1 指纹的模式对象、模式特征对象、模式类型对象 55 4.1.2 指纹模式和指纹模式识别的发展历程 60 4.1.3 指纹模式的数据结构和数字图像文件表示 62 4.2 指纹模式识别系统算法的组成及流程 62 4.2.1 指纹模式识别系统算法组成概述 62 4.2.2 指纹模式识别系统算法实现流程 64 第5章 指纹模式识别的预处理 68 5.1 指纹数学建模与图像的畸变矫正 68 5.1.1 指纹图像畸变的自然模型 68 5.1.2 指纹图像畸变的物理模型 69 5.1.3 指纹图像畸变矫正的数学模型 70 5.1.4 指纹图像畸变矫正的C++源代码实现 78 5.2 指纹图像场及其计算 82 5.2.1 指纹图像场的自然模型 82 5.2.2 指纹图像场的物理模型 82 5.2.3 指纹图像场的数学模型 84 5.2.4 指纹图像场能计算的源代码实现 85 5.3 指纹图像的分割 88 5.3.1 计算强度场分割指纹图像 89 5.3.2 计算梯度场分割指纹图像 89 5.3.3 指纹图像分割的C++源代码实现 91 5.4 指纹图像的均衡 93 5.4.1 指纹图像灰度失衡的自然模型 93 5.4.2 指纹图像灰度失衡的物理模型 94 5.4.3 指纹图像灰度均衡的数学建模 95 5.4.4 指纹图像灰度均衡的C++源代码实现 97 5.5 指纹图像的收敛 99 5.5.1 指纹图像混沌发散的自然模型 99 5.5.2 指纹图像混沌发散的物理模型 100 5.5.3 指纹图像混沌发散的数学模型 101 5.5.4 指纹图像收敛的C++源代码实现 103 5.
©️2022 CSDN 皮肤主题:深蓝海洋 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值