MATLAB指纹识别算法实现

图像处理 专栏收录该内容
191 篇文章 15 订阅

摘 要 由于指纹所具有的普遍性,唯一性和不变性,以及指纹识别技术具有很高的可行性和实用性,使之成为目前最流行、也最可靠的个人身份认证技术之一。

本文主要对指纹图像进行三方面处理:图像预处理、特征提取和特征匹配。图像预处理包括四个步骤:图像分割、滤波增强、二值化、细化,对指纹图像进行预处理后,去除了原图像的冗余部分,方便后续的识别处理;特征提取主要是提取指纹图像细化后的端点和分叉点;特征匹配是利用两个指纹的图像进行特征点比较,来确定两幅图像是否来自于同一手指。

本文给出了指纹图像预处理、特征提取、特征匹配的matlab程序及处理结果。该结果证明,用matlab实现的这些算法的处理结果比较理想,满足识别的可行性和应用性。

关键词 分割,二值化,细化,特征点提取,匹配,Matlab

第1章 绪论

指纹识别概述

21世纪是信息化时代,在这个特殊的时代,我们的生活中电子设备越来越多,比如,笔记本电脑,ATM取款机,考勤系统,门禁系统和各种智能卡,网络中的网上银行,人人网账号等,都需要验证身份。对个人身份识别技术的要求不断提高,如果没有安全可靠和快捷的身份识别技术,电子商务、网上购物等就存在重大隐患。目前许多身份验证系统都采用“用户名+密码”的方式来进行用户访问控制[1],但此方法存在诸多隐患,比如密码被窃取、破解或遗忘。因此我们在与机器交互时急需一种准确、安全快捷的识别技术来取代现有的身份验证。

1.1.1 研究背景及意义

因为人的一些特殊的生物特征,人们把身份认证技术的目光转向了生物特征的识别技术。生物识别技术是利用人体生物特征进行身份认证的一种技术,它主要有指纹、手形、脸形、声音、虹膜、视网膜、签名、掌纹、和脸部热谱图等,在生物识别技术中指纹识别技术是目前相对成熟的一种。

1.1.2 国内外研究状况

指纹是人特有的一种特征,在中国的研究也有近百年的历史,中国被认为是世界上最早应用指纹识别技术的国家,指纹识别技术从很早以前的人工比对到现如今采用先进的计算机技术实现指纹的识别,使得指纹对比比以前更加准确,识别效率得到了非常大的提高。

在国外,经过几十年的发展,指纹识别技术的软件和硬件相对来说都比较成熟。在很多国家内,政府用法律强制性的规定来保证生物识别技术的应用。所以总体上来说,国外的指纹识别应用己经进入了正规的应用阶段。

但是在国内,经过了十多年的发展,指纹识别的一些关键算法是有了较大的提高和发展,但是距离国外的优秀算法仍然有非常大的差距,因此国内的应用现在处于发展的初期,应用主要集中在自发性的企业上。

指纹识别的应用前景是非常广阔的,它的应用将渗透到社会生活,经济贸易的每一个角落,将成为保护我们个人以及国家信息的重要手段。

指纹识别的原理和方法

1.2.1 指纹的基本知识

指纹是我们各个手指的第一个指节的指头表面突起的脊线;而脊线是手指突起的花脊线条;谷线是两个脊线之间低凹下去的部分;指印是指纹在物体表面留下的痕迹;指纹的细节特征是指纹固有的自身特点。根据指纹中的细节特征我们常将指纹特点分为端点和分叉点,如图1-1所示。

图1-1 端点、分叉点

英国科学家Gallon在1892年的《Fingerprint》一书中提出了指纹的四条基本性质。

(1)确定性:指纹脊线的轮廓和细节特征是在人的一生中基本上保持不变。自胚胎六个月到出生至死亡腐败之前,始终是没有很大变化的。指纹的确定性,还表现在它具有一定的复原性和难于毁灭的特性。

(2)唯一性:由于指纹脊线的连接关系千变万化,因此,即使两个不同的指纹有着相同的轮廓和相同数量的细节特征,它们的细节位置也是不可能完全相同的。

(3)可分类性:指纹可根据脊线和谷线的走向进行分类,一般可分为如图1-2所示的弓形、环形和螺旋形。

(a)弓形 (b) 环形 (c)螺旋形

图1-2 指纹类型

(4)留痕性:指纹接触物体后会留下痕迹。指纹的这个特点,是与手掌表面附着面的污垢的性能紧密相关的。

正是因为这些独特的性质,指纹被国内外的刑侦界称为“证据之首”。一切指纹的自动识别系统,都是根据这些独特的性质,进行身份的识别和确认的。

脊线是指纹的一个非常突出的特征,指纹的脊线一般由弓形线、环形线、箕形线、螺形线、曲形线和棒形线等脊线组成,每种脊线具有不同的细节和长度,如图1-3所示[2]。

图1-3 脊线的一般形态

1.2.2 指纹识别的原理及应用

在指纹识别的技术中, 一般都采用总体特征和局部特征来进行识别。总体特征是那些很容易就能看出来的非常明显的特征, 局部特征则是一小块指纹中的细节特征。指纹纹路一般都会有断点和分叉点, 因此会形成一些独特的节点。根据研究,两个指纹的总体特征有时候会很相似,但是局部特征是不会相同的,即没有两个指纹的纹路是相同的。英国学者认为, 只要有13个特征点能重合, 就可以确认这两枚指纹是同一指纹[3]。指纹的面积虽然不大但却蕴含着大量的识别信息。这些皮肤的纹路会在交叉点,断点上有很大的区别。在指纹识别的过程中将其称为“特征点”,利用特征点的性质,我们可以把一个人的指纹同预先存储起来的指纹模版对比来验证他的真实身份。

