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

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

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Scala集合操作

1 集合简介 Scala 中拥有多种集合类型,主要分为可变的和不可变的集合两大类: 可变集合: 可以被修改。即可以更改,添加,删除集合中的元素; 不可变集合类:不能被修改。对集合执行更改,…

CSDN规则详解(一)

文章目录 前言CSDN博客用户准则总则博客注册博客行为规则被投诉侵权用户处理规则附则 博客积分规则博客等级博客VIP文章说明后记 前言 CSDN是一个专业的技术社区,不仅可以分享自己的技术经验,还可以向其他行业专业人士学习。在CSDN上写出优秀的博客可以…

tcp/ip协议2实现的插图,数据结构2 (15 - 章)

(40) 40 十五1 插口层 结构socket,sysent (41) 41 十五2 插口层 实用函数与file结构描述汇总 (42) 42 十五3 插口层 函socket,socreate,pr_usrreq (43)

第23期 | GPTSecurity周报

GPTSecurity是一个涵盖了前沿学术研究和实践经验分享的社区,集成了生成预训练 Transformer(GPT)、人工智能生成内容(AIGC)以及大型语言模型(LLM)等安全领域应用的知识。在这里,您可以…

适用于 Linux 的 WPF:Avalonia

许多年前,在 WPF 成为“Windows Presentation Foundation”并将 XAML 作为 .NET、Windows 等的 UI 标记语言引入之前,有一个代号为“Avalon”的项目。Avalon 是 WPF 的代号。XAML 现在无处不在,XAML 标准是一个词汇规范。 Avalonia 是一个开…

软考之软件工程基础理论知识

软件工程基础 软件开发方法 结构化方法 将整个系统的开发过程分为若干阶段,然后依次进行,前一阶段是后一阶段的工作依据按顺序完成。应用最广泛。特点是注重开发过程的整体性和全局性。缺点是开发周期长文档设计说明繁琐,工作效率低开发前要…

数据库存储引擎和锁

存储引擎: mysal当中数据用各种不同的技术存储在文件中,每一种技术都使用不同的存储机制,索引技巧,锁定水平以及最终提供的不同功能和能力,这些就是我们说的存储引擎。 功能: 1、mysql将数据存储在文件系…

【LeetCode刷题-链表】--1290.二进制链表转整数

1290.二进制链表转整数 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val) { this.val val; }* ListNode(int val, ListNode next) { this.val val; this.next next; }*…

低代码开发,一场深度的IT效率革命

目录 一、前言 二、低代码迅速流行的理由 三、稳定性和生产率的最佳实践 四、程序员用低代码开发应用有哪些益处? 1、提升开发价值 2、利于团队升级 五、总结 一、前言 尽管IT技术支撑了全球的信息化浪潮,然而困扰行业已久的软件开发效率并未像摩尔定律那…

k8s、调度约束

Kubernetes 是通过 List-Watch **** 的机制进行每个组件的协作,保持数据同步的,每个组件之间的设计实现了解耦 用户是通过 kubectl 根据配置文件,向 APIServer 发送命令,在 Node 节点上面建立 Pod 和 Container。 APIS…

【sql注入】sql关卡1~4

前言: 靶场自取 level-1 测试注入点 POC: 1,1,1,1"",1/1,1/0 》存在注入点 爆破 POC: id-1andextractvalue(1,concat(0x7e,user(),0x7e))-- level-2 尝试注入点 POC1:admin POC2:admin POC3:adminandsleep(3)-- POC4: adminandif(1,1,0)0-- POC…

按键精灵开发环境搭建

按键精灵是一个可用于编写自动化执行程序的软件,不仅可以用于PC端,也可以用于手机端,平台稳定,生态良好,开发快捷,是自动化软件开发必不可少的利器。 1. 下载软件 官网:按键精灵_按键精灵论坛…

OpenCV实战——OpenCV.js介绍

OpenCV实战——OpenCV.js介绍 0. 前言1. OpenCV.js 简介2. 网页编写3. 调用 OpenCV.js 库4. 完整代码相关链接 0. 前言 本节介绍如何使用 JavaScript 通过 OpenCV 开发计算机视觉算法。在 OpenCV.js 之前,如果想要在 Web 上执行一些计算机视觉任务,必须…

这个超实用的门禁技巧,让办公楼安全更简单高效!

门禁监控是现代社会中不可或缺的一部分,用于确保安全和管理进出某个区域的人员。随着科技的不断发展,门禁监控已经远离了传统的机械锁和钥匙,变得更加智能化和高效。 客户案例 企业办公大楼 无锡某大型企业在其办公大楼内部部署了泛地缘科技…

12.JavaScript(WebAPI) - JS api文献精解

文章目录 1.WebAPI 背景知识1.1什么是 WebAPI1.2什么是 API1.3API 参考文档 2.DOM 基本概念2.1什么是 DOM2.2DOM 树 3.获取元素3.1querySelector3.2querySelectorAll 4.事件初识4.1基本概念4.2事件三要素4.3简单示例 5.操作元素5.1获取/修改元素内容5.1.1innerText5.1.2innerHT…

tbh常用的绘图快捷键

1、Altb -> 笔刷 2、Alt/ -> 画笔 3、按住Shift 绘出的线条是直线 4、按住shiftalt 绘出来的线条是水平线或垂直线 5、alte ->橡皮擦 6、alts ->选择工具 7、altq -> 轮廓编辑器 以下操作都是在选中轮廓编辑器下操作的: 按住alt…

Linux 将Qt程序打包为AppImage包

前言 在 Linux 环境下,开发完 Qt 程序后,也需要制作为一个安装包或者可执行文件进行分发。这里介绍使用 linuxdeployqt 将 Qt 程序打包为 .AppImage 应用程序(类似于 Windows 的绿色免安装软件) 环境配置 配置 Qt 环境变量 这…

TensorFlow案例学习:简单的音频识别

前言 以下内容均来源于官方教程:简单的音频识别:识别关键字 音频识别 下载数据集 下载地址:http://storage.googleapis.com/download.tensorflow.org/data/mini_speech_commands.zip 可以直接浏览器访问下载。 下载完成后将其解压到项目…

路由器基础(九):防火墙基础

防火墙 (Fire Wall) 是网络关联的重要设备,用于控制网络之间的通信。外部网络用户的访问必须先经过安全策略过滤,而内部网络用户对外部网络的访问则无须过滤。现在的防火墙还具有隔离网络、提供代理服务、流量控制等功能。 一、三种防火墙技术 常见的…

医疗数据可视化大屏:重构医疗决策的未来

医疗行业一直是信息密集型领域之一,它的复杂性不仅在于患者病历和医疗数据的海量积累,还包括了病情诊断、医疗资源分配、病患治疗等多层次的挑战。随着信息技术的不断发展,医疗数据可视化大屏成为了一种创新性的工具,它为医疗管理…