基于matlab的指纹图像处理、脊线增强、脊线分割、脊线细化、细节点检测和细节点验证

news/2024/11/20 21:37:14/

需求分析


对于指纹的特征提取包含几个步骤,脊线增强、脊线分割、脊线细化、细节点检测和细节点验证,本次大作业需要针对已经增强的指纹图片进行后续几个步骤,通过多种形态学算法进行分割、细化、细化后处理,找到其中的端点和分叉点,而指纹周边的伪细节点需要被去除。

本次作业有两张图片需要进行处理,如图 2 所示,分别称为图片 1 和图片 2。

图 1 指纹特征提取步骤

图片 1 (b)图片 2 图 2 两张待处理指纹

二、算法设计


2.1 脊线分割


脊线分割的目的是使增强后的指纹图像脊线更加清晰、饱满、平滑。首先使用函数 𝑖𝑚𝑏𝑖𝑛𝑎𝑟𝑖𝑧𝑒对图像进行二值化处理。选择参数 0.5,图片 1 能得到较好的二值化效果,而图 片 2 会出现指纹背景与脊线同色的情况,影响之后的细化操作,因此需要先通过灰度值范围 将底色去除,再进行二值化,会呈现较好的效果。

之后的形态学处理使用𝑖𝑚𝑜𝑝𝑒𝑛(𝐼, 𝑠𝑒)函数做开运算,其中运算结构𝑠𝑒为边长为 2 个像素 的正方形,开运算能够对指纹轮廓进行一定程度的平滑,连接一些在二值化之后出现的脊线 断裂1;对于图像中的孤岛,使用函数𝑏𝑤𝑎𝑟𝑒𝑎𝑜𝑝𝑒𝑛,去除一定像素大小以内的连通域,可以 对原始图片和反色图片各做一次,分别去除脊线空洞和白背景上的孤岛。

2.2 脊线细化


使用函数𝑏𝑤𝑚𝑜𝑟𝑝ℎ(𝐼, ′ 𝑡ℎ𝑖𝑛 ′ , 𝑁)对指纹进行细化,其中𝑁为细化操作的次数,可以设为 𝑖𝑛𝑓,即细化至图像不变化为止。

脊线细化后可能出现脊线断裂、桥接、短线或毛刺等问题,如图 3 所示。由于在 2.1 中 去除了背景中孤岛,细化后未产生短线。对于不希望的桥接,可以通过𝑏𝑤ℎ𝑖𝑡𝑚𝑖𝑠𝑠(𝐼,𝐵1,𝐵2) 函数,对指纹图片进行“击中与否”变换,其中 B1 是感兴趣的结构体,B2 是其互补结构, 在本例中,即桥接部分主要形状,𝐻𝑖𝑡 𝑜𝑟 𝑚𝑖𝑠𝑠返回的是图中相同结构体的中心点,之后再手 动改变周围像素值,实现去除桥接的目的。脊线的断裂可以通过𝑖𝑚𝑒𝑟𝑜𝑑𝑒做腐蚀2实现,腐蚀 后的图像脊线会加粗,再细化即可。

对于脊线上的毛刺,需要进行剪枝,借鉴老师的示例程序编写剪枝算法𝑝𝑟𝑢𝑛𝑖𝑛𝑔,可以 设定剪枝长度(剪枝次数)𝑛,首先定义一些毛刺结构,使用𝑏𝑤ℎ𝑖𝑡𝑚𝑖𝑠𝑠寻找具有相同结构的 毛刺,找到毛刺位置后对获得的ℎ𝑖𝑡 𝑜𝑟 𝑚𝑖𝑠𝑠图片做膨胀,从而在原图上去除这些毛刺,也能 使脊线更加平滑。

桥接 (b)断裂 (c)毛刺图 3 细化后图片待处理问题

2.3 细节点检测


指纹细节包括端点和分叉点,对于两种类型细节点的寻找可以通过下述算法统一实现。 对于像素点𝑃,其类型由交叉数𝑐𝑛(𝑝)决定。