指纹识别技术主要包括三大部分:指纹图像采集、指纹预处理、特征提取与匹配。如图1-4所示。

v2-96ef137b1b3ae13a63a626d7d7f84dd1_b.jpg

图1-4 指纹识别流程

指纹作为人类与生俱来的特征,因为其独有的特性而成为具有法律地位的有力证据。一切需要身份确认的场所,都有它的踪影,如金融证券类的ATM指纹终端、指纹保险箱等、IT类的计算机的系统密码验证、网络安全等、安防类的门禁系统等、医疗类的个人医疗档案验证等、福利类的医疗确认、福利确认等,因此指纹识别在许多行业的应用系统中都具有广阔的应用前景。

Matlab在指纹识别中的应用

Matlab是一种高级的计算机语言, 具有独特的数学运算能力是matlab语言最突出的优点。许多在其他语言中描述起来很复杂的问题在matlab语言编程中却只需要一条专用的指令就可以完成。Matlab语言的所有计算都是基于矩阵的,所以matlab中的所有变量都被定义为矩阵, 它是一种解释型语言, 因此几乎没有语法格式上的限制。基于matlab实现指纹图像算法及仿真验证不仅有较高的准确率, 而且减小了仿真难度。

第2章 指纹图像预处理

图像预处理是对原始图像进行的一种前期处理,方便后续的模块识别。无论采用何种方式获取的指纹图像, 都有一部分由于质量原因, 不能被系统直接识别,因此图像的预处理就显得非常有必要。

指纹图像的预处理目的就是将自己感兴趣的目标区域保留下来,去除背景区域和没有用的部分,同时根据指纹目标区域中脊线的结构特征,采取较好的滤波方法,提高指纹脊线清晰度,平滑脊线边缘的毛刺和空洞,抑制图像噪声,保证指纹特征的可靠提取,并使灰度图像转化成黑白的二值图像,最终得到脊线结构清晰的单像素宽的二值图像。本文预处理的主要流程如图2-1所示。

图2-1 预处理流程

图像的分割

图像分割是从一幅图像中按一定规则将一些物体或区域加以分离,划分出我们感兴趣的部分或区域。经过分割后的图像更容易进行进一步的分类、分析和识别处理。图像分割要在指纹二值化和滤波及细化之前进行,如此可以减少计算的冗余量,提高指纹检测速度。

采集到的指纹内容分为目标区域和背景区域。在指纹图像中,由脊线和谷线组成的较清晰的部分,称之为目标区域;没有用的部分我们称之为背景区域。指纹识别中的分割就是将有用的目标区域分割出来,去掉没用的背景区域,以避免背景区域的各种干扰。指纹图像可分为四类区域:背景区、不可恢复区、可恢复区、清晰区,如下图所示。

图2-2 指纹图像的四种区域

2.1.1 图像归一化

对指纹图像进行分割处理,消除剩下的背景区域前,首先要进行图像归一化。

对采集好的指纹图像进行归一化处理,是对指纹灰度图的灰度均值和方差做一次调整,使得不论用什么设备采集的指纹图像都可以有预期的方差和均值,从而屏蔽不必要的噪声。指纹归一化不改变指纹质量,只是方便指纹的后续处理并保证程序运行时收敛加快。


2.1.2 图像分割的方向法

这一方法是基于指纹方向信息的分割方法,它是利用了指纹的脊线和谷线所蕴藏的平行方向信息来分割的,该方法的优点是:适合有污渍的指纹,但缺点是因为依赖脊线的方向,所以脊线不连续时将被识别为背景区域,难以取得满意效果。且计算复杂,处理时间很长,不适宜实际使用。

2.1.3 图像分割的方差法

方差法[5]:传统的分割算法都是基于图像局部灰度方差的分割方法(即方差法),一般地,目标区域中指纹脊和谷的灰度差是较大的,因而其局部灰度方差也较大;对于图像背景区域,方差值则是较小的。基于这一基本特性,可利用图像的局部方差对指纹图像进行分割。该方法的优点:算法简单,计算速度快,如果采集到的指纹质量好,则分割效果不错;缺点:对质量较差的指纹,该方法分割效果不是很理想,如当指纹背景区域有污渍时, 这些区域的方差也比较大,用方差法分割时就不能被有效地分割出去。

改进后的方差法:为了解决上述问题,可以在方差法分割的基础上进行开运算和闭运算操作,该算法继承了方差法的优点且又克服了易受噪声影响的缺陷。

把指纹的图像分成3*3块,将归一化处理后的图像进行分割的具体算法步骤如下:

图像的二值化

2.2.1 方向图

因为许多二值化算法和增强滤波算法都用到了方向图,因此方向图的计算对后续的各种算法都有很大帮助。

指纹图像有着自己独特和固有的特征,其中指纹的方向性、纹理性都很强,可以看作是一个流状模型,该模型可以用方向图来具体表示。

方向图描述了指纹图像中的像素点、小块指纹所在处的脊线或谷线的切线方向,因为指纹图像在一块不大的区域内的指纹方向几近相同,因此在计算中,一般以该点所在的小块方向来代替该像素点的方向。

