当前位置: 首页 > news >正文

竞赛保研 基于计算机视觉的身份证识别系统

0 前言

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

基于机器视觉的身份证识别系统

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

🧿 更多资料, 项目分享:

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

1 实现方法

1.1 原理

1.1.1 字符定位

在Android移动端摄像头拍摄的图片是彩色图像,上传到服务器后为了读取到身份证上的主要信息,就要去除其他无关的元素,因此对身份证图像取得它的灰度图并得到二值化图。

对身份证图像的的二值化有利于对图像内的信息的进一步处理,可以将待识别的信息更加突出。在OpenCV中,提供了读入图像接口函数imread,
首先通过imread将身份证图像读入内存中:


id_card_img = cv2.imread(path_img)

之后再调用转化为灰度图的接口函数cvtColor并给它传入参数COLOR_BGR2GRAY,它就可以实现彩色图到灰度图的转换,代码如下


gray_id_card_img = cv2.cvtColor(color_img, cv2.COLOR_BGR2GRAY)
preprocess_bg_mask = PreprocessBackgroundMask(boundary)

转化为二值化的灰度图后图像如图所示:

在这里插入图片描述

转换成灰度图之后要进行字符定位,通过每一行进行垂直投影,就可以找到所有字段的位置,具体如下:

在这里插入图片描述
然后根据像素点起始位置,确定字符区域,然后将字符区域一一对应放入存放字符的列表中:

 vertical_peek_ranges = extract_peek_ranges_from_array(vertical_sum,minimun_val=40,minimun_range=1)vertical_peek_ranges2d.append(vertical_peek_ranges)

最后的效果图如图所示:

在这里插入图片描述

1.1.2 字符识别

身份证识别中,最重要的是能够识别身份证图像中的中文文字(包括数字和英文字母),这里学长采用深度学习的方式来做:

1)身份证图像涉及个人隐私,很难获取其数据训练集。针对此问题,我采用获取身份证上印刷体汉字和数字的数据训练集的方法,利用Python图像库(PIL)将13类汉字印刷体字体转换成6492个类别,建立了较大的字符训练集;

2)如何获取身份证图片上的字符是在设计中一个重要问题。我采用水平和垂直投影技术,首先对身份证图像进行预处理,然后对图片在水平和垂直方向上像素求和,区分字符与空白区域,完成了身份证图像中字符定位与分割工作,有很好的切分效果;

3)在模型训练中模型的选择与设计是一个重要的环节,本文选择Lenet模型,发现模型层次太浅,然后增加卷积层和池化层,设计出了改进的深层Lenet模型,然后采用Caffe深度学习工具对模型进行训练,并在训练好的模型上进行测试,实验表明,模型的测试精度达到96.2%。

1.1.3 深度学习算法介绍

深度学习技术被提出后,发展迅速,在人工智能领域取得了很好的成绩,越来越多优秀的神经网络也应运而生。深度学习通过建立多个隐层的深层次网络结构,比如卷积神经网络,可以用来研究并处理目前计算机视觉领域的一些热门的问题,如图像识别和图像检索。

深度学习建立从输入数据层到高层输出层语义的映射关系,免去了人工提取特征的步骤,建立了类似人脑神经网的分层模型结构。深度学习的示意图如图所示

在这里插入图片描述

1.1.4 模型选择

在进行网络训练前另一项关键的任务是模型的选择与配置,因为要保证模型的精度,要选一个适合本文身份证信息识别的网络模型。


首先因为汉字识别相当于一个类别很多的图片分类系统,所以先考虑深层的网络模型,优先采用Alexnet网络模型,对于汉字识别这种千分类的问题很合适,但是在具体实施时发现本文获取到的数据训练集每张图片都是6464大小的一通道的灰度图,而Alexnet的输入规格是224224三通道的RGB图像,在输入上不匹配,并且Alexnet在处理像素较高的图片时效果好,用在本文的训练中显然不合适。

其次是Lenet模型,没有改进的Lenet是一个浅层网络模型,如今利用这个模型对手写数字识别精度达到99%以上,效果很好,在实验时我利用在Caffe下的draw_net.py脚本并且用到pydot库来绘制Lenet的网络模型图,实验中绘制的原始Lenet网络模型图如图所示,图中有两个卷积层和两个池化层,网络层次比较浅。

在这里插入图片描述

