OpenCV小练习:身份证号码识别

目标:针对一张身份证照片,把身份证号码识别出来(转成数字或字符串)。

实现思路:需要将目标拆分成两个子任务:(1) 把身份证号码区域从整张图片中检测/裁剪出来;(2) 将图片中的数字转化成文字。第一个子任务用OpenCV(如何自行编译OpenCV源码?),第二个子任务主要仰仗Tesseract(注:Tesseract是著名的OCR文字识别开源项目)。

使用OpenCV做图像处理的大致过程为:首先要将彩色图像转成灰度图,再进一步做二值化转换。为了把身份证号码区域整个圈出来,需要继续对图像进行“膨胀”处理,使得每个数字的小区域都与相邻数字的小区域连接起来,连成一个大区域。这样处理之后,在用cv::findContours查找轮廓时,就可以根据身份证号码区域的面积和宽高比把它挑选出来了。

具体代码实现

首先用OpenCV加载图片文件:

Mat srcImage = imread(".\\assets\\pigidcard.png");

接着对图像进行灰度化和二值化处理:

Mat grayImg;
cv::cvtColor(srcImage, grayImg, COLOR_BGR2GRAY);
Mat binary;
cv::threshold(grayImg, binary, 0, 255, THRESH_BINARY_INV | THRESH_OTSU);

到这一步,图像看起来是这样的:

接着要做“膨胀”处理。这一步非常关键!需要调整下面这个Size类型的内核大小,目标是让身份证号码的这些数字前后相连,形成一个整体的矩形区域。

Mat kernel = cv::getStructuringElement(MORPH_RECT, Size(26, 26));
Mat dilation;
cv::dilate(binary, dilation, kernel);

到这一步,图像看起来是这样的:

实际的轮廓/区域分布是这样的:

然后就是遍历图像中的所有轮廓。我们设定两个条件,当轮廓的面积以及轮廓外边框的宽高比都大于某个值(根据实际情况而定),我们就认为当前这个轮廓就是身份证号码区域,可以把它裁剪出来。

std::vector<std::vector<Point>> contours;
std::vector<Vec4i> hierarchy;
cv::findContours(dilation, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);for (size_t i = 0; i < contours.size(); i++) {double area = cv::contourArea(contours[i]);Rect roi = cv::boundingRect(contours[i]);double aspectRatio = (double)roi.width / roi.height;// 根据实际情况调整这两个阈值if (area > 40000 && aspectRatio > 10) {Mat cropped = binary(roi);imshow("ID Card - number only", cropped);// 继续使用 Tesseract OCR// …break;}
}

上面代码运行的结果:cropped对象是裁剪出来的仅含一串身份证号码的小图片。注意这是一个二值图,而且不是膨胀处理后的图像哦!接着轮到Tesseract登场了,把这个图片中的数字转成字符串。(注:请参考这篇文章自行把Tesseract源代码编译成静态库。)

#include "baseapi.h"
#include "allheaders.h"#pragma comment(lib, "leptonica-1.84.1.lib")
#pragma comment(lib, "tesseract54.lib")// 使用 Tesseract OCR
tesseract::TessBaseAPI tess;
if (tess.Init("tessdata", "eng") == 0) {tess.SetPageSegMode(tesseract::PSM_SINGLE_BLOCK);// Tesseract无法识别二值图!转换回RGB图像Mat ocrImg;cv::cvtColor(cropped, ocrImg, COLOR_GRAY2BGR);int bytesPerPixel = GetBytesPerPixel(ocrImg);tess.SetImage((uchar*)ocrImg.data, ocrImg.cols, ocrImg.rows, bytesPerPixel, ocrImg.cols * bytesPerPixel);char* outText = tess.GetUTF8Text();std::cout << "ID numbers: " << outText << std::endl;delete[] outText;tess.End();
}

打完收工!o(* ̄▽ ̄*)ブ

