接下来我将讲述如何利用pysseract、dlib以及OpenCV识别身份证号码并检查其是否合法(包括库文件的安装等)。

我参照了以下两篇博客的内容(或者说是这两篇博客的整理以及整合):

https://blog.csdn.net/qq_37674858/article/details/80497563

https://blog.csdn.net/nzjdsds/article/details/81775981

1.安装相关的库文件

身份证号码识别需要用到的库文件有:

import pytesseract
import cv2
import matplotlib.pyplot as plt
import dlib
import matplotlib.patches as mpatches
from skimage import io,draw,transform,color
import numpy as np
import pandas as pd
import re

建议大家下载anaconda来安装相关的包,这样比较简单,但是anaconda只能安装其中一部分的包(numpy,pandas,matplotlib,cv2),剩下的几个包利用anaconda安装的时候会报错,这时候就要使用其他方法下载。(re库自带)

这里提醒一下大家,CV2就是OpenCV,大家想用CV2库的话直接下载 OpenCV即可;skimage的全名是scikit-image,如果直接搜索skimage是搜不到的,需要搜索scikit-image。

anaconda安装pytesseract、dlib、scikit-image这三个库时,可能会报如下错误:

TypeError: sequence item 0: expected str instance, bytes found

出现这个错误后,我上网搜了很多方法,都下载不下来,最后利用windows自带的pip安装,才下载下来。

pip安装的命令:

pip install pytesseract
pip install dlib
pip install scikit-image

其中,pytesseract安装后并不能直接使用,在windows环境下进行识别时,会报如下错误:pytesseract.pytesseract.TesseractNotFoundError: tesseract is not installed or it's not in your path

意思就是找不到Tesseract。

出现这个错误的原因主要由两点,一个是没有下载相应的库(Tesseract-OCR),另一个就是pytesseract调用tesseract的路径不对。

如果没有下载Tesseract-OCR,这里给大家提供下载:

链接:https://pan.baidu.com/s/1C1DTjcunff6zRrExdInjWw 
提取码:tv9y

如果是调用路径不对,大家可以参考如下的博客修改相关路径:

https://blog.csdn.net/qq_36853469/article/details/91572797

至此,所有的库文件已经下载完毕,前期的准备工已经完成了。

代码的详细讲解,大家可以参照下面这篇博客,我这里只贴完整的代码(可以直接运行):

https://blog.csdn.net/qq_37674858/article/details/80497563

如果缺少相关的数据库(shape_predictor_5_face_landmarks.dat以及shape_predictor_68_face_landmarks.dat),大家可以去我的另一篇博客下载相关资源(百度网盘资源):

https://blog.csdn.net/Viadimir/article/details/105035660

识别身份证号码的完整代码如下:

# -*- coding: UTF-8 -*- import pytesseract
import cv2
import matplotlib.pyplot as plt
import dlib
import matplotlib.patches as mpatches
from skimage import io,draw,transform,color
import numpy as np
import pandas as pd
import re#计算图像的身份证倾斜的角度
def IDcorner(landmarks):"""landmarks:检测的人脸五个特征点经过测试使用第0个和第2个特征点计算角度比较合适"""corner20 =  twopointcor(landmarks[2,:],landmarks[0,:])corner = np.mean([corner20])return corner#计算眼睛的倾斜角度,逆时针角度
def twopointcor(point1,point2):"""point1 = (x1,y1),point2 = (x2,y2)"""deltxy = point2 - point1corner = np.arctan(deltxy[1] / deltxy[0]) * 180 / np.pireturn cornerdef rotateIdcard(image):"image :需要处理的图像"## 使用dlib.get_frontal_face_detector识别人脸detector = dlib.get_frontal_face_detector()#使用detector进行人脸检测 dets为返回的结果dets = detector(image, 2) ## 检测人脸的眼睛所在位置predictor = dlib.shape_predictor("shape_predictor_5_face_landmarks.dat")detected_landmarks = predictor(image, dets[0]).parts()landmarks = np.array([[p.x, p.y] for p in detected_landmarks])corner = IDcorner(landmarks)## 旋转后的图像image2 = transform.rotate(image,corner,clip=False)image2 = np.uint8(image2*255)## 旋转后人脸位置det = detector(image2, 2)return image2,detdetector = dlib.get_frontal_face_detector()
image = io.imread("idcard.jpg")
#使用detector进行人脸检测dets为返回结果
dets = detector(image, 2)
for i, face in enumerate(dets):#在图片中标注人脸并显示left = face.left()top = face.top()right = face.right()bottom = face.bottom()rect = mpatches.Rectangle((left,bottom), right - left, top - bottom,fill=False, edgecolor='red', linewidth=1)image = io.imread("idcard.jpg")
image2,dets = rotateIdcard(image)# 在图片中标注人脸,并显示
left = dets[0].left()
top = dets[0].top()
right = dets[0].right()
bottom = dets[0].bottom()
rect = mpatches.Rectangle((left,bottom), (right - left), (top - bottom),fill=False, edgecolor='red', linewidth=1)## 照片的位置(不怎么精确)
width = right - left
high = top - bottom
left2 = np.uint(left - 0.3*width)
bottom2 = np.uint(bottom + 0.4*width)
rect = mpatches.Rectangle((left2,bottom2), 1.6*width, 1.8*high,fill=False, edgecolor='blue', linewidth=1)## 身份证上人的照片
top2 = np.uint(bottom2+1.8*high)
right2 = np.uint(left2+1.6*width)
image3 = image2[top2:bottom2,left2:right2,:]## 对图像进行处理,转化为灰度图像=>二值图像
imagegray = cv2.cvtColor(image2,cv2.COLOR_RGB2GRAY)
retval, imagebin = cv2.threshold(imagegray, 120, 255, cv2.THRESH_OTSU + cv2.THRESH_BINARY)
## 将照片去除
imagebin[0:bottom2,left2:-1] = 255#利用pytesseract识别照片上的身份证号码
text = pytesseract.image_to_string(imagebin,lang='chi_sim')
textlist = text.split("\n")
textdf = pd.DataFrame({"text":textlist})
textdf["textlen"] = textdf.text.apply(len)
textdf = textdf[textdf.textlen > 1].reset_index(drop = True)
#打印身份证号码
print(textdf.text.values[-1])