2 算法流程

在这里插入图片描述

3 部分关键代码

cv2_color_img = cv2.imread(test_image)##放大图片resize_keep_ratio = PreprocessResizeKeepRatio(1024, 1024)cv2_color_img = resize_keep_ratio.do(cv2_color_img)    ##转换成灰度图cv2_img = cv2.cvtColor(cv2_color_img, cv2.COLOR_RGB2GRAY)height, width = cv2_img.shape##二值化  调整自适应阈值 使得图像的像素值更单一、图像更简单adaptive_threshold = cv2.adaptiveThreshold(cv2_img, ##原始图像255,     ##像素值上限cv2.ADAPTIVE_THRESH_GAUSSIAN_C,  ##指定自适应方法Adaptive Method,这里表示领域内像素点加权和cv2.THRESH_BINARY,  ##赋值方法(二值化)11,  ## 规定领域大小(一个正方形的领域)2)   ## 常数C,阈值等于均值或者加权值减去这个常数adaptive_threshold = 255 - adaptive_threshold## 水平方向求和,找到行间隙和字符所在行(numpy)horizontal_sum = np.sum(adaptive_threshold, axis=1)## 根据求和结果获取字符行范围peek_ranges = extract_peek_ranges_from_array(horizontal_sum)vertical_peek_ranges2d = []for peek_range in peek_ranges:start_y = peek_range[0]  ##起始位置end_y = peek_range[1]    ##结束位置line_img = adaptive_threshold[start_y:end_y, :]## 垂直方向求和,分割每一行的每个字符vertical_sum = np.sum(line_img, axis=0)## 根据求和结果获取字符行范围vertical_peek_ranges = extract_peek_ranges_from_array(vertical_sum,minimun_val=40, ## 设最小和为40minimun_range=1)  ## 字符最小范围为1## 开始切割字符vertical_peek_ranges = median_split_ranges(vertical_peek_ranges)## 存放入数组中vertical_peek_ranges2d.append(vertical_peek_ranges)## 去除噪音,主要排除杂质,小的曝光点不是字符的部分filtered_vertical_peek_ranges2d = []for i, peek_range in enumerate(peek_ranges):new_peek_range = []median_w = compute_median_w_from_ranges(vertical_peek_ranges2d[i])for vertical_range in vertical_peek_ranges2d[i]:## 选取水平区域内的字符,当字符与字符间的间距大于0.7倍的median_w,说明是字符if vertical_range[1] - vertical_range[0] > median_w*0.7:new_peek_range.append(vertical_range)filtered_vertical_peek_ranges2d.append(new_peek_range)vertical_peek_ranges2d = filtered_vertical_peek_ranges2dchar_imgs = []crop_zeros = PreprocessCropZeros()resize_keep_ratio = PreprocessResizeKeepRatioFillBG(norm_width, norm_height, fill_bg=False, margin=4)for i, peek_range in enumerate(peek_ranges):for vertical_range in vertical_peek_ranges2d[i]:## 划定字符的上下左右边界区域x = vertical_range[0]y = peek_range[0]w = vertical_range[1] - xh = peek_range[1] - y## 生成二值化图char_img = adaptive_threshold[y:y+h+1, x:x+w+1]## 输出二值化图char_img = crop_zeros.do(char_img)char_img = resize_keep_ratio.do(char_img)## 加入字符图片列表中char_imgs.append(char_img)## 将列表转换为数组np_char_imgs = np.asarray(char_imgs)## 放入模型中识别并返回结果output_tag_to_max_proba = caffe_cls.predict_cv2_imgs(np_char_imgs)ocr_res = ""## 读取结果并展示for item in output_tag_to_max_proba:ocr_res += item[0][0]print(ocr_res.encode("utf-8"))## 生成一些Debug过程产生的图片if debug_dir is not None:path_adaptive_threshold = os.path.join(debug_dir,"adaptive_threshold.jpg")cv2.imwrite(path_adaptive_threshold, adaptive_threshold)seg_adaptive_threshold = cv2_color_img#        color = (255, 0, 0)#        for rect in rects:#            x, y, w, h = rect#            pt1 = (x, y)#            pt2 = (x + w, y + h)#            cv2.rectangle(seg_adaptive_threshold, pt1, pt2, color)color = (0, 255, 0)for i, peek_range in enumerate(peek_ranges):for vertical_range in vertical_peek_ranges2d[i]:x = vertical_range[0]y = peek_range[0]w = vertical_range[1] - xh = peek_range[1] - ypt1 = (x, y)pt2 = (x + w, y + h)cv2.rectangle(seg_adaptive_threshold, pt1, pt2, color)path_seg_adaptive_threshold = os.path.join(debug_dir,"seg_adaptive_threshold.jpg")cv2.imwrite(path_seg_adaptive_threshold, seg_adaptive_threshold)debug_dir_chars = os.path.join(debug_dir, "chars")os.makedirs(debug_dir_chars)for i, char_img in enumerate(char_imgs):path_char = os.path.join(debug_dir_chars, "%d.jpg" % i)cv2.imwrite(path_char, char_img)