P.S. 完整的代码可以从这里下载:https://github.com/luqiming666/OpenCVMisc。查看OpenCVMiscDlg.cpp 文件中的_DetectIDCard_WithGoodDilation() 函数实现即可。我也上传了Tesseract库文件,但只有Release版。如果要验证OCR效果,需要把OpenCVMisc项目的配置切换到Release + x64,并且在OpenCVMiscDlg.cpp文件头部放开这个宏定义:#define _ENABLE_TESSERACT_

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

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

相关文章

Ubuntu 22.04上稳定安装与配置搜狗输入法详细教程

摘要&#xff1a;本教程详细介绍了如何在Ubuntu 22.04上安装和配置搜狗输入法&#xff0c;每个步骤详细配图。由于在Ubuntu 24.04上存在兼容性问题&#xff0c;建议用户继续使用稳定的22.04版本。教程涵盖了从更新系统源、安装fcitx输入法框架&#xff0c;到下载和配置搜狗输入…

存储实验:基于华为存储实现存储双活(HyperMetro特性)

目录 什么是存储双活仲裁机制 实验需求实验拓扑实验环境实验步骤1. 双活存储存储初始化&#xff08;OceanStor v3 模拟器&#xff09;1.1开机&#xff0c;设置密码1.2登录DM&#xff0c;修改设备名、系统时间和导入License1.3 设置接口IP 2. 仲裁服务器配置&#xff08;Centos7…

全局点云配准的新思考:没有良好初值时如何配准?

更多优质内容&#xff0c;请关注公众号&#xff1a;智驾机器人技术前线 1.论文信息 论文标题&#xff1a;BiEquiFormer: Bi-Equivariant Representations for Global Point Cloud Registration 作者&#xff1a;Stefanos Pertigkiozoglou*, Evangelos Chatzipantazis∗ and K…

【循环顺序队的实现】

1.队列的逻辑结构 与 抽象数据类型定义 先进先出的线性表 在顺序队列中&#xff0c;我们使用头指针front指向队首元素&#xff1b;用尾指针rear指向队尾元素的下一个位置&#xff08;当然这里的指针是用下标模拟出来的&#xff09; 同时顺序队列中的元素当然是用数组来存储的 …

解决STM32使用J-Link可以擦除和读取但是无法烧录问题

现象 使用J-Link烧录模组固件&#xff0c;出现可以读取和擦除&#xff0c;但是无法烧录问题&#xff0c;提示错误如下&#xff1a; ERROR: Programming failed address 0x08000080 (program error)End of flash programmingERROR: Program failed 读出来的时候这个地址数据…

Linux 软件包管理器yum 自动化构建工具-make/makefile

Linux 工具 linux 软件包管理器 yum 把一些常用的软件提前编译好&#xff0c;做成软件包放在一个服务器上&#xff0c;通过包管理器可以很方便的获取到在这个编译好的软件包。直接进行安装。 软件包和软件包管理器就相当于 App 和应用商店这样的关系。 Linux 安装软件 源代码…

poe供电原理以及应用

1,根据IEEE802.3af标准,一个完整的PoE系统包括供电端设备PSE和受电端设备PD两部分; 供电设备PSE是整个系统的电源提供者,为PD设备提供直流电源,其可分为M

如何理解进程

一、进程的概念 进程&#xff1a;顾名思义&#xff0c;就是一个完整执行程序的过程。没错&#xff0c;就是这么简单&#xff0c;但是在程序执行的过程之中&#xff0c;系统会为这个执行的程序分配内存资源&#xff0c;这些过程也包含在进程当中。 进程是动态的&#xff0c;是程…

【网络编程通关之路】 Tcp 基础回显服务器(Java实现)及保姆式知识原理详解 ! ! !

本篇会加入个人的所谓鱼式疯言 ❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言 而是理解过并总结出来通俗易懂的大白话, 小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的. &#x1f92d;&#x1f92d;&#x1f92d;可能说的不是那么严谨.但小编初心是能让更多人…

Linux下IO多路复用—select,poll,epoll

一.概述 1.IO多路复用介绍 IO多路复用是一种操作系统的技术&#xff0c;用于在单个线程或进程中管理多个输入输出操作。它的主要目的是通过将多个IO操作合并到一个系统调用中来提高系统的性能和资源利用率&#xff0c;避免了传统的多线程或多进程模型中因为阻塞IO而导致的资源…