为方便认知,以指纹图像为模板,画一环形区域来表示指纹,其中,扇形区域中的小块表示指纹被分块后的小块。全局信息如下图2-5所示:

图 2-5 指纹小块模型

方向图计算的基本思想: 在原灰度的指纹图像中计算每小块在每个方向上的统计量, 由这些统计量在每个小块方向上的差异来确定该小块的方向。

2.2.2 指纹图像二值化

二值化就是将图像上的像素点的灰度值设置为0或1,也就是将整个图像呈现出明显的黑白视觉效果。指纹图像中包括目标和背景还有众多噪声,要想从原始的指纹图像中提取出目标,一般用的方法是设定一个阈值T,用T将图像中像素数据分成两部分。

通过求解阈值T,从而把图像f(x,y)分成目标和背景两个区域,其中大于T的像素群为目标区域,小于等于T的像素群为背景区域,阈值的选取原则是:(1)尽可能的多保存图像信息;(2)尽可能的减少噪声。

本文将讨论两种二值化方法,选取其中一个作为效果最好的算法。

2.2.3 静态阈值二值化

静态阈值二值化是根据灰度图像的直方图为整幅图像来确定一个阈值,也可以根据相关经验来确定阈值,阈值的确定一般分为两种:

(1)人工设定阈值:该方案是根据实验或经验设置一个固定的阈值,然后对每个像素按照式来进行二值化处理。

(2)按照直方图确定阈值:利用原灰度图像分部的直方图来确定,设灰度值f取值是0~255之间的整数,f=0为黑色,f=255为白色。

2.2.4 基于方向场的二值化

采集到的指纹图像一般都有比较清晰的方向场,方向场估计得准确与否直接决定了图像二值化算法的效果。

为估计方向场,我们把指纹脊线的走向分为如下8个方向,如图2-6所示:

图 2-6 一个像素处的8个指纹脊线方向

我们先对分割后的图像进行了平均滤波,然后对图像的每一个像素,为确定在该像素处的脊线方向,在以该像素为中心的9*9窗口内,分别计算8个方向上的经过处理后的灰度值,即将图2-6中数字1到8的位置的像素灰度值去除其中最大summax和最小值summin,若满足最大的summax和最小的summin与 4*I(x,y))之和大于 (3*summ/8),则该像素点的脊线方向为summin,否则为summax.确定完脊线方向后再由该方向场对图像进行二值化。

二值化的matlab程序见附录A。结果如下:

图 2-7 指纹二值化

指纹图像的滤波

一个优秀的指纹识别系统不仅需要高的识别准确度,还需要高的识别速度,而影响识别速度的最主要因素就是指纹图像的滤波,而滤波的好坏直接因素是增强滤波的算法,当然跟所使用的软件和硬件也有很大的关系。

图像在当前的采集设备条件下,不可避免的会受到环境和自身因素的影响,指纹图像质量低的主要原因有:(1)存在擦伤或创伤的伤痕所引起的脊线中断或变的不清晰;(2)指纹干燥所引起指纹图像印痕模糊,导致脊线和谷线的对比度比较差;(3)污渍导致指纹图像的脊线或谷线粘连和断裂。

这些图像噪声对后续的指纹提取带来很大的困难,因此必须要在指纹二值化和细化之前进行图像增强滤波,图像增强的目的:减弱原始图像的噪声,增强脊线和谷线的对比度,即修补指纹图像脊线中断裂的部分,去除指纹图像中脊线或谷线的叉连部分,从这些原指纹图像中尽可能多的获取清晰的指纹纹路结构,以保证指纹提取的可靠性。指纹图像的增强滤波有很多的算法,本文就一种图像滤波器算法进行阐述。

上下文滤波器:

该算法也是基于脊线纹路和纹理的方向图的,但是这种算法比较简单且效果良好,使用时用的滤波器要根据具体的某一块指纹脊线的方向从一系列的滤波器中选择一个合理的滤波器来对要进行滤波的指纹进行滤波,其它块的指纹图像滤波则可以通过已用过的滤波器旋转得到。一个基本增强滤波器主要由可将脊线中的断点连接起来的平均滤波器和可将脊线分叉点去除的分离滤波器组成。

指纹图像中脊线的一个周期(即一脊一谷)可以决定增强滤波器的大小,一般地周期T=5,本文中选择5*5的滤波器,平均滤波器在水平方向上的权值可以用下图2-8来表示。

图 2-8 平均滤波器水平方向权值 图 2-9 分离滤波器水平方向权值

(其中A>B>C>=0;P+2Q+2R=0)。

二值化后的指纹图像通过平均滤波器的处理,其每一点灰度值由它临近的二十四个(因为是5*5的滤波器)像素的灰度值决定,因此可以用下式来对f(i,j)(第i行和第j列的灰度值)进行处理[9]:

平均滤波的原理如下:对于脊线中的断点我们采用平均滤波器。断点处脊线的灰度值要比周围的灰度值小,经过平均滤波器的处理,它的灰度值就大约等于周围的灰度值,因此二值化后的指纹中断裂的脊线就会被连起来。

对于脊线中的分叉点我们采用分离滤波器。脊线中叉连点的两端灰度值比中间的要稍微大一些,经过分离滤波器的处理,叉连点处的灰度值就会降下来,脊线中的叉连点就会被去除了。脊线的断裂和叉连点如图2-10所示:

图2-10 断裂与叉连

