竞赛 python opencv 深度学习 指纹识别算法实现

1 前言

🔥 优质竞赛项目系列,今天要分享的是

🚩 python opencv 深度学习 指纹识别算法实现

🥇学长这里给一个题目综合评分(每项满分5分)

  • 难度系数:3分
  • 工作量:4分
  • 创新点:4分

该项目较为新颖,适合作为竞赛课题方向,学长非常推荐!

🧿 更多资料, 项目分享:

https://gitee.com/dancheng-senior/postgraduate

2 指纹识别方式

目前市面上有两种指纹识别,分别是光学式和电容式指纹识别。

2.1 电容式指纹识别

电容式指纹识别要比光学式的复杂得多,其原理是将压力感测、电容感测、热感测等感测器整合于一块芯片中,当指纹按压芯片表面时,内部电容感测器会根据指纹波峰与波谷而产生的电荷差(或是温差),形成指纹影像,再通过与算法内部的指纹库进行匹配,从而完成指纹识别。

在这里插入图片描述

电容式指纹识别技术较为复杂,对技术研发和积累有较高要求,并且涉及大量专利,算法得实现也相对困难,所以目前全球只有少数公司能在这方面提供领先的技术产品。

2.2 光学式指纹识别

然后是光学式指纹识别,大家常见的指纹考勤机就是光学式指纹识别。

这类光学式指纹识别主要包括4个方面功能

  • 1.指纹模块负责采集指纹图像。
  • 2.数字信号处理器主要把采集到的指纹图像转化为数字信号。
  • 3.微控制器是整个系统的控制单元,在这里将进行指纹的验证以及输出指令。
  • 4.液晶显示器将输出指纹验证结果。

当我们把手指放在指纹考勤机上时,通过镜面反射原理,指纹模块就会采集指纹图像

在这里插入图片描述

接着指纹图像就会被数字信号处理器转换成数字信号

在这里插入图片描述

然后通过微控制器将数字信号与指纹库里的指纹进行匹配,匹配结果将通过液晶显示器显示出来。这就是光学式指纹识别的工作原理。

电容式与光学式指纹识别主要在指纹的采集方式上拥有较大差异,而在指纹的验证过程中则基本类似。然而因为电容式指纹识别拥有体积小、适用性广的优点,已经有越来越多的设备采用电容式指纹识别,未来的主流将是电容式指纹识别。

3 指纹识别算法实现

3.1 指纹识别算法流程

在这里插入图片描述

3.2 指纹图像预处理

  • 1.图像归一化
  • 2.图像分割
  • 3.图像二值化
  • 4.细化

几个步骤 当然有一些算法为了追求极致,中间还利用了增强、多重滤波等方式,但最根本的目的都是为了在细化之后保留指纹信息并且方便后续处理。

预处理之后是特征点的提取,也就是找到指纹图像当中有价值,具有唯一性和不变性的信息。主要特征点有端点、分叉点几类,在提取部分除了简单的遍历检索确认之外,还有比较重要的一步是伪特征点的去除,主要是针对图像不清晰、不完整导致的断点和边缘端点等。

最后一步是特征点的匹配,将指纹库中的指纹信息与提取的目标图像特征点进行对比。主流算法是以指纹中心点为依据,根据特征点所在的角度及距离,确认其所在位置,根据匹配度计算是否是同一手指的指纹。

3.3 指纹图像目标提取

指纹图像目标提取主要是将指纹图片中提取出来,也叫做指纹图像分割。

图片的前景通过观察可知是由条状或者圆形的一些组成,而底图其他部分只是一个均匀的底色而已。

我们使用非常简单的手段,基于局部梯度就可以很容易实现我们的目标。

方差梯度法提取指纹:

指纹图像通常由前景区域(包含有指纹的脊线和谷线)和背景区域这两部分组成。一般来说,在指纹图像的前景区域中,指纹的脊线和谷线的灰度差是较大的,因而其灰度统计特性局部灰度方差很大;而在指纹图像的背景区域中,两者的方差是很小的。基于这一特性,可以利用指纹图像的局部方差来进行分割。因此,这种方法也被称为方差梯度法。