其实上面那片博客是有完整代码的,但是那个博主写的完整代码很不符合Python编码的规范,简直可以用乱七八糟来形容,所以我这里给他整理了一下,删掉了冗余的内容,并更改了部分代码的位置。

接下来贴判别身份证号码是否合法的代码。网络上有很多判别身份证是否合法的代码,效果有的好有的坏,我试了很多,下面给大家贴我认为我找到的判别效果最好的代码:

# -*- coding: utf-8 -*-
import re
#Errors=['验证通过!','身份证号码位数不对!','身份证号码出生日期超出范围或含有非法字符!','身份证号码校验错误!','身份证地区非法!']
def checkIdcard(idcard):Errors=['验证通过!','身份证号码位数不对!','身份证号码出生日期超出范围或含有非法字符!','身份证号码校验错误!','身份证地区非法!']area={"11":"北京","12":"天津","13":"河北","14":"山西","15":"内蒙古","21":"辽宁","22":"吉林","23":"黑龙江","31":"上海","32":"江苏","33":"浙江","34":"安徽","35":"福建","36":"江西","37":"山东","41":"河南","42":"湖北","43":"湖南","44":"广东","45":"广西","46":"海南","50":"重庆","51":"四川","52":"贵州","53":"云南","54":"西藏","61":"陕西","62":"甘肃","63":"青海","64":"宁夏","65":"新疆","71":"台湾","81":"香港","82":"澳门","91":"国外"}idcard=str(idcard)idcard=idcard.strip()idcard_list=list(idcard)#地区校验if(not area[(idcard)[0:2]]):print(Errors[4])#15位身份号码检测if(len(idcard)==15):if((int(idcard[6:8])+1900) % 4 == 0 or((int(idcard[6:8])+1900) % 100 == 0 and (int(idcard[6:8])+1900) % 4 == 0 )):erg=re.compile('[1-9][0-9]{5}[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|[1-2][0-9]))[0-9]{3}$')#//测试出生日期的合法性else:ereg=re.compile('[1-9][0-9]{5}[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|1[0-9]|2[0-8]))[0-9]{3}$')#//测试出生日期的合法性if(re.match(ereg,idcard)):print(Errors[0])else:print(Errors[2])#18位身份号码检测elif(len(idcard)==18):#出生日期的合法性检查#闰年月日:((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|[1-2][0-9]))#平年月日:((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|1[0-9]|2[0-8]))if(int(idcard[6:10]) % 4 == 0 or (int(idcard[6:10]) % 100 == 0 and int(idcard[6:10])%4 == 0 )):ereg=re.compile('[1-9][0-9]{5}(19[0-9]{2}|20[0-9]{2})((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|[1-2][0-9]))[0-9]{3}[0-9Xx]$')#//闰年出生日期的合法性正则表达式else:ereg=re.compile('[1-9][0-9]{5}(19[0-9]{2}|20[0-9]{2})((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|1[0-9]|2[0-8]))[0-9]{3}[0-9Xx]$')#//平年出生日期的合法性正则表达式#//测试出生日期的合法性if(re.match(ereg,idcard)):#//计算校验位S = (int(idcard_list[0]) + int(idcard_list[10])) * 7 + (int(idcard_list[1]) + int(idcard_list[11])) * 9 + (int(idcard_list[2]) + int(idcard_list[12])) * 10 + (int(idcard_list[3]) + int(idcard_list[13])) * 5 + (int(idcard_list[4]) + int(idcard_list[14])) * 8 + (int(idcard_list[5]) + int(idcard_list[15])) * 4 + (int(idcard_list[6]) + int(idcard_list[16])) * 2 + int(idcard_list[7]) * 1 + int(idcard_list[8]) * 6 + int(idcard_list[9]) * 3Y = S % 11M = "F"JYM = "10X98765432"M = JYM[Y]#判断校验位if(M == idcard_list[17]):#检测ID的校验位print(Errors[0])else:print(Errors[3])else:print(Errors[2])else:print(Errors[1])if __name__ == "__main__":while True:cdcard = input(u"请输入你的身份证号:")if cdcard == "exit":print ("程序已结束!")breakelse:checkIdcard(cdcard)

