指纹识别系统实验报告.docx
《指纹识别系统实验报告.docx》由会员分享,可在线阅读,更多相关《指纹识别系统实验报告.docx(22页珍藏版)》请在冰豆网上搜索。
![指纹识别系统实验报告.docx](https://file1.bdocx.com/fileroot1/2023-3/1/da6be5ae-d549-4097-86d9-7384f08b514d/da6be5ae-d549-4097-86d9-7384f08b514d1.gif)
指纹识别系统实验报告
实验报告
《指纹识别系统》
【实验名称】指纹识别系统
【实验目的】1.对指纹识别系统的图像预处理有一定的掌握;
2.对后续操作只简单了解;
3.通过功能模块实现指纹识别系统。
【实验内容】1.系统需求分析;
2.系统设计;
3.系统实现。
【实验步骤】
一、系统需求分析
1、目的与背景
在网络化时代的今天,我们每个人都拥有大量的认证密码,比如开机密码、邮箱密码、银行密码、论坛登录密码等;并配备了各种钥匙,如门钥匙,汽车钥匙,保险柜钥匙等。
这些都是传统的安全系统所采用的方式,随着社会发展,其安全性越来越弱。
而我们的生活随时都需要进行个人身份的确认和权限的认定,尤其是在信息社会,人们对于安全性的要求越来越高,同事希望认证的方式简单快速。
为了解决这一问题,人们把目光转向了生物识别技术,希望能借助人体的生理特征或行为来进行身份识别。
这样人们可以不用携带大串钥匙,不用费心去记各种密码。
另外,生物特征具有唯一性,不可复制性,例如指纹。
生物特征识别技术所研究的生物特征包括脸、指纹、手掌纹、虹膜、视网膜、声音(语音)、体形。
而人类在追寻文档、交易及物品的安全保护的有效性与方便性经历了三个阶段的发展。
第一阶段也就是最初始的方法,是采用大家早已熟悉的各种机械钥匙。
第二阶段是由机械钥匙发展到数字密钥如密码或条形码等。
第三阶段是利用人体所固有的生物特征(指纹识别)来辨识与验证身份。
生物识别(指纹识别)是当今数字化生活中最高级别的安全密钥系统。
对生物识别(指纹识别)技术来说,被广泛应用意味着它能在影响亿万人的日常生活的各个地方使用。
通过取代个人识别码和口令,生物识别(指纹识别)技术可以阻止非授权的"访问",可以防止盗用ATM、蜂窝电话、智能卡、桌面PC、工作站及其计算机网络;在通过电话、网络进行的金融交易时进行身份认证;在建筑物或工作场所生物识别技术(指纹识别)可以取代钥匙、证件、图章等。
生物识别(指纹识别)技术的飞速发展及其广泛应用将开创个人身份鉴别的新时代!
指纹识别
二.系统设计
1.总体设计及系统架构
本系统有两大功能:
指纹登记和指纹比对。
指纹登记主要包括指纹采集、指纹图像预处理、特征点提取、特征模板存储和输出显示;指纹比对的前三步与指纹登记相同,但在特征点提取后,是将生成的特征模板与存储在指纹特征模板库中的特征模板进行特征匹配,最后输出显示匹配结果。
自动指纹识别系统的基本原理框图如图1所示。
图1自动指纹识别的基本原理框图
本系统在结构上分为三层:
系统硬件平台、操作系统和指纹识别算法。
系统层次结构如图2所示。
图2系统层次
最底层——系统硬件平台,是系统的物理基础,提供软件的运行平台和通信接口。
系统的硬件平台在Altera的FPGACyclone嵌入式系统开发板上实现,指纹传感器采用美国Veridicom公司的FPS200。
FPS200可输出大小为256×300像素、分辨率为500dpi的灰度图像。
第二层是操作系统,采用μC/OSII。
μC/OSII是一个基于抢占式的实时多任务内核,可固化、可剪裁、具有高稳定性和可靠性。
这一层提供任务调度以及接口驱动,同时,通过硬件中断来实现系统对外界的通信请求的实时响应,如对指纹采集的控制、对串口通信的控制等。
这种方式可以提高系统的运行效率。
最上层是指纹识别核心算法的实现。
该算法高效地对采集到的指纹进行处理和匹配。
采用C语言在FPGA的集成开发环境(IDE)中实现。
2.系统硬件的设计与实现
2.1FPGA嵌入式软核处理器简介
FPGA嵌入式处理器是Altera公司于2004年6月推出的第二代用于可编程逻辑器件的可配置的软核处理器,性能超过200DMIPS。
FPGA是基于哈佛结构的RISC通用嵌入式处理器软核,能与用户逻辑相结合,编程至Altera的FPGA中。
处理器具有32位指令集,32位数据通道和可配置的指令以及数据缓冲。
它特别为可编程逻辑进行了优化设计,也为可编程单芯片系统(SoPC)设计了一套综合解决方案。
FPGA处理器系列包括三种内核:
一种是高性能的内核(FPGA/f);一种是低成本内核(FPGA/e);一种是性能/成本折中的标准内核(FPGA/s),是前两种的平衡。
本系统采用标准内核。
FPGA处理器支持256个具有固定或可变时钟周期操作的定制指令;允许FPGA设计人员利用扩展CPU指令集,通过提升那些对时间敏感的应用软件的运行速度,来提高系统性能。
2.2硬件平台结构
系统的硬件平台结构如图3所示。
图3系统硬件平台结构
本系统使用FPS200指纹传感器获取指纹图像。
FPS200是电容式固态指纹传感器,采用CMOS技术,获取的图像为256×300像素,分辨率为500dpi。
该传感器提供三种接口方式:
8位微机总线接口、集成USB全速接口和集成SPI接口。
本系统采用集成SPI接口。
指纹采集的程序流程是:
首先初始化FPS200的各个寄存器,主要是放电电流寄存器(DCR)、放电时间寄存器(DTR)和增益控制寄存器(PGC)
的设置;然后查询等待,指纹被FPS200采集进入数据寄存器后,通过DMA存入内存。
由于从指纹传感器采集到的指纹图像数据在80KB左右,以DMA方式存入片内RAM。
FPGA对指纹图像数据进行处理后,生成指纹特征模板,在指纹登记模式下,存入片外Flash中;在指纹比对模式下,与存储在Flash中的特征模板进行匹配,处理结果通过LCD和七段LED显示器输出显示。
本系统的硬件平台主要是在Altera的FPGACyclone嵌入式开发板上实现,选用Altera的Cyclone版本的FPGA开发套件,包括FPGA处理器、标准外围设备库、集成了SoPCBuilder系统设计工具的QuartusII开发软件等。
系统的主要组件FPGA的标准内核、片内存储器、SPI、UART、DMA控制器、并行I/O接口、Avalon总线、定时器等都集成在一块Altera的CycloneFPGA芯片上,使用SoPCBuilder来配置生成片上系统。
SoPCBuilder是功能强大的基于图形界面的片上系统定义和定制工具。
SoPCBuilder库中包括处理器和大量的IP核及外设。
根据应用的需要,本系统选用FPGAProcessor、OnChipMemory、FlashMemory(CommonFlashInterface)、SPI、JTAGUART、DMA、Intervaltimer、LCDPIO、SevenSegmentPIO、AvalonTriStateBridge等模块。
对这些模块配置完成后,使用SoPCBuilder进行系统生成。
SOPCBuilder自动产生每个模块的HDL文件,同时自动产生一些必要的仲裁逻辑来协调系统中各部件的工作。
3.系统软件的设计与实现
本系统的指纹图像处理及识别算法采用C语言在FPGAIDE中实现。
指纹识别算法的流程如图4所示。
图4指纹识别算法流程
背景分离是将指纹区与背景分离,从而避免在没有有效信息的区域进行特征提取,加速后续处理的速度,提高指纹特征提取和匹配的精度。
采用标准差阈值跟踪法,图像指纹部分由黑白相间的纹理组成,灰度变化大,因而标准差较大;而背景部分灰度分布较为平坦,标准差较小。
将指纹图像分块,计算每个小块的
标准差。
若大于某一阈值(本文取20),则该小块中的所有像素点为前景;
否则,为背景。
方向图是用纹线的方向来表示原来的纹线。
本文采用块方向图,将源指纹图像分成小块,使用基于梯度值的方向场计算方法,计算出每个小块的脊线方向。
图像增强的目的是改善图像质量,恢复脊线原来的结构;采用方向滤波,设计一个水平模板,根据计算出的方向图,在每个小块中将水平模板旋转到所需要的方向进行滤波。
图像的二值化是将脊线与背景分离,将指纹图像从灰度图像转换为二值图像。
二值化后的图像经过细化,得到纹线的骨架图像。
细化采用迭代的方法,使用ZhangSuen并行细化算法,可对二值图像并行处理。
特征提取阶段,选择脊线端点和分叉点作为特征点,记录每一个特征点的类型、位置和方向信息,从而得到指纹的特征点集。
但由于在指纹扫描和预处理阶段会引入噪声,产生大量伪特征点,因此需要进行伪特征点的去除。
去除伪特征点后的特征点集作为特征模板保存。
特征匹配阶段采用基于特征点的匹配算法,通过平移和旋转变换实现特征点的大致对齐重合,计算坐标变换后两个模板中的特征点的距离和角度。
如果小于某一阈值(本文的距离和角度阈值分别取5个像素和10°),则认为是一对匹配的特征点。
计算得出所有匹配的特征点对后,计算匹配的特征点占模板中所有特征点的百分比S。
根据系统的拒识率(FRR)和误识率(FAR)要求设置阈值TS。
如果S大于或等于阈值TS,则认为是同一指纹;否则,匹配失败。
4.系统程序语言
用C语言和C++语言进行编程,程序各部分成员与方法如下:
Sensor
三.系统实现
打开程序
进行指纹识别
匹配成功
匹配失败
四、代码实现
1.
#include
#include
#include
#include"thin_image.h"
intnCol,nVS;
voidreadBmp(char*bmpFile)
{
FILE*bmpInput,*rasterOutput;
sImageoriginalImage;
unsignedcharsomeChar;
unsignedchar*pChar;
intnColors;
longfileSize;
intvectorSize,r,c;
/*initializepointer*/
someChar='0';
pChar=&someChar;
printf("Readingfilename%s\n",bmpFile);
/*--------READINPUTFILE------------*/
bmpInput=fopen(bmpFile,"rb");
fseek(bmpInput,0L,SEEK_END);
rasterOutput=fopen("data.txt","w");
/*--------GETBMPDATA---------------*/
originalImage.cols=(int)getImageInfo(bmpInput,18,4);
originalImage.rows=(int)getImageInfo(bmpInput,22,4);
fileSize=getImageInfo(bmpInput,2,4);
nCol=nColors=getImageInfo(bmpInput,46,4);
nVS=vectorSize=fileSize-(14+40+4*nColors);
/*-------PRINTTOSCREEN-------------*/
printf("Width:
%d\n",originalImage.cols);
printf("Height:
%d\n",originalImage.rows);
printf("Filesize:
%ld\n",fileSize);
printf("#Colors:
%d\n",nColors);
printf("Vectorsize:
%d\n",vectorSize);
image->Hres=originalImage.cols;
image->Vres=originalImage.rows;
image->Size=fileSize;
image->i=newPixel[fileSize];
image->p=newPixel*[fileSize];
for(inti=0;iHres;i++)
image->p[i]=newPixel[image->Vres];
printf("%d\n",image->Hres);
/*----------READRASTERDATA---------*/
fseek(bmpInput,(54+4*nColors),SEEK_SET);
intcount=0;
for(r=0;r<=originalImage.rows-1;r++)
{
for(c=0;c<=originalImage.cols-1;c++)
{
count++;
fread(pChar,sizeof(char),1,bmpInput);
image->p[r][c]=int(*pChar)/255;
//invertingtheimage
if(image->p[r][c]==1)
{
image->p[r][c]=0;
}
else
{
image->p[r][c]=1;
}
fprintf(rasterOutput,"(%d,%d)=%d\n",r,c,int(*pChar)/255);
}
}
fclose(bmpInput);
fclose(rasterOutput);
}
voidwriteBmp(char*bmpFile)
{
FILE*bmpOutput,*rasterOutput,*oldFile;
sImageoriginalImage;
unsignedcharsomeChar;
unsignedchar*pChar;
intnColors;
longfileSize;
intvectorSize,r,c;
oldFile=fopen("output.bmp","rb");
/*initializepointer*/
someChar='0';
pChar=&someChar;
printf("Writingfilename%s\n",bmpFile);
/*--------writeINPUTFILE------------*/
bmpOutput=fopen(bmpFile,"wb");
fseek(bmpOutput,0L,SEEK_END);
rasterOutput=fopen("data.txt","w");
originalImage.cols=image->Hres;
originalImage.rows=image->Vres;
fileSize=image->Size;
nColors=nCol;
vectorSize=nVS;
//image->i=newPixel[fileSize];
//image->p=newPixel*[fileSize];
//writetheheader
//54+4*nColors
//charch[2];
//for(inti=0;i<54+4*nColors;i++){/
//fread(ch,sizeof(char),1,oldFile);
//fwrite(ch,sizeof(char),1,bmpOutput);
//}
copyImageInfo(oldFile,bmpOutput);
copyColorTable(oldFile,bmpOutput,nColors);
/*-------PRINTTOSCREEN-------------*/
printf("Width:
%d\n",originalImage.cols);
printf("Height:
%d\n",originalImage.rows);
printf("Filesize:
%ld\n",fileSize);
printf("#Colors:
%d\n",nColors);
/*----------WriteRASTERDATA---------*/
fseek(bmpOutput,(54+4*nColors),SEEK_SET);
for(r=0;r<=originalImage.rows-1;r++)
{
for(c=0;c<=originalImage.cols-1;c++)
{
*pChar=(unsignedchar)image->p[r][c]*255;
fwrite(pChar,sizeof(char),1,bmpOutput);
//fprintf(rasterOutput,"(%d,%d)=%d\n",r,c,int(*pChar)/255);
}
}
fclose(bmpOutput);
fclose(rasterOutput);
}
/*-------------COPIESHEADERANDINFOHEADER----------------*/
voidcopyImageInfo(FILE*inputFile,FILE*outputFile)
{
unsignedchar*ptrC;
unsignedchardummy;
inti;
dummy='0';
ptrC=&dummy;
fseek(inputFile,0L,SEEK_SET);
fseek(outputFile,0L,SEEK_SET);
for(i=0;i<=50;i++)
{
fread(ptrC,sizeof(char),1,inputFile);
fwrite(ptrC,sizeof(char),1,outputFile);
}
}
/*----------------COPIESCOLORTABLE-----------------------------*/
voidcopyColorTable(FILE*inputFile,FILE*outputFile,intnColors)
{
unsignedchar*ptrC;
unsignedchardummy;
inti;
dummy='0';
ptrC=&dummy;
fseek(inputFile,54L,SEEK_SET);
fseek(outputFile,54L,SEEK_SET);
for(i=0;i<=(4*nColors);i++)/*thereare(4*nColors)bytesincolortable*/
{
fread(ptrC,sizeof(char),1,inputFile);
fwrite(ptrC,sizeof(char),1,outputFile);
}
}
/*----------GETIMAGEINFOSUBPROGRAM--------------*/
longgetImageInfo(FILE*inputFile,longoffset,intnumberOfChars)
{
unsignedchar*ptrC;
longvalue=0L;
unsignedchardummy;
inti;
dummy='0';
ptrC=&dummy;
fseek(inputFile,offset,SEEK_SET);
for(i=1;i<=numberOfChars;i++)
{
fread(ptrC,sizeof(char),1,inputFile);
/*calculatevaluebasedonaddingbytes*/
value=(long)(value+(*ptrC)*(pow(256,(i-1))));
}
return(value);
}/*endofgetImageInfo*/
/*----------SETIMAGEINFOSUBPROGRAM--------------*/
voidsetImageInfo(FILE*outputFile,longoffset,intnumberOfChars,longvalue)
{
unsignedchar*ptrC;
//longvalue=0L;
unsignedchardummy;
inti;
dummy='0';
ptrC=&dummy;
fseek(outputFile,offset,SEEK_SET);
for(i=1;i<=numberOfChars;i++)
{
printf("%d\n",value);
fwrite(&(((char*)(&value))[i]),sizeof(char),1,outputFile);
/*calculatevaluebasedonaddingbytes*/
//value=(long)(value+(*ptrC)*(pow(256,(i-1))));
//*ptrC=(unsignedchar)value/pow(256,(i-1));
//value=fmod(value,pow(256,(i-1)));
//fwrite(ptrC,sizeof(char),1,outputFile);
}
//return(value);
}/*endofsetImageInfo*/
2.
#include
#include
#include
#include"thin_image.h"
staticintmasks[]={0200,0002,0040,0010};
staticunsignedchardelet[512]={
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,1,0,0,1,1,0,1,1,1,0,0,1,1,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,1,1,1,0,1,1,0,0,1,1,0,0,1,1,
0,0,0,0,0,0,0