目 录
摘 要 I
Abstract II
1绪论 1
1.1选题背景及意义 1
1.2研究现状 2
1.3研究主要内容 2
2技术介绍 3
2.1软件环境 3
2.1.1 C++的产生和发展以及特点简介 3
2.1.2 Visual C++6.0简介及其优点 5
2.2硬件环境 5
3指纹识别系统需求分析 6
3.1业务需求分析 6
3.2功能需求分析 6
3.3性能需求分析 7
4指纹识别系统总体设计 8
4.1指纹模式对象的信息量 8
4.2指纹识别系统算法的组成及流程 11
4.3指纹识别系统总体算法流程规划 14
5指纹识别系统的详细设计 15
5.1指纹识别系统界面设计 15
5.2指纹图像预处理算法 18
5.2.1 指纹图像畸变矫正 18
5.2.2指纹图像方向场和分割 22
5.2.3指纹图像均衡 25
5.2.4指纹图像去噪 26
5.2.5指纹图像的智能化增强 27
5.2.6指纹图像二值化 28
5.2.7指纹图像的细化 30
5.3指纹图像特征点提取 31
5.3.1 指纹特征端点的提取 31
5.3.2 指纹特征交叉点的提取 31
5.3.3 指纹特征中心点和三角点的提取 32
5.4指纹图像匹配 33
5.4.1指纹图像的配准 33
5.4.2 指纹图像的匹配 33
5.5指纹采集仪的制作 34
结 论 36
致 谢 37
参考文献 38
3指纹识别系统需求分析
在进行指纹识别系统的开之前发,我们必须首先了解与分析用户与市场的需求。在做一个软件之前做需求调研是不可不缺少的,因为我们不能做一个没有实际用户的软件。通过调研,我们就可以知道,我们所做的软件是否实用,并且可以给软件所具有的功能作出导向。因此需求分析是整个设计过程的基础,它可以直接影响到软件的开发速度和质量。
经过现场的调研,本章主要对指纹系统的业务需求、功能需求、性能需求、软件需求进行详细分析。需求分析是整个设计过程的基础,它将直接影响应用程序的开发速度与质量,所以对指纹识别系统的需求调研分析必不可少。
3.1业务需求分析
指纹识别系统在业务上的应用主要是起到一个身份鉴别的作用。身份鉴别就像一把钥匙,也可以理解为权限,只有得到了这把钥匙,我们才能进行接下来的工作。它就犹如一个大门,只允许主人进去,一切陌生人都被拒之门外。传统的身份鉴别作用越来越不能适应当今社会的脚步,而且可应用的范围很小。指纹识别技术在身份鉴别上的应用顺应历史潮流,势不可挡。
指纹识别系统可以应用在社会服务管理、医保服务管理、身份护照管理、银行账户管理、智能家居管理等等。把指纹识别系统嵌入在身份验证模块中,只需要本人的指纹轻轻一按,就能快速识别,进入接下来的工作,快捷,安全。在上面的这些行业中迫切需要指纹识别技术的加入让工作变的轻松,简单[4]。
3.2功能需求分析
通过一系列的调查研究,对应上一节的业务需求分析,本节主要从指纹识别系统的几个功能模块指纹图像采集、指纹图像预处理、指纹特征提取、指纹特征比配、特征数据库这几个方面来分析公司的功能需求。
a)指纹图像采集 :用于捕捉指纹图像。
b)指纹图像预处理 :预处理过程是整个系统关键的第一步。指纹图像由于输入设备等原因会发生畸变、不清晰、产生噪音,所以特征提取之前,需要对图像进行预处理。常用的预处理过程一般包括:增强、细化,分割、二值化等。
c)指纹特征提取:指纹特征提取根据指纹对象预处理后形成的指纹框架,提取出指纹的特征点,然后把特征点分类,形成特征点拓扑数据结构。特征点整体上分成局部特征点和整体特征点。局部特征点有端点、交叉点,整体特征点有三角点和中心点。
d)指纹特征比配:指纹特征比配就是输入的指纹特征与事先保存起来的模板特征进行对比,从而判断这两个指纹图像是否来自同一个手指。使用最普遍的指纹匹配算法是基于细节点的匹配算法
e)特征数据库用来存储指纹图像模板。
3.3性能需求分析
性能需求有以下几个方面:
a)自己制作的指纹采集装置,采集图片要清晰。主要是拟采用COMS摄像头和三菱镜,应用光的折射成像原理来捕获指纹图像。应用三菱镜通过光的折射会增加图像采集的精度。
b)指纹的信息量很大,要使计算机做到识别速度快,质量高,提高软件的性能,就必须要对信息做出合理化的减少。通过一系列的指纹模式转化可以极大地减少指纹的信息量。从而达到指纹识别的高速,高质。
c) 软件的指纹比对结果要准确。拟采用数学上的拓扑数据知识,来完成指纹的比对。把指纹的特征点装配成指纹拓扑数据结构,然后利用整体特征点来进行匹配,使其处在一个坐标系下,再利用分支特征点进行精密的比对。达到精确地指纹比对结果。
4指纹识别系统总体设计
本章的内容是介绍指纹识别系统的总体设计。总体设计就像是一个设计蓝图,和方向标,给我们的工作作出指引。同时总体设计对项目的开发进度和项目的质量有着至关重要的影响。通过上一章对指纹识别系统的需求分析,在本章规划一个指纹识别系统的总体设计方向。
指纹识模式识别系统存在着大量的算法,每个算法之间存在着独立性,把所有的算法按一定的逻辑关系就能实现强大的指纹识别系统。本章主要介绍指纹识别系统的算法总论,在对开发系统进行全面分析调查的基础上,制定出应用指纹识别系统的算法规划,对建立一个该系统来说是必须的,也是全面展开开发工作的重要基础。其中指纹识别系统的算法总论分为三个大部分:指纹模式对象的信息量、指纹模式转化方法、指纹识别系统算法的组成及流程。
4.1指纹模式对象的信息量
在起初开始做指纹识别系统之前,我很迷茫,不知道到底该如何插手,面对我们自己的真实指纹,既熟悉又陌生。熟悉的是它就是在我们身上,摸得到,看得到,陌生的是指纹的特点,我们该如何进行辨别,还有计算机要出入处理,处理什么。后来我在图书馆查阅了很多关于指纹识别的很多书,逐渐的我找到了我的设计方向。设计思维导图如图4.1所示。
// FPEngine.cpp : Defines the entry point for the DLL application.
//
#include "stdafx.h"
#include "FPEngine.h"
#include "VF_Api.h"
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
// This is an example of an exported variable
FPENGINE_API int nFPEngine=0;
// This is an example of an exported function.
FPENGINE_API int fnFPEngine(void)
{
return 42;
}
// This is the constructor of a class that has been exported.
// see FPEngine.h for the class definition
CFPEngine::CFPEngine()
{
return;
}
//
// Extract: 从指纹图像中提取指纹特征
//
FPENGINE_API int 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;
}
//
// ExtractEx: 从指纹图像BMP文件中提取指纹特征
//
FPENGINE_API int AnalyzeFromFile(LPCSTR lpszFileName, BYTE *lpFeature, int *lpSize)
{
//
// lpszFileName: [in] 指纹图像文件路径
// Resolution: [in] 指纹图像分辨率
// lpFeature: [out] 提取的指纹特征数据缓冲区指针
// lpSize: [out] 提取的指纹特征数据大小
//
// TODO: Add your implementation code here
VF_RETURN re;
// 读取指纹图像数据
re = VF_LoadFinger(lpszFileName);
if(re != VF_OK)
return re;
// 处理指纹图像,提取指纹特征
re = VF_Process();
if(re != VF_OK)
return re;
// 对指纹特征进行编码
re = VF_FeatureEncode(&g_Feature, lpFeature, lpSize);
if(re != VF_OK)
return re;
return 0;
}
//
// VerifyMatch: 两个指纹特征间的比对
//
FPENGINE_API int PatternMatch(BYTE *lpFeature1, BYTE *lpFeature2, int *lpScore)
{
//
// lpFeature1: [in] 第一个指纹特征
// lpFeature2: [in] 第二个指纹特征
// lpScore: [out] 比对的相似度
// FastMode: [in] 是否进行快速模式比对
//
// TODO: Add your implementation code here
VF_RETURN re;
MATCHRESULT mr;
FEATURE feat1, feat2;
// 第一个指纹特征的解码
re = VF_FeatureDecode(lpFeature1, &feat1);
if(re != VF_OK)
return re;
// 第二个指纹特征的解码
re = VF_FeatureDecode(lpFeature2, &feat2);
if(re != VF_OK)
return re;
*lpScore = 0;
bool FastMode = true;
if(FastMode)
{
// 快速模式的比对
VF_VerifyMatch(&feat1, &feat2, &mr, VF_MATCHMODE_IDENTIFY);
}
else
{
// 精确模式的比对
VF_VerifyMatch(&feat1, &feat2, &mr, VF_MATCHMODE_VERIFY);
}
// 匹配的相似度
if(mr.MMCount < 8)
*lpScore = 0;
else
*lpScore = mr.Similarity;
return 0;
}
//
// SaveFeature: 保存指纹特征到文件中
//
FPENGINE_API int SaveFeature(LPCSTR lpszFileName, BYTE *lpFeature)
{
/
// lpFeature: [in] 指纹特征
// lpszFileName: [in] 文件路径
/
// TODO: Add your implementation code here
FILE *fp = NULL;
BYTE v;
int i;
// 对指纹特征进行校验
v = 0;
for(i = 0; i < (lpFeature[0]*256+lpFeature[1]); i++)
{
v = v ^ lpFeature[i];
}
// 校验失败返回错误
if(v != 0)
return VF_SAVEFEATURE_ERR;
// 创建并写入指纹特征数据
fp = fopen(lpszFileName, "wb");
if(fp == NULL)
{
return VF_SAVEFEATURE_ERR;
}
fwrite((char *)lpFeature, lpFeature[0]*256+lpFeature[1], 1, fp);
fclose(fp);
return 0;
}
//
// LoadFeature: 从指纹特征到文件中读取指纹特征
//
FPENGINE_API int LoadFeature(LPCSTR lpszFileName, BYTE *lpFeature, int *lpSize)
{
/
// lpszFileName: [in] 指纹特征文件路径
// lpFeature: [out] 指纹特征
// lpSize: [out] 指纹特征大小
/
// TODO: Add your implementation code here
FILE *fp = NULL;
BYTE v;
int i;
fp = fopen(lpszFileName, "rb");
if(fp == NULL)
{
return VF_LOADFEATURE_ERR;
}
// 读取指纹特征大小
fread((void *)&lpFeature[0], 2, 1, fp);
// 读取指纹特征其他字段数据
fread((void *)&lpFeature[2], lpFeature[0]*256+lpFeature[1]-1, 1, fp);
fclose(fp);
// 校验
v = 0;
for(i = 0; i < (lpFeature[0]*256+lpFeature[1]); i++)
{
v = v ^ lpFeature[i];
}
// 校验失败返回错误
if(v != 0)
return VF_LOADFEATURE_ERR;
return 0;
}
//
// LoadFinger: 从指纹图像文件中读取指纹图像数据
//
FPENGINE_API int LoadFingerImage(LPCSTR lpszFileName, BYTE *lpFinger, int *lpWidth, int *lpHeight)
{
/
// lpszFileName: [in] 指纹图像文件路径
// lpFinger: [out] 指纹图像矩阵数据
// lpWidth: [out] 图像宽度指针
// lpHeight: [out] 图像高度指针
/
// TODO: Add your implementation code here
int re;
// 读取图像数据并得到图像大小
re = loadBitmap((char *)lpszFileName, lpFinger, lpWidth, lpHeight);
if(re != 0)
return VF_LOADFINGER_ERR;
return 0;
}
//
// SaveFinger: 将指纹图像数据保存为BMP文件
//
FPENGINE_API int SaveFingerImage(LPCSTR lpszFileName, BYTE *lpFinger, int Width, int Height)
{
/
// lpFinger: [in] 指纹图像矩阵数据
// Width: [in] 图像宽度
// Height: [in] 图像高度
// lpszFileName: [in] 指纹图像文件路径
/
// TODO: Add your implementation code here
int re;
// 保存指纹图像数据为BMP文件
try {
re = saveBitmap(lpFinger, Width, Height, (char *)lpszFileName);
} catch (char *str) {
FILE *fp = NULL;
fp = fopen("d:\\err.txt", "wb");
fwrite(str, strlen(str), 1, fp);
fclose(fp);
}
if(re != 0)
return VF_SAVEFINGER_ERR;
return 0;
}
//
// GetQuality: 获取指纹图像质量分数(100分满分)
//
FPENGINE_API int GetImageQuality(BYTE *lpFinger, int Width, int Height, int *pScore)
{
/
// lpFinger: [in] 指纹图像矩阵数据
// Width: [in] 图像宽度
// Height: [in] 图像高度
// pScore: [out] 质量分数指针
/
// TODO: Add your implementation code here
VF_RETURN re;
sint32 x, y, num;
sint32 temp,score;
// 导入指纹图像数据
re = VF_ImportFinger(lpFinger, Width, Height);
if(re != VF_OK)
return re;
// 对指纹图像进行二次平滑
smooth(g_lpOrgFinger, g_lpTemp, 1, 1);
smooth(g_lpOrgFinger, g_lpTemp, 1, 1);
memcpy(g_lpOrgFinger, g_lpTemp, IMGSIZE);
// 利用图像低频部分计算方向场,提高速度
zoomout();
// 计算指纹图像的方向场,得到幅值
getOrientMap(6);
// 分割指纹图像
divide(12, 32);
//统计前景区域大小
temp = 0;
num = 0;
for(y = 0; y < IMGH; y++)
{
for(x = 0; x < IMGW; x++)
{
if(*(g_lpDivide + temp + x) != 255)
{
num++;
}
}
temp += IMGW;
}
// 计算质量分数
score = (int)(100*num/(0.8*IMGSIZE)+0.5);
if(score > 100)
score = 100;
*pScore = score;
return 0;
}