的灰度平均值 M和方差 Var计算方法:
在这里插入图片描述

提取前的指纹图像:

在这里插入图片描述

提取后的指纹图像:
在这里插入图片描述

可以看到,学长做的还有些噪点,但是也很好解决,做一次形态学操作即可:

在这里插入图片描述

这样噪点就去除了。

3.4 指纹图像增强

在这里插入图片描述

3.5 指纹特征提取

人体指纹的特征可以反映在给定的人类群体里来自不同手指的指纹之间相似的程度。

指纹的特征信息很多,所有的这些指纹特征信息构成了庞大的指纹特征集合。

指纹的细节特征主要指的是纹线端点(RidgeEnding)和纹线分叉点(RidgeBifurcation)。

纹线端点指的是纹线突然结束的位置,而纹线分叉点则是指纹线一分为二的位置。

大量的统计结果表明,使用这两类特征点就足以描述指纹的唯一性。

在这里插入图片描述

Minutia Cylinder-Code (MCC) ,该算法是非常著名的指纹特征识提取算法,

第一次发表在:IEEE tPAMI

Minutia Cylinder-Code: a new representation and matching technique for
fingerprint recognition", IEEE tPAMI 2010

  • MCC提出了一种基于三维数据结构的圆柱编码算法,其从细节的距离和角度出发,构造了圆柱编码
  • 为一种多级的指纹匹配方法,其不仅使用了细节点特征也使用了方向场等特征
  • 特征视为一种局部结构,也是3D结构

在这里插入图片描述

部分实现代码:

# Compute the cell coordinates of a generic local structure# 计算
​    mcc_radius = 70
​    mcc_size = 16
​    

g = 2 * mcc_radius / mcc_size
x = np.arange(mcc_size)*g - (mcc_size/2)*g + g/2
y = x[..., np.newaxis]
iy, ix = np.nonzero(x**2 + y**2 <= mcc_radius**2)
ref_cell_coords = np.column_stack((x[ix], x[iy]))
    mcc_sigma_s = 7.0
    mcc_tau_psi = 400.0
    mcc_mu_psi = 1e-2
    

def Gs(t_sqr):
    """Gaussian function with zero mean and mcc_sigma_s standard deviation, see eq. (7) in MCC paper"""
    return np.exp(-0.5 * t_sqr / (mcc_sigma_s**2)) / (math.tau**0.5 * mcc_sigma_s)

def Psi(v):
    """Sigmoid function that limits the contribution of dense minutiae clusters, see eq. (4)-(5) in MCC paper"""
    return 1. / (1. + np.exp(-mcc_tau_psi * (v - mcc_mu_psi)))


​    
​    
​    
​    # n: number of minutiae# c: number of cells in a local structure
​    

xyd = np.array([(x,y,d) for x,y,_,d in valid_minutiae]) # matrix with all minutiae coordinates and directions (n x 3)

# rot: n x 2 x 2 (rotation matrix for each minutia)

d_cos, d_sin = np.cos(xyd[:,2]).reshape((-1,1,1)), np.sin(xyd[:,2]).reshape((-1,1,1))
rot = np.block([[d_cos, d_sin], [-d_sin, d_cos]])

# rot@ref_cell_coords.T : n x 2 x c

# xy : n x 2

xy = xyd[:,:2]

# cell_coords: n x c x 2 (cell coordinates for each local structure)

cell_coords = np.transpose(rot@ref_cell_coords.T + xy[:,:,np.newaxis],[0,2,1])

# cell_coords[:,:,np.newaxis,:]      :  n x c  x 1 x 2

# xy                                 : (1 x 1) x n x 2

# cell_coords[:,:,np.newaxis,:] - xy :  n x c  x n x 2

# dists: n x c x n (for each cell of each local structure, the distance from all minutiae)

dists = np.sum((cell_coords[:,:,np.newaxis,:] - xy)**2, -1)

# cs : n x c x n (the spatial contribution of each minutia to each cell of each local structure)