在Linux下搭建go环境

下载go go官网&#xff1a;All releases - The Go Programming Language 我们可以吧压缩包下载到Windows上再传到Linux上&#xff0c;也可以直接web下载&#xff1a; wget https://golang.google.cn/dl/go1.23.0.linux-amd64.tar.gz 解压 使用命令解压&#xff1a; tar -x…

解决有向图中节点出度和入度计算问题

解决有向图中节点出度和入度计算问题 引言邻接链表表示法邻接链表的数据结构创建图添加边计算节点的出度伪代码C代码计算节点的入度伪代码C代码时间复杂度示例结论引言 在图论中,有向图是一种重要的数据结构,用于表示元素之间的方向性关系。有向图中的节点(顶点)通过边连接…

VBA之正则表达式(47)-- 快速将公式转换为静态值计算

实例需求&#xff1a;工作表I列包含多种计算公式&#xff0c;为了便于演示&#xff0c;将I列公式显示在J列单元格中&#xff0c;现在需要将公式的单元格引用转换为静态值&#xff0c;如K列所示。 示例代码如下。 Sub RegExpDemoReplace()Dim Res()Dim objRegEx As ObjectDim o…

[解决]Invalid configuration `aarch64-openwrt-linux‘: machine `aarch64-openwrt

背景 交叉编译libev-4.19 问题 checking host system type… Invalid configuration aarch64-openwrt-linux: machine aarch64-openwrt’ not recognized 解决 打开config.sub&#xff0c;在244行后添加"| aarch64-openwrt \ "

Git学习(001 git介绍以及安装)

尚硅谷2024最新Git企业实战教程&#xff0c;全方位学习git与gitlab 总时长 5:42:00 共40P 此文章包含第1p-第p4的内容 文章目录 介绍Git介绍GitLab介绍 概述Git安装版本控制工具介绍 介绍 Git介绍 GitLab介绍 相当于中央仓库 概述 Git安装 进入官网(下载当前版本 2.43.0) …

解决 RT-Thread bsp stm32l476-st-nucleo STM32L4 HAL库缺失问题

问题描述 当前最新的 RT-Thread 版本&#xff1a;5.2.0&#xff0c;发现在 编译 BSP stm32l476-st-nucleo&#xff0c;缺少了 STM32L4xx_HAL 驱动库&#xff0c;造成生成的 工程&#xff0c;如 Keil MDK5 工程无法编译通过 初步的【临时】解决方法是 回退 RT-Thread 的版本&am…

rabbitmq发送的消息接收不到

1.消息被其他消费者消费 2.主要说的2这种情况&#xff0c;就是在延迟队列中&#xff0c;忘记给一个bean加注解导致日志报exchange not found. 这个报错&#xff0c;进而引发了bindings没有绑定。没有绑定的话&#xff0c;发送消息就会接收不到。

心脑血管科曹启富医生谈:引起高血压的原因

曹医生指出&#xff0c;高血压这一日益普遍的健康问题&#xff0c;其根源深藏于多重复杂因素之中。首要提及的便是年龄因素&#xff0c;它如同时间的刻度&#xff0c;悄然影响着我们的血管健康。随着年龄的增长&#xff0c;血管逐渐失去往昔的弹性与活力&#xff0c;变得僵硬而…

HTMl标签;知识回忆;笔记分享;

HTML标签是用于定义和组织网页内容的基础构建块。每个标签都有特定的作用。 一&#xff0c;标准结构标签&#xff1a; HTML文档标准结构&#xff1a; <html><head></head><body>this is my second html... </body> </html> 【1】htm…

python-FastApi框架

文章目录 FastApi一. 简介二. 特性三. 安装1. 安装fastapi模块2. 安装ASGI服务器( Uvicorn 或者 Hypercorn) 四. 实例1. 创建**main.py**文件(GET请求)2. 运行3. 测试4. 更新main_py(加入PUT请求) 五. 自动化API文档1. Swagger UI(交互式文档)2. ReDoc(可选式文档) FastApi 一…