因此选择增强滤波器的时候必须要具有类似平均滤波器和分离滤波器作用的增强滤波器,分离滤波器的权值可以用下图2-9来表示,并且可以得到一般滤波器的权值如图2-11。

图 2-11 上下文滤波器的权值

参数满足K =A+P,L =B+Q,M =C+R。

上下文滤波器中的平均滤波器起到了去除空洞的作用,分离滤波器起到了去除毛刺的作用。

算法实现的matlab程序见附录A。

结果如图2-12和图2-13:

图 2-12 去除毛刺

图 2-13 去除空洞

图像细化

分割和滤波后的指纹图像再进行二值化处理后,脊线仍然有一定的宽度,指纹识别的匹配是只利用图像的点或线的特征,这些点或者特征只与脊线的走向或者纹理有关系,有一定宽度的二值化图像显得有些多余,所以需要对二值化图像进行细化处理,指纹二值化图像经过细化处理即可得到一个单一像素宽度的脊线,经过上述的细化处理,在后续的指纹特征提取和特征匹配的算法中大大的减少了计算的冗余量和出错率,使得指纹识别的速度和准确度有了很大的提高。

细化目的是在不破坏指纹图像连通性的情况下去除掉多余的信息(即多余的像素点),将二值化的指纹图像的脊线采用逐层剥离的方法,将图像中的指纹脊线细化成单象素宽(实际为保存原图的骨架)。一个好的指纹细化算法必须在不破坏指纹纹理性和连通性的情况下细化成单像素脊线。总体来说,细化算法应满足(1)尽量保持原图像的基本机构特性(如脊线的形态);(2)尽量以脊线的中轴线或者指纹的中心为重心;(3)从指纹脊线的两面对称的删除;(4)保证细化完后的指纹图像是单个像素的;(5)对边缘上噪声不应该敏感;(6)算法简单且实用。

2.4.1 快速细化算法

快速细化算法的原理为先判断出指纹的边缘,并沿着脊线的边缘对称的逐步删除像素,直至删除的剩下单个像素。该算法速度快但不彻底。它的算法为

2.4.2 改进的OPTA算法

常用的传统细化算法还有OPTA算法[10](基于模板的图象细化算法),原理为构造两个模板:一消除模板和一保留模板,将指纹图像二值化后与这两个模板相比较,来决定是否删除该像素,本文研究的是改进后的OPTA算法,改进后的OPTA算法的优点是消除了原OPTA算法算法中两种模板不一致的问题。本算法采用统一的4*4模板,消除模板有八个,保留模板有六个,模板的结构如下图2-15,图2-16,图2-17所示。

图 2-15 OPTA算法的改进模板(4*4)

图 2-16 消除模板(八个)

图2-17 保留模板(六个)

改进后的OPTA算法的细化原理:从图像(类似于4*4的模板中)左上角开始进行,图中的各个像素(如图所示的元素,用P表示)抽取如图2-15所示的

)与图2-15所示的消除模板(八个)相比较, 若都不匹配,则P保留,否则将抽取出来的元素和图2-16的保留模板(六个)相比较,若与其中的一个匹配,则保留P,否则应该将P删除。重复利用以上的操作,将所有图像中的像素值进行比较直至不变为止。此算法是八连通的算法,基本都能够保证单像素的宽度。但该算法却不能使分叉点处彻底的细化,同时也会产生部分毛刺。

Matlab程序见附录A。细化结果图如图2-18:

图2-18 细化图

根据实验发现,该方法处理弓形指纹效果较好,对于环形或螺旋形指纹的中心区域时会出现较多的毛刺和断裂,如下图2-19,这是其的缺点之一,为了很好的使其有实际应用,有待改进。

图 2-19 细化图

本章通过对指纹原图像的分割,二值化,滤波和细化算法的分析比较,得出了一套比较实用和便捷的算法,并通过matlab仿真实现最终的结果,为后续的特征提取和匹配打下了基础。

第3章 图像特征提取和特征匹配

特征点提取

(1)提取指纹的端点和交叉点

端点和交叉点均是指纹图像的两个细节特征,同时在指纹识别的的过程中起着重要的作用,因为识别的首要前提就是找到图像的所有端点和交叉点。先通过一函数对八个邻域的坐标位置进行定义,然后定义另一函数来找出细化后指纹图像的所有端点及交叉点。

将八邻域中的每个点依次两两相减并取其绝对值,后将所有结果加起来,因为端点处是两个点,即和为2时细化图像有端点,和为6时图像特征为交叉点。

运行完上面的和函数的程序后,能把细化图像的的端点和交叉点全部找出。在定义函数的程序中有数组txy,其中t为横坐标,x为纵坐标,y为2时为端点,y为6时为交叉点。

(2)去除图像边缘的端点

可以看出,指纹图像细化的边缘,由于采集仪器不同的关系,因此不可避免的会多出很多的端点,这些端点不仅增加了后续的工作量,还可能导致识别过程中产生错误,所以要把这些边缘的端点都去除,在matlab中这些操作都可以采用一函数来实现,本实验中设计了一cut函数来进行处理。

找出特征点

设置三个函数来找出图像的特征点:

(1)single_point函数

经过去除边缘端点的操作后进一步减少了指纹细化图像中的端点和交叉点的个数。下面就需要找出一些在细化图像中比较独特的端点来作为识别的特征点。在一幅细化的指纹图像中,如果在一个像素(该像素为端点)的周围半径为r(r为像素的个数)的圆内没有任何的端点或者交叉点,那么随着r的逐渐增大,这样的点就会越来越少,因此该点也就越来越独特。于是我们设计了一single_point函数来找出这样独特的点。