cs = Gs(dists)
diag_indices = np.arange(cs.shape[0])
cs[diag_indices,:,diag_indices] = 0 # remove the contribution of each minutia to its own cells

# local_structures : n x c (cell values for each local structure)

local_structures = Psi(np.sum(cs, -1))

3.6 指纹识别结果

提取特征后,剩下的任务就是对特征进行分类了,可以使用的算法就很多了,比如svm,决策树、神经网络,都可以

在这里插入图片描述

4 整体效果

在这里插入图片描述

5 最后

🧿 更多资料, 项目分享:

https://gitee.com/dancheng-senior/postgraduate

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/484952.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何使用OpenCV扫描图像、查找表和时间测量

返回&#xff1a;OpenCV系列文章目录&#xff08;持续更新中......&#xff09; 上一篇&#xff1a;OpenCV4.9.0开源计算机视觉库核心功能&#xff08;核心模块&#xff09; ​ 编辑 目标 我们将寻求以下问题的答案&#xff1a; 如何浏览图像的每个像素&#xff1f;OpenCV 矩…

SVN的branch分支合并完要不要删除

在 SVN 中&#xff0c;当一个分支&#xff08;branch&#xff09;的工作已经完成并成功合并回主干&#xff08;trunk&#xff09;后&#xff0c;通常不需要立即删除该分支。保留分支可以有一些好处&#xff0c;例如&#xff1a; 历史记录和追溯&#xff1a;保留分支可以帮助团…

pycharm搭建新的解释器及删除处理

目录 1.创建虚拟环境 个人实际操作&#xff1a; 对于“继承全局站点包”&#xff1a; 2.创建一个新项目 3.删除操作 &#xff08;1&#xff09;删除解释器 &#xff08;2&#xff09;删除新建项目 1.创建虚拟环境 Pycharm官方文档说明网址&#xff1a; Configure a virt…

StringRedisTemplate

Redis快速入门 3.2.3.StringRedisTemplate 为了节省内存空间&#xff0c;我们可以不使用JSON序列化器来处理value&#xff0c;而是统一使用String序列化器&#xff0c;要求只能存储String类型的key和value。当需要存储Java对象时&#xff0c;手动完成对象的序列化和反序列化。…

芯片工程系列(5)2.5D 3D封装

0 英语缩写 硅通孔&#xff08;Through Silicon Via&#xff0c;TSV&#xff09;硅中介层&#xff08;Silicon Interposer&#xff09;物理气象沉淀法&#xff08;Physical Vapor Deposition&#xff0c;PVD&#xff09;DRIE、CVD、PVD、CMP等设备CoWoS&#xff08;Chip on Wa…

SpringMVC | SpringMVC中的 “文件上传和下载”