其中𝑓(𝑝𝑖)表示𝑝𝑖处的像素值,如图 4 所示,遍历图像,对每个脊线像素的 8 邻域像素做计 算,端点和交叉点的对于特征图如图 4(b)(d),端点的cn(𝑝) = 1,交叉点cn(𝑝) = 3,其他的 cn(𝑝)值忽视。

程序中找到的端点用绿色框标记,交叉点用红色方框标记。

开运算针对图片中的白色底色进行操作,因此可以连接灰度值为 0 的黑色脊线部分

与脚注 1 同理,对白色背景做腐蚀,可以连接断裂脊线

邻域 (b)端点 (c)其他 (d)交叉点图 4 像素 8 邻域特征与细节点类型

2.4 伪细节点去除


本次作业中,定义指纹边缘端点为找到的伪细节点,因此去除边缘点需要确定边缘。使用𝑛𝑙𝑓𝑖𝑙𝑡𝑒𝑟计算全图 3*3 的局部方差3,非指纹区域值为 0,通过此法可以大致画出边缘形状,如图 5,在此范围内的细节端点统一被去除。

图 5 找到的指纹边缘

三、实验结果


图片 1 输出

该算法效率较低,可以使用小作业中实现的积分图方法计算局部方差,速度较快

值化 (b)形态学处理

细化 (d)细化处理

细节点检测 (f)去除伪细节点

图片 2 输出

值化 (b)形态学处理

细化 (d)细化后处理

细节点检测 (f)去除伪细节点

完整代码+报告:

https://download.csdn.net/download/qq_38735017/87386312


http://www.ppmy.cn/news/12500.html

相关文章

Swift return陷阱

return后还会执行后边的代码 我们来看下边一个例子: func test() -> Bool {print("1 test")return falseprint("2 test") }func test2() {print("1 test2")returnprint("2 test2") }test() test2()输出: 1…

【数据结构】保姆级单链表教程(概念、分类与实现)

目录 🍊前言🍊: 🍈一、链表概述🍈: 1.链表的概念及结构: 2.链表存在的意义: 🍓二、链表的分类🍓: 🥝三、单链表的实现&#x1f…

寻找两个正序数组的中位数

题目 给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。 算法的时间复杂度应该为 O(log (m+n)) 。 示例 1: 输入:nums1 = [1,3], nums2 = [2] 输出:2.00000 解释:合并数组 = [1,2,3] ,中位数 2 示例 2: 输入…

Java使用Zxing二维码生成

目录 1、二维码简介 二维码纠错级别 2、ZXing简介 3、示例 3.1 搭建一个maven项目,引入Zxing依赖包 3.2 创建QrCodeUtil.java 类 1、二维码简介 二维条形码是用某种特定的几何图形按一定规律在平面(二维方向上)分布的黑白相间的图形记录…

react受控组件和非受控组件区别

一、受控组件 在HTML中,表单元素的标签、、等的值改变通常是根据用户输入进行更新。 在React中,可变状态通常保存在组件的状态属性中,并且只能使用 setState() 进行更新,而呈现表单的React组件也控制着在后续用户输入时该表单中发…

Python学习笔记-PyQt6消息窗

对话框是界面编程中重要的窗体,一般用于提示或者一些其他特定操作。一、使用QDialog显示通用消息框直接使用QDialog类,可以及通过对话框进行通用对话框显示,亦可以通过自定义设置自己需要的对话框。# _*_ coding:utf-8 _*_import sysfrom PyQ…

Linux 中断子系统(八):中断处理流程

1、上层中断处理 系统初始化时,已经建立起 硬件中断号 和 软件中断号的 映射表。 中断注册时,我们需要先从设备树中获取硬件中断号,然后调用 API 将硬件中断号转换为软件中断号,根据软件终端号 irq 找到对应的 irq_desc,并将中断处理函数添加到 irq_desc 中(也就是 irq…

【C语言进阶】使用“动态内存文件处理”实现进阶版通讯录

目录 前言 改进后的优势 一、test.c 二、contact.h 三、contact.c 1.加载通讯录函数load_contact 2、将数据保存到文件save_contact函数 3、初始化通讯录init_contact函数 4、扩容check_full函数 5、销毁通讯录destory_contact函数 6、其余函数 四、完整源码 总结 …