(2)walk函数

为了进一步找出特征点,我们还需定义一walk函数,它的主要作用就是判断某一端点在num的距离内是否还有其他的端点。

(3)last1函数

single_point函数和walk函数都是找细化图像特征点的函数,因此可以设计另一个新的last1函数,通过执行

[pxy3,error2]=last1(thin,r,txy,num)

可以找出一端点以r为半径的像素内的任何端点和交叉点且沿着脊线走向的num内没有任何的其他端点和交叉点。

特征点匹配

由上文的函数可知,已经找出了指纹细化图像中的特征点,并画出了一段独特的脊线,在图像中用红色来标示。下面就是指纹匹配[12]的问题了。在此我们设置了三层匹配。

(1)脊线长度匹配

对于上面的函数即可找出细化图像中的特征点和一段脊线,沿着该段脊线走向,每隔五个像素测量一下,看到到原始端点的距离,此段距离由一distance函数得到。

函数结果会得到一数组(内有脊线的长度信息)。如果两幅指纹细化图像中的纹路是相同的,则它们就包含相同的端点和交叉点及用distance函数找出的相同的一段脊,则这两个指纹图像中的长度数组对应的位置比例会基本相等(我们选择的指纹图像大小基本相等,因此该比例选1),因此函数最终定义了一个数f=(sum(abs((d1./d2)-1))),其中若f的值越接近于0,这两幅图像的匹配度就越高,在一定范围的阈值内我们可以认定为匹配。

(2)三角形边长匹配

找到一个指纹细化图像的特征点后,可以找出距离这个端点距离最近的两个端点或者交叉点,与这个指纹图像细化的特征点构成一个三角形,若两幅图像中的边长比例基本相等(原理同上,也选1),则说明这两幅图像匹配,越接近于1说明这两幅指纹图像越匹配。其中设置一find_point函数来找出距离最近的端点或交叉点。

函数最后定义了一个数ff=(sum(abs((dd1./dd2)-1))),因此ff值越接近于0,这两幅指纹图像的匹配度越高,在一定范围的阈值内我们可以认定为匹配。

(3)点类型匹配

找到一个指纹细化图像的特征点后,在该端点周围找到四十个端点或者交叉点,统计在这四十个特征点中端点的个数和交叉点的个数。若有两幅指纹细化图像中的端点所占的比例近似相同,则两幅图像相匹配,越近似,则越相同。函数最终定义了一个数fff=abs(f11-f21)/(f11+f12),所以fff值越接近于0,这两幅指纹图像的匹配度就会越高。我们也设定一阈值,在此阈值内都可以认定为匹配。

本文中取r=8,num=60,经过试验,得到f的阈值为,ff的阈值为,fff的阈值为。即两幅图像的f,ff,fff若均小于阈值,则两幅图匹配;若三个值中有至少一个值大于阈值,则不匹配。验证如下:

一、选择两幅图:和来验证

图 3-1(a) 输出的时间

图 3-1(b) 特征匹配

通过以上的f,ff,fff和阈值的比较说明和匹配,为同一手指的指纹,匹配时间为秒。

二、选择两幅图:和来验证

图 3-2(a) 输出的时间

图 3-2(b) 特征匹配

通过以上的f,ff,fff和阈值的比较说明和不匹配,为同一手指的指纹,匹配时间为秒。

总结与展望

该论文是在前人研究的基础上,参阅了部分资料,并在刘文博老师的指导下认真完成的,文中主要对指纹图像预处理的各个步骤做了较为详细的讨论,并用matlab加以仿真和验证。

论文中的算法基本上能够实现指纹识别的预期目的,但是由于毕业设计的时间较短以及我的知识面的限制,有许多问题的考虑还不全面,有待于进一步完善。

本文中主要对图像预处理进行了分析比较,最后得到了一套比较合适的算法,但通过实验验证可发现比对时间比较长,有待于进一步改进。在指纹特征点的提取和匹配的过程中,均设置了一个函数来实现算法,实现的过程的时间也相对较长,也可以用其他的语言来实现。

参考文献

[1] 李俊山,李旭.数字图像处理.北京:清华大学出版社,

[2] 阮秋琦.数字图像处理学.北京:电子工业出版社,

[3] 祝恩,版建平等.自动指纹识别技术.长沙:国防科技大学出版社,

[4] 查振元、朱华炳.电子门禁系统组成.机电产品开发与创新.2003,(2):13—14

[5] 胡士斌,杨卫平. 指纹图像复合分割算法研究[J]. 计算机工程与应用, 2006,40(12): 71273.

[6] 李建华,马小妹,郭成安,基于方向图的动态闽值指纹图像二值化方法.大连理工大学学报.2002,42(5):626-628

[7] 家锋,唐降龙,赵泉.一个基于特征点匹配的联机指纹鉴别系统.哈尔滨工业大学学报,2002,34(1):132-136

[8] 刘文星,王肇圻,母国光.脊线跟踪及其在细化指纹后处理中的应用[J].光电子,激光,2002,13(2):184~187.

[9] 王玮着,自动指纹识别系统关键技术研究,重庆,重庆大学光电工程学院,2007,80-82

[10] 罗希平,田捷.自动指纹识别的图像增强和细节匹配算法.软件学报,2002-5,13(5): 946-956