4 效果展示

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

5 最后

🧿 更多资料, 项目分享:

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

相关文章:

竞赛保研 基于计算机视觉的身份证识别系统

0 前言 🔥 优质竞赛项目系列,今天要分享的是 基于机器视觉的身份证识别系统 该项目较为新颖,适合作为竞赛课题方向,学长非常推荐! 🧿 更多资料, 项目分享: https://gitee.com/dancheng-sen…...

在visual studio中调试时无法查看std::wstring

1.问题 在调试的时候发现std::wstring类型的变量查看不了,会显示(error)|0,百思不得其解。 2.解决方法 参考的:vs2015调试时无法显示QString变量的值,只显示地址_vs调试qstring的时候如何查看字符串-CSDN博客 在工具/选项/调试…...

2023年全国职业院校技能大赛高职组应用软件系统开发正式赛题—模块三:系统部署测试

模块三:系统部署测试(3 小时) 一、模块考核点 模块时长:3 小时模块分值:20 分本模块重点考查参赛选手的系统部署、功能测试、Bug 排查修复及文档编写能力,具体包括:系统部署。将给定项目发布到…...

微信小程序上传并显示图片

实现效果&#xff1a; 上传前显示&#xff1a; 点击后可上传&#xff0c;上传后显示&#xff1a; 源代码&#xff1a; .wxml <view class"{{company_logo_src?blank-area:}}" style"position:absolute;top:30rpx;right:30rpx;height:100rpx;width:100rp…...

java基础知识点系列——数据输入(五)

java基础知识点系列——数据输入&#xff08;五&#xff09; 数据输入概述 Scanner使用步骤 &#xff08;1&#xff09;导包 import java.util.Scanner&#xff08;2&#xff09;创建对象 Scanner sc new Scanner(System.in)&#xff08;3&#xff09;接收数据 int i sc…...

MySQL面试题 | 07.精选MySQL面试题

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…...

C语言中关于指针的理解及用法

关于指针意思的参考&#xff1a;https://baike.baidu.com/item/%e6%8c%87%e9%92%88/2878304 指针 指针变量 地址 野指针 野指针就是指针指向的位置是不可知的&#xff08;随机的&#xff0c;不正确的&#xff0c;没有明确限制的&#xff09; 以下是导致野指针的原因 1.指针…...

软件测试|深入理解Python中的re.search()和re.findall()区别

前言 在Python中&#xff0c;正则表达式是一种强大的工具&#xff0c;用于在文本中查找、匹配和处理模式。re 模块提供了许多函数来处理正则表达式&#xff0c;其中 re.search()和 re.findall() 是常用的两个函数&#xff0c;用于在字符串中查找匹配的模式。本文将深入介绍这两…...

❤ Vue3 完整项目太白搭建 Vue3+Pinia+Vant3/ElementPlus+typerscript(一)yarn 版本控制 ltb (太白)

❤ 项目搭建 一、项目信息 Vue3 完整项目搭建 Vue3PiniaVant3/ElementPlustyperscript&#xff08;一&#xff09;yarn 版本控制 项目地址&#xff1a; 二、项目搭建 &#xff08;1&#xff09;创建项目 yarn create vite <ProjectName> --template vueyarn install …...

linux搭建SRS服务器

linux搭建SRS服务器 文章目录 linux搭建SRS服务器SRS说明实验说明搭建步骤推流步骤查看web端服务器拉流步骤final SRS说明 SRS&#xff08;simple Rtmp Server&#xff09;,是一个简单高效的实时视频服务器&#xff0c;支持RTMP/WebRTC/HLS/HTTP-FLV/SRT, 是国人自己开发的一款…...

