MATLAB的指纹识别系统的设计与实现
本文系统地介绍了指纹识别技术的发展和国内外研究应用现状,阐述了建立指纹识别系统的必要性和意义。以数字图像处理为基础,研究指纹识别的原理和方法,重点分析基于神经网络指纹识别算法、滤波特征和不变矩指纹识别算法和指纹匹配算法,将matlab作为仿真工具,针对已有的三种指纹识别算法进行编程识别;并通过实验论证各种算法的优缺点。
指纹其实是比较复杂的。与人工处理不同,许多生物识别技术公司并不直接存储指纹的图象。多年来在各个公司及其研究机构产生了许多数字化的算法(美国有关法律认为,指纹图象属于个人隐私,因此不能直接存储指纹图象)。但指纹识别算法最终都归结为在指纹图象上找到并比对指纹的特征。
1.指纹的特征
我们定义了指纹的两类特征来进行指纹的验证:总体特征和局部特征。在考虑局部特征的情况下,英国学者E.R.Herry认为,只要比对13个特征点重合,就可以确认为是同一个指纹。
总体特征:总体特征是指那些用人眼直接就可以观察到的特征,包括:基本纹路图案环型(loop),弓型(arch),螺旋型(whorl)。其他的指纹图案都基于这三种基本图案。仅仅依靠图案类型来分辨指纹是远远不够的,这只是一个粗略的分类,但通过分类使得在大数据库中搜寻指纹更为方便。
局部特征:局部特征是指指纹上的节点的特征,这些具有某种特征的节点称为特征点。两枚指纹经常会具有相同的总体特征,但它们的局部特征--特征点,却不可能完全相同。
2.指纹的特征点
指纹纹路并不是连续的、平滑笔直的,而是经常出现中断、分叉或打折。这些断点、分叉点和转折点就称为“特征点”。就是这些特征点提供了指纹唯一性的确认信息。
图3.1 指纹识别系统工作原理框图
本文重点研究基于神经网络指纹识别算法、滤波特征和不变矩指纹识别算法和指纹匹配算法,,针对已有的三种指纹识别算法进行编程识别,通过matlab仿真,从而进一步论证三种算法的优缺点。
用神经网络进行识别选用哪种特征是个关键问题考虑到本文这里的识别过程是在同类型指纹间进行的这些指纹具有相似的纹线走向指纹的方向信息在这里就显得无关紧要了通过对同类型指纹的分析发现它们差别主要体现在具体的每个细节点上因此本文就提取了指纹的细节点特征作为识别特征每个样本提取的细节点特征是一个80×1维的向量包含20个特征点每个特征点的特征值是个4维的向量分别是特征点的类型特征点与参考点的纹线方向差值特征点与参考点的距离特征点与参考点的角度我们认为特征点的这些信息即可充分体现同类型指纹间的细微差别也同时具有一定的抗平移和抗旋转性。
本文采用的是学习矢量量化LVQ神经网络模型LVQ神经网络由于其自身的自组织和聚类特性可以很好地给出模式在多维空间的概率分布估计从而可较好地完成指纹的识别,其识别模型如图2.2所示.
图4.2 基于神经网络的自动指纹识别模型
滤波特征识别算法:指纹图像特征的表示要求满足尺度不变性、 位移不变性和旋转不变性3个特征。尺度不变性是满足的。在滤波提取算法中,位移不变性是通过确定指纹图像的中心参考点来实现的。 图像的旋转不变性可以通过在匹配阶段建立多角度旋转特征向量来实现。滤波特征的提取算法包括4 个步骤: 确定指纹图像的中心参考点,以及要处理的指纹区域,记为ROI 区域; 以参考点为中心, 对ROI 区域进行划分, 得到一定大小的块; 用一组Gabor 滤波器在八个不同的方向对ROI 区域进行滤波运算(在指纹图像中,完全获取指纹的局部脊线特征需要使用8 个方向滤波器, 获取全局结构信息仅需要4 个方向滤波器);在滤波图像中,计算每一块中灰度值相对于均值的平均绝对偏差, 进而得到特征向量或特征编码。基于滤波特征的指纹识别算法,首先对指纹图像进行滤波特征提取,然后在滤波特征值构成的特征向量的基础上进行匹配。
不变矩识别算法:算法的基本思路是:搜索预处理后的二值图像中所有可能为目标的区域,计算区域的7个不变矩特征,认为与模板匹配程度最高的区域为目标。其中相似度度量采用欧式距离。
算法程序:
{
CvRect r;
r.x = 120;
r.y = 100;
r.width = 20;
r.height = 20;
CvMoments m;
CvMat mat;
IplImage* src;
//8位图 必须为灰度图像
src = cvLoadImage("c:\\自然图2.bmp",0);
CvArr *arr;
arr = cvGetSubRect(src, &mat, r);
//获取矩
cvMoments(arr, &m, 0);
//获取空间矩
double m00 = cvGetSpatialMoment(&m,0,0);
//获取hu不变矩
CvHuMoments hu;
cvGetHuMoments(&m, &hu);
CString str;
str.Format("空间矩: m00 = %f \n Hu不变矩:h1 = %f, h2 = %f, h3 = %f, h4 = %f, h5 = %f, h6 = %f, h7 = %f, ",
m00,hu.hu1,hu.hu2,hu.hu3,hu.hu4,hu.hu5,hu.hu6,hu.hu7);
AfxMessageBox(str);
cvReleaseImage(&src);
cvWaitKey(0);
}
五、指纹匹配算法
指纹匹配就是指纹特征值比对过程。它是把当前取得的指纹特征值集合与事先存的指纹特征值模板进行匹配的过程。指纹匹配是一个模式识别的过程,判定的标准不是相等与不等,而是相似的程度。这个程度判定依赖于事先设定的阈值,以及与判定时比较的特征点的个数。阈值取的合理,特征点取的越多,误判的机率就越小。指纹匹配的方法很多,包括基于奇异点的匹配、嵴模式的匹配、特征点的匹配、特征点线对(两个特征点的连线)匹配,以及特征点组的匹配方法。
指纹匹配之前需作指纹定位。指纹定位是使待验证指纹的数个细节点的坐标值与指纹库中的数个细节点的坐标值一一相互对准的过程,从而使两个指纹图像对准重合。由于在指纹采样时,用户手指每次放置的位置和角度不同,形成的指纹图像也略有不同,因此各个指纹特征值的坐标值也就不同。主要表现为手指平移和旋转的差异,形成平移误差和旋转误差。解决指纹图像的平移误差和旋转误差是指纹比对算法面对的首要问题。可以选取奇异点作为对准参数,也可以选择某一区域内的特征点及嵴方向、嵴密度作为对准参数。实际上,在除了处理两种误差之外,在指纹采集过程中,由于每次按压的力度不同而形成的指纹图像挤压变形和拉伸变形,同样是指纹匹配之前需处理的。下图为基于混合模式的指纹识别算法的流程图。
图2.3 混合模式匹配算法流程图
算法程序:
function [sector_num] = whichsector(index)
% Modiofied by Luigi Rosa
% index is the index of current pixel of cropped image ( cropped image is
% 175 x 175 ); sector_num is the output and represents what is the
% corresponding sector.
global immagine n_bands h_bands n_arcs h_radius h_lato n_sectors matrice
length = h_lato;
x = rem( index , length );
y = floor(index / length);
x = x - floor(length / 2);
y = y - floor(length / 2);
rad = (x*x) + (y*y);
if rad < (h_radius*h_radius) % innerest radius = 12 (144=12*12)
sector_num = (n_sectors-1)+1;
sector_num;
return
end
if rad >= (h_bands*n_bands+h_radius)^2 % outtest radius = 72 (5184=72*72)
sector_num = (n_sectors-1)+2;
sector_num;
return
end
if x ~= 0
theta = atan( y / x );
else
if y > 0
theta = pi/2;
else
theta = -pi/2;
end
end
if x < 0
theta = theta + pi;
else
if theta < 0
theta = theta + 2*pi;
end
end
if theta < 0
theta = theta + 2*pi;
end
r = floor(rad ^ 0.5);
ring = floor(( r-h_radius )/h_bands);
arc = floor(theta /(2*pi/n_arcs));
sector_num = ring * n_arcs + arc;
本课题通过matlab仿真软件分别对神经网络指纹识别算法、滤波特征和不变矩指纹识别算法、指纹匹配算法进行仿真实验与分析。
图6.1 原始指纹图像
图6.2 经过神经网络和高斯滤波的指纹图像
图6.3 经过不变矩的指纹图像
图6.4 经过匹配细化后的指纹图像
程序1:
function out = go_to_next_element(in, path);
% called by end_track()
% with the input image and the path list, it will track to the next
% connected element of the ridge
[ix,iy] = size(in);
[length, dummy] = size(path);
next_x = 0;
next_y = 0;
flag = 0;
% length is the length of the path
%simply go to the next element
if (path(length,1) <4)
flag = 1;
end;
if (path(length,1) > 197)
flag =1;
end;
if (path(length,2) <4)
flag = 1;
end;
if (path(length,2) > 197)
flag =1;
end;
if flag == 0
[next_x,next_y] = find_next(in,path);
end;
%add it to the path
path(length+1,1) = next_x;
path(length+1,2) = next_y;
out = path;
程序2:
function [out, real_end ] =end_track(in,end_list,branch_list)
% 2/12
% this function will use the input image and the end_list to generate the
% output image ( cleaned ) and the list of real minutiae ( end points )
%
% out --- output image
% real_end --- real minutiae (end points)
% in --- input image
% end_list --- the list of valid and invalid end points
real_end = zeros(1,3);
end_count = 0;
'end_track'
out = in;
[number_of_end, dummy] = size(end_list);
for i=1:number_of_end
%path is a list of the tracked element in the currently
%tracking ridge
path = zeros(1,2);
path(1,1) = end_list(i,1);
path(1,2) = end_list(i,2);
if is_single(path(1,1),path(1,2),out) == 1
%it is a single point (pore) it should be invalid minutia
% and will be removed
out(path(1,1),path(1,2)) = 0;
else
% loop for n times , n > max path length value
flag = 0;
for j=1:25
path = go_to_next_element(in, path);
% check two conditions here
% if any one of the condition match
% break the loop
curr_x = path(len,1);
curr_y = path(len,2);
% three conditions will break the loop.
if is_a_end_point(curr_x,curr_y,end_list) == 1
'---> is a end'
%need to delete it from output image
%
flag = 1;
break;
elseif is_a_branch_point(curr_x,curr_y,branch_list) == 1
'--->is a branch'
%need to delete it from output image
%
flag =1;
break;
elseif curr_x == 0 & curr_y == 0
'---> curr is 0'
flag = 1;
break;
end;
% no break
j
end; %end of the 25 loop
% the path length of the ridge is
% longer than 24 pixels
% it consider as a valid minutia (end points)
% store it in the real_end
if flag == 0
[ path_length, dddd] = size(path);
mean_x = 0;
mean_y = 0;
for k = 1:path_length
mean_x = mean_x + path(k,1);
mean_y = mean_y + path(k,2);
end;
mean_x = mean_x / path_length;
mean_y = mean_y / path_length;
theta = atan2( (mean_x - path(1,1)),(mean_y - path(1,2)) );
end_count = end_count +1;
real_end(end_count,1) = path(1,1);
real_end(end_count,2) = path(1,2);
real_end(end_count,3) = theta;
end;
end; %else%
i
end;
文章浏览阅读1.7k次。GDBus 创建dbus服务示例dbus服务响应Method、Property、Signal_gdbus g_dbus_server_new_sync
文章浏览阅读344次。3布丁足迹;秒后自动跳转……function countDown(secs){ tiao.innerText=secs; if(--secs>0) setTimeout("countDown("+secs+")",1000); } countDown(3); 按钮式: 链接式: 返回上一步_auto.js跳转抖音个人界面 site:blog.csdn.net
文章浏览阅读239次。今天在服务器上安装pip包,遇到很多问题,查阅资料大多说pip版本过低导致,直接更新pip后,问题更加严重再次查资料,最后发现是pip版本过高的问题,python2.7版本最高支持到20.3.4使用easy_install来安装指定版本的pip,问题解决参考来源:https://www.cnblogs.com/hxlasky/p/14504677.html..._python2.7最高支持pip什么版本
文章浏览阅读938次。笔者按:文章中很多图片无法观看,读者可前往下面的原文地址阅读。文中有一个视频,读者可以从下面地址下载获得:https://pan.baidu.com/s/1o8sXZGA文章转载自:智慧安防网,地址:链接地址 2017年12月14日,“第五届中国·深圳智慧城市建设高峰论坛”在深圳大中华喜来登酒店盛大开幕!来自全国各地的政企领袖、行业大咖、权威专家、企业代表、媒体_前端智能
文章浏览阅读4.4k次,点赞8次,收藏26次。先从前序的第一个结点开始,其为根节点,然后在中序中找到该元素,一分为二,中序左边为左子树,右边为右子树,然后从前序中找第二个元素为根结点左子树的根,然后重复上面这个过程,发现出现NULL,跳到右子树。但是,如果在先根遍历中加入反映兄弟结点间的左右次序的信息(如以“^”标明空子树),则可以唯一确定一颗二叉树。当一个结点的左右孩子链都已建立,则以当前结点为根的一棵子树就已建立,返回上一层结点。二叉树的广义表表示语法如下图,其中元素表示结点,“^”表示空子树。,则创建一个结点,该结点的左孩子结点元素是。_中根后根构造二叉树
文章浏览阅读648次。NetSuite有高级打印和普通打印模板两种设置本文通过html进行修改,普通打印模板支持的单据相比高级要多:例如请购单;纸张大小:在高级打印模板设置的时候,只有信纸、A4、A5三种纸张可以进行选择,但是我们可以通过原代码修改 将打印的大小进行修改,源代码的size 修改大小之后,关闭原代码,不能预览,因为没有合适的size;现在只是测试过,但是还没有在针式打印机正式测试,A4纸打印机可以打印出设置大小的单据;<body header="nlheader..._netsuite 如何调整打印模版
文章浏览阅读605次。 public static void main(String[] args) throws IOException { BigInteger Num = new BigInteger("1"); int i = 1,count = 0; for(;i<=100;i++) { BigInteger I = new BigInteger(i+"");//将int数i转换..._计算100阶乘中0尾数的个数
文章浏览阅读98次。Omondo EclipseUML分为Studio版和Free版两种,我只用过Free版,对于创建EMF类图来说感觉已经够用了。不过和Eclipse的版本比起来,EclipseUML的升级比较缓慢,目前为止最新的版本还是2005年9月27日放出的,这就造成在新版本Eclipse里EclipseUML可能无法正常运行。20050927版本是针对Eclipse 3.1开发的,现在Ec..._free eclipse
文章浏览阅读89次。C语言中的接续符(\)是指示编译器行为的利器示例程序如下: 1 #in\ 2 clud\ 3 e <st\ 4 dio.h> 5 6 in\ 7 t m\ 8 ain(\ 9 )10 {11 pri\12 ntf\13 (\14 "Hello D.T.\n"15 )\16 ..._连接he和灵骑bian的第7÷4的余数个字符和h1 tao的字符数
文章浏览阅读266次。该插件乃本博客作者所写,目的在于提升作者的js能力,也给一些js菜鸟在使用插件时提供一些便利,老鸟就悠然地飞过吧。此插件旨在实现目前较为流行的无缝向上滚动特效,当鼠标移动到文字上时,向上滚动会停止,当鼠标离开时,向上滚动继续。整体代码如下:<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://..._文字无缝向上滚动插件
文章浏览阅读54次。https://blog.csdn.net/v_JULY_v/article/details/81708386转载于:https://www.cnblogs.com/bingws/p/10607641.html
文章浏览阅读204次。有向图G=(V,E)中,如果存在一个点r,使得从r出发,那么就可以到达所有的节点,那么称G为一个流图,记作(G,r)_强连通分支的有向无环图