[11] 姜腾云.指纹识别门禁系统的matlab仿真实现.江门:五邑大学,2011.

[12] 乔治宏.基于细节结构的指纹特征提取及匹配算法研究.北京:北京工业大学硕士学位论文,2004-5.

附录A 预处理代码
function img = tuxiangyuchuli(path)
M=0;var=0;
I=double(imread(path));
[m,n,p]=size(I);
for x=1:m
    for y=1:n
        M=M+I(x,y);
    end
end
M1=M/(m*n);
for x=1:m
    for y=1:n
        var=var+(I(x,y)-M1).^2;
    end
end
var1=var/(m*n);
for x=1:m
    for y=1:n
        if I(x,y)>=M1
            I(x,y)=150+sqrt(2000*(I(x,y)-M1)/var1);
        else
            I(x,y)=150-sqrt(2000*(M1-I(x,y))/var1);
        end
    end
end
figure, imshow(I(:,:,3)./max(max(I(:,:,3))));title(‘归一化’)
%************************************************************************

for x=1:H;
   for y=1:L;
       aveg=0;var=0;
 for i=1:M;
            for j=1:M;
                aveg=I(i+(x-1)*M,j+(y-1)*M)+aveg;
            end
        end
         aveg1(x,y)=aveg/(M*M);    %计算每一块的方差
        for i=1:M;
            for j=1:M;
                var=(I(i+(x-1)*M,j+(y-1)*M)-aveg1(x,y)).^2+var;
            end
        end
       var1(x,y)=var/(M*M);
   end
end
Gmean=0;Vmean=0;
for x=1:H
    for y=1:L
        Gmean=Gmean+aveg1(x,y);
        Vmean=Vmean+var1(x,y);  
    end
end
Gmean1=Gmean/(H*L);    %所有块的平均值
Vmean1=Vmean/(H*L);    %所有块的方差
gtemp=0;gtotle=0;vtotle=0;vtemp=0;
for x=1:H
    for y=1:L
       if Gmean1>aveg1(x,y)
           gtemp=gtemp+1;
           gtotle=gtotle+aveg1(x,y);
       end
       if Vmean1<var1(x,y)
           vtemp=vtemp+1;
           vtotle=vtotle+var1(x,y);
       end 
    end
end
G1=gtotle/gtemp;V1=vtotle/vtemp;  
gtemp1=0;gtotle1=0;vtotle1=0;vtemp1=0;
for x=1:H
    for y=1:L
       if G1<aveg1(x,y)
           gtemp1=gtemp1-1;
           gtotle1=gtotle1+aveg1(x,y);
       end
       if 0<var1(x,y)<V1
           vtemp1=vtemp1+1;
           vtotle1=vtotle1+var1(x,y);
       end 
    end
end
G2=gtotle1/gtemp1;V2=vtotle1/vtemp1; 
e=zeros(H,L);
for x=1:H
   for y=1:L
       if aveg1(x,y)>G2 && var1(x,y)<V2
           e(x,y)=1;
       end
       if aveg1(x,y)< G1-100 && var1(x,y)< V2
           e(x,y)=1;
       end
   end
end 
for x=2:H-1
    for y=2:L-1
        if e(x,y)==1
            if e(x-1,y) + e(x-1,y+1) +e(x,y+1) + e(x+1,y+1) + e(x+1,y) + e(x+1,y-1) + e(x,y-1) + e(x-1,y-1) <=4
                e(x,y)=0;
            end
        end
    end
end  
Icc = ones(m,n);
for x=1:H
   for y=1:L
       if  e(x,y)==1
          for i=1:M
            for j=1:M
                I(i+(x-1)*M,j+(y-1)*M)=G1;
                Icc(i+(x-1)*M,j+(y-1)*M)=0;
            end
          end 
       end
   end
end
figure, imshow(I(:,:,3)./max(max(I(:,:,3))));title('分割');
%************************************************************************
temp=(1/9)*[1 1 1;1 1 1;1 1 1];    % 模板系数、均值滤波
 Im=double(I);
 In=zeros(m,n);
for a=2:m-1;
    for b=2:n-1;
In(a,b)=Im(a-1,b-1)*temp(1,1)+Im(a-1,b)*temp(1,2)+Im(a-1,b+1)*temp(1,3)+Im(a,b-1)*temp(2,1)+Im(a,b)*temp(2,2)+Im(a,b+1)*temp(2,3)+Im(a+1,b-1)*temp(3,1)+Im(a+1,b)*temp(3,2)+Im(a+1,b+1)*temp(3,3);
    end
end
I=In;
Im=zeros(m,n);
for x=5:m-5;
   for y=5:n-5;
    sum1=I(x,y-4)+I(x,y-2)+I(x,y+2)+I(x,y+4);
    sum2=I(x-2,y+4)+I(x-1,y+2)+I(x+1,y-2)+I(x+2,y-4);
    sum3=I(x-2,y+2)+I(x-4,y+4)+I(x+2,y-2)+I(x+4,y-4);
    sum4=I(x-2,y+1)+I(x-4,y+2)+I(x+2,y-1)+I(x+4,y-2);
    sum5=I(x-2,y)+I(x-4,y)+I(x+2,y)+I(x+4,y);
    sum6=I(x-4,y-2)+I(x-2,y-1)+I(x+2,y+1)+I(x+4,y+2);
    sum7=I(x-4,y-4)+I(x-2,y-2)+I(x+2,y+2)+I(x+4,y+4);
    sum8=I(x-2,y-4)+I(x-1,y-2)+I(x+1,y+2)+I(x+2,y+4);
    sumi=[sum1,sum2,sum3,sum4,sum5,sum6,sum7,sum8];
    summax=max(sumi);
    summin=min(sumi);
     summ=sum(sumi);
     b=summ/8;
     if (summax+summin+ 4*I(x,y))> (3*summ/8)            
            sumf = summin;
         else
            sumf =summax;
         end
         if   sumf > b
           Im(x,y)=128;
        else
            Im(x,y)=255;
         end
   end