系列六、Spring Security中的认证 授权 角色继承

一、Spring Security中的认证 & 授权 & 角色继承 1.1、概述 关于Spring Security中的授权&#xff0c;请参考【系列一、认证 & 授权】&#xff0c;这里不再赘述。 1.2、资源类 /*** Author : 一叶浮萍归大海* Date: 2024/1/11 20:58* Description: 测试资源*/ Re…...

云原生周刊:OpenTofu 宣布正式发布 | 2023.1.15

开源项目推荐 kubeaudit kubeaudit 是一个开源项目&#xff0c;旨在帮助用户对其 Kubernetes 集群进行常见安全控制的审计。该项目提供了工具和检查规则&#xff0c;可以帮助用户发现潜在的安全漏洞和配置问题。 Chronos Chronos 是一款综合性开发人员工具&#xff0c;可监…...

【如何在 GitHub上面找项目】【转载】

很多的小伙伴&#xff0c;经常会有这样的困惑&#xff0c;我看了很多技术的学习文档、书籍、甚至视频&#xff0c;我想动手实践&#xff0c;于是我打开了GitHub&#xff0c;想找个开源项目&#xff0c;进行学习&#xff0c;获取项目实战经验。这个时候很多小伙伴就会面临这样的…...

java每日一题——ATM系统编写(答案及编程思路)

前言&#xff1a; 基础语句学完&#xff0c;也可以编写一些像样的程序了&#xff0c;现在要做的是多加练习&#xff0c;巩固下知识点&#xff0c;打好基础&#xff0c;daydayup! 题目&#xff1a;模仿银行ATM系统&#xff0c;可以创建用户&#xff0c;存钱&#xff0c;转账&…...

《TrollStore巨魔商店》TrollStore2安装使用教程支持IOS14.0-16.6.1

TrollStore(巨魔商店) 简单的说就相当于一个永久的免费证书&#xff0c;它可以给你的iPhone和iPad安装任何你想要安装的App软件&#xff0c;而且不需要越狱,不用担心证书签名过期的问题&#xff0c;不需要个人签名和企业签名。 支持的版本&#xff1a; TrollStore安装和使用教…...

鸿鹄电子招投标系统源码实现与立项流程:基于Spring Boot、Mybatis、Redis和Layui的企业电子招采平台

随着企业的快速发展&#xff0c;招采管理逐渐成为企业运营中的重要环节。为了满足公司对内部招采管理提升的要求&#xff0c;建立一个公平、公开、公正的采购环境至关重要。在这个背景下&#xff0c;我们开发了一款电子招标采购软件&#xff0c;以最大限度地控制采购成本&#…...

力扣-三数之和

三数之和 给你一个整数数组 nums &#xff0c;判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k &#xff0c;同时还满足 nums[i] nums[j] nums[k] 0 。请你返回所有和为 0 且不重复的三元组。 注意&#xff1a;答案中不可以包含重复的三元组。…...

全罐喂养一个月多少钱?适合全罐喂养的猫罐头推荐

不少铲屎官一直没有办法get到猫罐头对猫咪的好处&#xff0c;或者get到了又觉得给猫咪买猫罐头好贵&#xff0c;看到其他铲屎官都开始全罐喂养了&#xff0c;但是自己却迟迟下不了手&#xff0c;犹犹豫豫的不知道全罐喂养一个月多少钱&#xff1f; 今天&#xff0c;铲龄15年的…...

js some方法的使用

JavaScript中的数组some()方法用于检查数组中是否至少有一个元素满足指定条件。该方法会遍历数组&#xff0c;并对每个元素应用指定的测试函数。如果有任何一个元素使得测试函数返回true&#xff0c;则some()方法返回true&#xff0c;否则返回false。 some()方法的语法如下&am…...

QT DAY5作业

1.QT基于TCP服务器端 头文件 #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTcpServer> //服务器类 #include <QMessageBox> //消息对话框类 #include <QTcpSocket> //客户端类 #include <QList> //链表容器类namespace …...

芯片研发为什么总是延期?问题不在技术,在管理没闭环

一个芯片项目失败&#xff0c;事后复盘&#xff0c;技术问题往往只占一小部分。更多的时候&#xff0c;是计划没做好&#xff0c;执行过程没人盯&#xff0c;出了问题没人协调&#xff0c;最后交付的时候才发现跑偏了很久。这是行业里非常普遍的现象。法约尔在一百年前提出管理…...