感谢大家的阅读。

Python识别身份证号码并检查是否合法(pysseract,dlib,opencv)相关推荐

  1. Python代码使用easyocr识别身份证号码

    Python代码使用easyocr识别身份证号码,直接上代码 import easyocr import os import re import pandas as pdclass card():de ...

  2. 利用python识别身份证号后获取年龄和性别信息

    利用python识别身份证号后获取年龄和性别信息 1. 实验目的 利用python识别身份证号后,从身份证号中获取年龄和性别信息 2. 主代码 1. 身份证号码识别 # !/usr/bin/pytho ...

  3. Android Studio+OpenCV 识别身份证号码---识别身份证号码

    上一章使用CLion+OpenCV对身份证号码进行了检测,经过检测我们能拿到身份证号码区域的照片,现在我们对上一章拿到的图片中的数字进行识别 上一章链接:CLion+OpenCV 识别身份证号码--- ...

  4. JAVA识别身份证号码,H5识别身份证号码,tesseract-ocr识别(一)

    背景介绍: 这段时间正在做一个流动人口管理项目,其中要求使用H5网页拍照识别身份证,当时就蒙圈了,这不是APP的功能吗?产品为了快速迭代一直把APP的功能往H5上堆砌,没办法只有想办法解决了. 查了一 ...

  5. JAVA识别身份证号码,H5识别身份证号码,tesseract-ocr识别(二)

    背景介绍 上一篇博文介绍了如何使用JAVA识别身份证号码,假设在截取了身份证号码信息的情况下,这一篇博文主要讨论一下思路吧,技术方面都是大家会的. 思路分析 H5拍照上传 -> 服务端截取身份证 ...

  6. 利用python进行身份证号码大全_用 Java 撸一个身份证号码识别系统,准确率高达 90%...

    项目介绍 本项目是通过学习https://gitee.com/nbsl/idCardCv 后整合tess4j,不需要经过训练直接使用的,当然,你也可以进行训练后进行使用.该项目修改原有的需要安装ope ...

  7. 【python】身份证号码有效性校验

    1. 前言 中华人民共和国国家标准GB 11643-1999<公民身份号码>中规定:公民身份号码是特征组合码,由17位数字本体码和1位校验码组成. 18位数字组合的方式是: 其中,最后一位 ...

  8. Python识别身份证信息,并保存在excel当中

    编写代码前的注意事项 批量进行身份证信息的识别,并保存在excel文件当中 python当前版本:3.7 需要安装包:pandas,easyocr,openpyxl import easyocr im ...

  9. Android 识别身份证号码(图片识别)

    概述 Android 身份证号码识别 (本地,在线,实时),网络识别用的别人的接口,不保障什么时候就用不了了,本地识别基于tess_two,位置对的话识别准确率达到90%以上. 详细 代码下载:htt ...

最新文章

  1. 不显示圆点_10个应用隐藏的彩蛋,细节控都不一定全知道。
  2. 最短路径问题 java实现 源代码
  3. lingo 嵌套@for或嵌套@sum
  4. C语言DCI(OCI)方式连接DM数据库
  5. 服务器内存型号与频率,一张图看懂如何选择DDR4内存的频率和容量
  6. 801. 二进制中1的个数
  7. rsem比对_RSEM方法比对和表达量计算
  8. 「HAOI2018」染色 解题报告
  9. 未来两年九大信息安全威胁
  10. (十七)Activitivi5之组任务分配
  11. SVN客户端安装与使用
  12. 块数据3.0:秩序互联网与主权区块链
  13. 青龙面板-- 咸鱼吃鱼(废-已不能使用)
  14. 【开关电源原理及选型介绍】
  15. 你不能不知道的荣耀V40隐藏功能
  16. vscode安装ARM插件搜不到
  17. win10更新服务打开后为什么服务拒绝访问
  18. android 全局菜单键,视听效果都很出色的超值之选 OPPO智能电视K9评测
  19. 用 .Net Framework 4.0 制作的安装程序来安装 .Net Framework 4.0 编写的程序
  20. php通讯录系统,企业通讯录管理系统

热门文章

  1. 基于STM32C8T6的智能蓝牙小车(毕业设计)
  2. 使用mapreduce进行流量汇总程序开发
  3. 怎么样写好头部姿态的研究背景?
  4. C语言聊天室项目说明书
  5. 用java基础实现五子棋
  6. jsp 简单的登陆界面(不连数据库)
  7. pyaudio usb playback_利用python工具包pyaudio实现录音
  8. JAVA程序运行流程
  9. go time包定时器和断续器
  10. 【BUUCTF】[MRCTF2020]套娃