end 
for i=1:m
     for j =1:n
         Icc(i,j)=Icc(i,j)*Im(i,j);
     end
end
 for i=1:m
     for j =1:n
         if (Icc(i,j)==128)
             Icc(i,j)=0;
         else
             Icc(i,j)=1;
         end;
     end
 end
figure,imshow(double(Icc));title('二值化');
%************************************************************************
u=Icc;
[m,n]=size(u)    %去空洞和毛刺
for x=2:m-1
for y=2:n-1
if u(x,y)==0
if u(x,y-1)+u(x-1,y)+u(x,y+1)+u(x+1,y)>=3
u(x,y)=1;
end
else u(x,y)=u(x,y);
end
end
end
figure,imshow(u)   %title('去毛刺')
for a=2:m-1
for b=2:n-1
if u(a,b)==1
if abs(u(a,b+1)-u(a-1,b+1))+abs(u(a-1,b+1)-u(a-1,b))+abs(u(a-1,b)-u(a-1,b-1))+abs(u(a-1,b-1)-u(a,b-1))+abs(u(a,b-1)-u(a+1,b-1))+abs(u(a+1,b-1)-u(a+1,b))+abs(u(a+1,b)-u(a+1,b+1))+abs(u(a+1,b+1)-u(a,b+1))~=1    %去空洞
if(u(a,b+1)+u(a-1,b+1)+u(a-1,b))*(u(a,b-1)+u(a+1,b-1)+u(a+1,b))+(u(a-1,b)+u(a-1,b-1)+u(a,b-1))*(u(a+1,b)+u(a+1,b+1)+u(a,b+1))==0     %去毛刺
u(a,b)=0;
end
end
end
end
end
figure,imshow(u)     %title('去空洞')
%*************************************************************************
v=~u;
se=strel('square',3);
fo=imopen(v,se);
v=imclose(fo,se);    %对图像开操作和闭操作
img=bwmorph(v,'thin',Inf);    %对图像进行细化
figure,imshow(img)
title('细化图')
附录B 特征点提取代码
function j = P (img, x, y, i)
switch (i)
    case {1, 9}
        j = img(x+1, y);
    case 2
        j = img(x + 1, y-1);
    case 3
        j = img(x, y - 1);
    case 4
        j = img(x - 1, y - 1);
    case 5
        j = img(x - 1, y);
    case 6
        j = img(x - 1, y + 1);
    case 7
        j = img(x, y + 1);
    case 8
        j = img(x + 1, y + 1);
end
%point函数
function txy=point(thin)
count = 1;
txy(count, :) = [0,0,0];
siz=min(size(thin,1),size(thin,2));
for x=40:siz - 40
    for y=40:siz - 40
        if (thin(y, x) )
            CN = 0;
            for i = 1:8
                CN = CN + abs (P(thin, y, x, i) - P(thin, y, x, i + 1));
            end         
            if (CN == 2) 
                txy(count, :) = [x, y,2];
                count = count + 1;
            end
            if (CN == 6)
                txy(count, :) = [x, y,6];
                count = count + 1;
            end
        end
    end 
end 
for i=1:count - 1
    x(i) =txy(i, 1);
    y(i)= txy(i, 2);
end 
imshow(double(thin));
hold on;
plot(x,y,'.');
%cut函数
function txy=cut(thin,txy)
s(8,8)=0;
delta(8,8)=0;
n=size(txy,1);
for i=1:8
    for j=1:8
        mp{i,j}=thin(1+31*(i-1):31+31*(i-1),1+31*(j-1):31+31*(j-1));
        s(i,j)=sum(sum(mp{i,j}))/(31*31);
        mp{i,j}=(mp{i,j}-s(i,j)).^2;
        delta(i,j)=sum(sum(mp{i,j}));
        if delta(i,j)<=70
            for k=1:n
if (txy(k,1)>=1+31*(i-1)&&txy(k,1)<=31+31*(i-1)&&txy(k,2)>=1+31*(j-1)&&txy(k,2)<=31+31*(j-1)&&txy(k,3)==2)
                    txy(k,:)=[0,0,0];
                end
            end
        end           
    end
end
txy=txy(find(txy(:,1)),:);
plot(txy(:,1),txy(:,2),'ro');
附录C 图像特征点代码
%single_point函数
function [pxy2,error]=single_point(txy,r)
error=0;
x=txy(:,1);
y=txy(:,2);
n=length(x);
d(1:n,1:n)=0;
for j=1:n
    for i=1:n
        if (i~=j)
        d(i,j)=sqrt((x(i)-x(j))^2+(y(i)-y(j))^2);
        else
            d(i,j)=2*r;
        end
    end
end
[a,b]=min(d);
c=find(a>r);
pxy2=txy(c,:);
pxy2=pxy2(find(pxy2(:,3)==2),:);
t=size(pxy2,1);
if t==0
    error=1
else  
    plot(x,y,'b.');   
    hold on
    plot(pxy2(:,1),pxy2(:,2),'r.');  