目录: 一、文件上传1.1 文件上传“概述”1.2 文件上传“具体配置” :“前端”中配置“文件上传” ( type“file” 满足3个条件 )“后端”中配置“文件上传” ( 配置id为“CommonsMultipartResolver”的bean 配置“文件上传”的“约束条件” 通过“MultipartFile接口”参数接…

【C语言数据结构】排序

1.排序的概念 在深入研究各个排序算法之前&#xff0c;首先&#xff0c;我们要对排序有个大概的了解&#xff0c;即与排序相关的一些概念 Q&#xff1a;什么是排序&#xff1f; A&#xff1a;所谓排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小…

Rust egui(3) 增加多个tab

话说不知道咋写&#xff0c;要不直接上git patch吧。代码都是移植的官方demo&#xff0c;核心改动就是把原来的line_demo换成了plot_demo&#xff0c;里面实现多个ui&#xff0c;然后点击tab标题会切换不同的ui。 如下图&#xff0c;Lines和Markers两个不同的标签对应不同的ui。…

pytest框架的封装以及用例管理框架

pytest框架的封装以及用例管理框架 公共类统一封装requests_util02.pytest_api01.py 自动化测试的基础自动化测试的介入点自动化测试和手工测试占比自动化实施过程 pytest元素定位元素定位查找元素定位的方式通过 ID 定位通过 Name 定位通过 Class Name 定位通过 Tag Name 定位…

数据结构面试常见问题之串的模式匹配(KMP算法)系列-简单解决方案

&#x1f600;前言 字符串匹配是计算机科学中一个常见的问题&#xff0c;指的是在一个长字符串中查找一个短字符串的出现位置。在文本编辑、生物信息学、数据挖掘等领域都有着广泛的应用。 本文将介绍 KMP 算法&#xff0c;一种用于解决字符串匹配问题的经典算法。KMP 算法可以…

鸿蒙网络开发学习:【ylong_http】

简介 ylong_http 构建了完整的 HTTP 能力&#xff0c;支持用户使用 HTTP 能力完成通信场景的需求。 ylong_http 使用 Rust 编写&#xff0c;为 OpenHarmony 的 Rust 能力构筑提供支持。 ylong_http 在 OpenHarmony 中的位置 ylong_http 向 OpenHarmony 系统服务层中的网络协…

flutter实现视频播放器,可根据指定视频地址播放、设置声音,进度条拖动,下载等

需要装依赖&#xff1a; gallery_saver: ^2.3.2video_player: ^2.8.3 AndroidManifest.xml <uses-permission android:name"android.permission.INTERNET"/> 实现代码 import dart:async; import dart:io;import package:flutter/material.dart; import pa…

深入理解栈和队列(二):队列

个人主页&#xff1a;17_Kevin-CSDN博客 专栏&#xff1a;《数据结构》 一、队列的概念和结构 队列是只允许在一端进行插入数据操作&#xff0c;在另一端进行删除数据操作的特殊线性表&#xff0c;队列具有先进先出 FIFO(First In First Out) 入队列&#xff1a;进行插入操作的…

OC对象 - 关联对象(如何给分类添加成员变量)

文章目录 OC对象 - 关联对象&#xff08;如何给分类添加成员变量&#xff09;1. 基本使用1.1 提供的API1.1.1 添加关联对象1.1.2 获得关联对象1.1.3 移除所有关联对象1.1.3 修饰符 1.2 使用方法1.2 Key的常见用法1.2.1 使用的get方法的selecor作为key1.2.2 使用指针的地址作为k…

【Node.js】zlib

gzip 和 deflate 的基本使用 const zlib require("zlib"); const fs require(fs)// 压缩 1. createGzip .gz 2. createDeflate .deflate // const readStream fs.createReadStream(index.txt) // const writeStream fs.createWriteStream(index.txt.gz) // rea…

Python Flask 自定义404错误

from flask import Flask, abort, make_response, request, render_templateapp Flask(__name__)# 重定向到百度 app.route(/index, methods["GET", "POST"]) def index():if request.method "GET":return render_template("index.html&q…

Python Flask 自定义过滤器

{{ data.list | li2 }} li2就是自定义的 from flask import Flask, render_templateapp Flask(__name__)app.route("/index") def index():data {name: "张三","age": 18,list: [123123, 41, 123]}return render_template("index2.html…

nodejs+vue高校二手商品交易平台的设计与实现python-flask-django-php

当今社会已经步入了科学技术进步和经济社会快速发展的新时期&#xff0c;国际信息和学术交流也不断加强&#xff0c;计算机技术对经济社会发展和人民生活改善的影响也日益突出&#xff0c;人类的生存和思考方式也产生了变化。传统高校二手商品交易采取了人工的管理方法&#xf…

BUG未解之谜01-指针引用之谜

在leetcode里面刷题出现的问题&#xff0c;当我在sortedArrayToBST里面给root赋予初始值NULL之后&#xff0c;问题得到解决&#xff01; 理论上root是未初始化的变量&#xff0c;然后我进入insert函数之后&#xff0c;root引用的内容也是未知值&#xff0c;因此无法给原来的二叉…

array go 语言的数组 /切片

内存地址通过& package mainimport "fmt"func main() {var arr [2][3]int16fmt.Println(arr)fmt.Printf("arr的地址是: %p \n", &arr)fmt.Printf("arr[0]的地址是 %p \n", &arr[0])fmt.Printf("arr[0][0]的地址是 %p \n"…