2026别墅地下室保养升值的最好方法:电渗透技术的应用

别墅地下室随着人们日益增长的生活质量&#xff0c;功能也逐渐变得丰厚。当今时代不少业主都会在地下室加装健身房&#xff0c;酒窖以及影视厅等。这些功能区建设完毕初期给人无不良影响&#xff0c;但是随着时间的渐长&#xff0c;湿气不断渗透&#xff0c;首先空气潮湿度会给…...

3步构建智能文献管理系统:Zotero GPT插件从配置到精通指南

3步构建智能文献管理系统&#xff1a;Zotero GPT插件从配置到精通指南 【免费下载链接】zotero-gpt GPT Meet Zotero. 项目地址: https://gitcode.com/gh_mirrors/zo/zotero-gpt 在信息爆炸的学术环境中&#xff0c;研究人员平均每天需要处理超过20篇文献&#xff0c;传…...

告别复杂配置!Phi-3-Mini-128K一键部署实测:7GB显存跑通,小白也能玩转大模型

告别复杂配置&#xff01;Phi-3-Mini-128K一键部署实测&#xff1a;7GB显存跑通&#xff0c;小白也能玩转大模型 1. 为什么选择Phi-3-Mini-128K 如果你正在寻找一个既强大又轻量的大语言模型&#xff0c;Phi-3-Mini-128K绝对值得考虑。这个由微软开发的模型虽然只有3.8亿参数…...

企业级离线OCR深度解析:5大策略实现高性能文字识别

企业级离线OCR深度解析&#xff1a;5大策略实现高性能文字识别 【免费下载链接】Umi-OCR OCR software, free and offline. 开源、免费的离线OCR软件。支持截屏/批量导入图片&#xff0c;PDF文档识别&#xff0c;排除水印/页眉页脚&#xff0c;扫描/生成二维码。内置多国语言库…...

AI辅助开发:描述需求,快马AI自动生成旅行商问题算法与可视化

最近在做一个旅行商问题(TSP)的算法项目&#xff0c;想试试用AI辅助开发能有多高效。结果发现InsCode(快马)平台的AI功能真的帮了大忙&#xff0c;整个过程特别顺畅。这里分享一下我的体验。 需求分析阶段 刚开始我只是简单描述了需求&#xff1a;"需要一个用模拟退火算…...

永磁同步电机多电机同步控制仿真:改进与对比的奇妙之旅

永磁同步电机多电机同步控制仿真&#xff0c;含改进对比在电机控制领域&#xff0c;永磁同步电机&#xff08;PMSM&#xff09;凭借其高效、节能等诸多优点&#xff0c;广泛应用于工业生产、电动汽车等多个重要领域。而当涉及多个永磁同步电机协同工作时&#xff0c;实现同步控…...

Vue 3 useModel与defineModel实战对比:如何根据项目需求选择最佳双向绑定方案

1. Vue 3双向绑定技术演进与核心概念 双向数据绑定一直是Vue框架的核心特性之一。在Vue 3.4版本中&#xff0c;官方引入了两种新的实现方式&#xff1a;useModel和defineModel。这两种API虽然目标相同&#xff0c;但在使用场景和实现方式上存在明显差异。 要理解它们的区别&…...

Qwen3.5-9B惊艳效果:上传物理实验图→识别仪器→生成操作步骤视频脚本

Qwen3.5-9B惊艳效果&#xff1a;上传物理实验图→识别仪器→生成操作步骤视频脚本 1. 模型能力概览 Qwen3.5-9B是一款拥有90亿参数的开源大语言模型&#xff0c;在多模态理解和逻辑推理方面表现出色。这个模型最令人惊艳的能力在于它能够&#xff1a; 准确识别实验仪器&…...

Python智能内存回收实战:3种GC策略对比+4个生产级调优参数配置(附压测数据)

第一章&#xff1a;Python智能体内存管理策略生产环境部署在高并发、长生命周期的Python智能体服务中&#xff0c;内存管理直接影响系统稳定性与响应延迟。默认的CPython引用计数循环垃圾回收&#xff08;GC&#xff09;机制在动态对象频繁创建销毁的场景下易引发内存抖动和不可…...