end
%walk函数
function [error,a,b]=walk(thin,x0,y0,num) 
error=0;
thin(y0,x0)=0;
t1=0;
for n=1:num
   if error==1
            break;
        else 
    x=x0;
    y=y0;  
    for x=x0-1:x0+1
        if error==1
            break;
        else
        for y=y0-1:y0+1
           t1=sum(sum(thin(y0-1:y0+1,x0-1:x0+1)));
           if (t1==0||t1>=2)
               error=1;
               a=x0;
               b=y0;
            break;
        else
            if (thin(y,x)==1&&(x-x0)^2+(y-y0)^2~=0)
                if  (t1>=2 )
                    error=1;
                break ;
                else
                thin(y,x)=0;
                x0=x;
                y0=y;
                a=x0;
                b=y0;
                plot(x0,y0,'r.')
                end
            end
        end
        end
        end
    end
    end
end
%last1函数
function [pxy3,error2]=last1(thin,r,txy,num)
error=0;
[pxy2,error]=single_point(txy,r);
n=size(pxy2,1);
l=1;
error2=0;
for i=1:n
    [error,a,b]=walk(thin,pxy2(i,1),pxy2(i,2),num);
    if error~=1
     pxy3(l,1)= pxy2(i,1);
     pxy3(l,2)= pxy2(i,2);
     pxy3(l,3)= pxy2(i,3);
     l=l+1;
     error2=0;
     plot(pxy2(i,1) ,pxy2(i,2),'r+');       
    end
end
附录D 特征点匹配代码
%distance函数程序
function d=distance(x0,y0,num,thin)
num2=fix(num/5);
for i=1:num2
    [error,a,b]=walk(thin,x0,y0,5*i);
    if error~=1
        d(i)=sqrt((a-x0)^2+(b-y0)^2);
    else 
        break;
    end
end
%find_point函数
function pxy=find_point(x0,y0,txy,num)
x=txy(:,1);
y=txy(:,2);
n=length(x);
l(1,n)=0;
lnn=1;
pxy(num,:)=[0,0,0];
for i=1:n
    l(i)=sqrt((x(i)-x0)^2+(y(i)-y0)^2);
end
ll=sort(l);
for i=1:num 
xiao=ll(i+lnn);
nn=find(l==xiao);
lnn=length(nn);   
pxy(i,:)=[x(nn(1)),y(nn(1)),txy(nn(1),3)];
end
plot(x0,y0,'bo');
x0;
y0;
hold on
plot(pxy(:,1),pxy(:,2),'ro');
%主函数main
close all;
tic
clear;
thin1=tuxiangyuchuli('');
thin2=tuxiangyuchuli('');
figure;
txy1=point(thin1);
txy2=point(thin2);
[w1,txy1]=guanghua(thin1,txy1);
[w2,txy2]=guanghua(thin2,txy2);
thin1=w1;
thin2=w2;
txy1=cut(thin1,txy1);
txy2=cut(thin2,txy2);
[pxy31,error2]=last1(thin1,8,txy1,60)
[pxy32,error2]=last1(thin2,8,txy2,60)
error=1;   
num=20;
cxy1=pxy31;
   cxy2=pxy32;
   d1=distance(cxy1(1,1),cxy1(1,2),num,thin1);
   d2=distance(cxy2(1,1),cxy2(1,2),num,thin2);
  f=(sum(abs((d1./d2)-1)));
  if ff<=
      error=0;
  else
      error=1;
  end  
   c11=find_point(cxy1(1,1),cxy1(1,2),txy1,1);
    c12=find_point(cxy1(1,1),cxy1(1,2),txy1,2);
    c21=find_point(cxy2(1,1),cxy2(1,2),txy2,1);
    c22=find_point(cxy2(1,1),cxy2(1,2),txy2,2);
    cxy1(2,:)=c11;
    cxy1(3,:)=c12(2,:);
    cxy2(2,:)=c21;
    cxy2(3,:)=c22(2,:);
    x11=cxy1(1,1);  y11=cxy1(1,2);
    x12=cxy1(2,1);  y12=cxy1(2,2);
    x13=cxy1(3,1);  y13=cxy1(3,2);
    x21=cxy2(1,1);  y21=cxy2(1,2);
    x22=cxy2(2,1);  y22=cxy2(2,2);
    x23=cxy2(3,1);  y23=cxy2(3,2);
    dd1(1)=juli(x11,y11,x12,y12);
    dd1(2)=juli(x12,y12,x13,y13);
    dd1(3)=juli(x13,y13,x11,y11);
    dd2(1)=juli(x21,y21,x22,y22);
    dd2(2)=juli(x22,y22,x23,y23);
    dd2(3)=juli(x23,y23,x21,y21);
    ff=(sum(abs((dd1./dd2)-1)))
    if ff<=1
        error=0;
    else 
        error=1;
    end
    cxy1(2:41,:)=find_point(pxy31(1,1),pxy31(1,2),txy1,40);
    cxy2(2:41,:)=find_point(pxy32(1,1),pxy32(1,2),txy2,40);
    f11=length(find(cxy1(:,3)==2));
    f12=length(find(cxy1(:,3)==6));
    f21=length(find(cxy2(:,3)==2));
    f22=length(find(cxy2(:,3)==6));
    fff=abs(f11-f21)/(f11+f12)
    toc

  • 1
    点赞
  • 0
    评论
  • 6
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值