8.OpenCV-识别身份证号码(Python)

这篇具有很好参考价值的文章主要介绍了8.OpenCV-识别身份证号码(Python)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

需求描述:

通过OpenCV识别身份证照片上的身份证号码(仅识别身份证号码)

实现思路:

1.将身份证号中的0,1,2,3,4,5,6,7,8,9作为模板,与身份证照片中的身份证号码区域进行模板匹配。

2.先要制作一个身份证号码模板,我这里弄了一个,基本上可以用。

8.OpenCV-识别身份证号码(Python)

 3.识别出身份证照片身份证号区域,进行图像模板匹配。

   以下面这样图为例(你也可以替换为你要识别的图片):

8.OpenCV-识别身份证号码(Python)

 4.识别出身份证号码后,在图中标记出识别结果。

运行效果:

8.OpenCV-识别身份证号码(Python)

Python源代码目前只能识别标准角度拍摄照片,拍摄角度变形的无法识别):

import cv2
import numpy as np 

rectKernel=cv2.getStructuringElement(cv2.MORPH_RECT,(15,15)) #kernel1 = np.ones((15, 15), np.uint8)
sqKernel=cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))

#轮廓排序
def sort_contours(cnts,method="left-to-right"):
    reverse=False
    i=0
    if method=="right-to-left" or method=="bottom-to-top":
        reverse=True
    if method=="top-to-bottom" or method=="bottom-to-top":
        i=1
    boundingBoxes=[cv2.boundingRect(c) for c in cnts] #外接矩形
    (cnts,boundingBoxes)=zip(*sorted(zip(cnts,boundingBoxes),key=lambda b:b[1][i],reverse=reverse))
    return cnts,boundingBoxes

# 第一步:预处理模板文件
templateImg = cv2.imread("template.jpg") #template.jpg 即为模板文件,上面那张0-9数字图片
templateImg = cv2.resize(templateImg, (900, 200), interpolation=cv2.INTER_CUBIC)
#转灰度图
templateGray=cv2.cvtColor(templateImg,cv2.COLOR_BGR2GRAY) 
cv2.imshow("1.1 templateGray",templateGray)
#二值处理
templateGray=cv2.threshold(templateGray,30,255,cv2.THRESH_BINARY_INV)[1] 
# cvblackhat = cv2.morphologyEx(templateGray, cv2.MORPH_BLACKHAT, np.ones((50, 50), np.uint8))
# templateGray=cv2.threshold(cvblackhat,0,255,cv2.THRESH_BINARY|cv2.THRESH_OTSU)[1] 
cv2.imshow("1.2 threshold",templateGray)

#提取轮廓(10个数字的外部轮廓)
templateContours,hierarchy=cv2.findContours(templateGray.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(templateImg,templateContours,-1,(0,0,255),3)
cv2.imshow("1.3 drawContours",templateImg)
templateContours=sort_contours(templateContours,method="left-to-right")[0]

#用于做模板匹配的图像集合
templates={}
for(i,c) in enumerate(templateContours):
    (x,y,w,h)=cv2.boundingRect(c) #外接矩形
    roi=templateGray[y:y+h,x:x+w]
    roi=cv2.resize(roi,(57,88))
    templates[i]=roi

#第二步:处理身份证图片

# 1.读取原图
idimg = cv2.imread("idcard.jpg") #需要进行识别的图片
idimg = cv2.resize(idimg, (509, 300), interpolation=cv2.INTER_CUBIC)
idimgok = idimg.copy()
cv2.imshow("1.origin", idimg)

#2.转灰度图
gray = cv2.cvtColor(idimg, cv2.COLOR_BGR2GRAY)
cv2.imshow("2.gray", gray)

#3.黑帽运算:移除干扰项
cvblackhat = cv2.morphologyEx(gray, cv2.MORPH_BLACKHAT, rectKernel)
cv2.imshow("3.black", cvblackhat)

#4.顶帽运算:突出轮廓
tophat=cv2.morphologyEx(cvblackhat,cv2.MORPH_TOPHAT,rectKernel)
cv2.imshow("4.tophat", tophat)

#5.边缘检测
sobel=cv2.Sobel(tophat,ddepth=cv2.CV_32F,dx=1,dy=0,ksize=-1)
sobel=np.absolute(sobel)
(min,max)=(np.min(sobel),np.max(sobel))
sobel=(255*((sobel-min)/(max-min)))
sobel=sobel.astype("uint8")
cv2.imshow("5.sobel", sobel)

#6.闭操作,先膨胀,再腐蚀
sobel=cv2.morphologyEx(sobel,cv2.MORPH_CLOSE,rectKernel) 
cv2.imshow("6.close", sobel)

#7.二值化突出轮廓,自动阈值范围 cv2.THRESH_BINARY|cv2.THRESH_OTSU
thresh=cv2.threshold(sobel,0,255,cv2.THRESH_BINARY|cv2.THRESH_OTSU)[1] 
cv2.imshow("7.thresh", thresh)

#8.再闭操作,先膨胀,再腐蚀
thresh=cv2.morphologyEx(thresh,cv2.MORPH_CLOSE,sqKernel) 
cv2.imshow("8.close2", thresh)

#9.提取轮廓,并在图上标记轮廓
cnts,hierarchy=cv2.findContours(thresh.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
mark=idimg.copy()
cv2.drawContours(mark,cnts,-1,(0,0,255),2)
cv2.imshow("9.mark", mark)

#身份证区域,虽然只有一个轮廓,这里还是用集合来处理
pidArea=[]
for(i,c) in enumerate(cnts):
    (x,y,w,h)=cv2.boundingRect(c)
    ar=w/float(h)
    if ar>12 and ar<40:
        pidArea.append((x,y,w,h)) #身份证号区域长宽比比较明显,算是一个比较明显的特征
        break
#pidArea=sorted(pidArea,key=lambda x:x[0])#若有多个区域,需进行从左到右排序

#10.模板匹配
output=[] 
for(i,(gx,gy,gw,gh)) in enumerate(pidArea):
    area=gray[gy-5:gy+gh+5,gx-5:gx+gw+5] #稍微扩展点区域,保证内容都能框住
    cv2.imshow("9.matched", area) 

    #下面操作跟处理模板图像一样:
    #先黑帽处理,移除干扰项,再二值化处理(自动阈值)    
    area = cv2.morphologyEx(area, cv2.MORPH_BLACKHAT, np.ones((10, 10), np.uint8))
    area=cv2.threshold(area,0,255,cv2.THRESH_BINARY|cv2.THRESH_OTSU)[1] 
    cv2.imshow("10.threshold", area) 

    # 再检测轮廓
    numContours,hierarchy=cv2.findContours(area.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)     

    #注意:此处需判断轮廓的个数是否是18个,对应18个数字 
    numContours=sort_contours(numContours,method="left-to-right")[0]

    #11.遍历轮廓,并逐个与模板图像进行匹配,将最高得分保留
    for c in numContours:
        (x,y,w,h)=cv2.boundingRect(c)
        roi=area[y:y+h,x:x+w]
        roi=cv2.resize(roi,(57,88)) #模板也做了缩放,相同尺寸进行比较
        scores=[]
        #跟10张模板图片进行模板匹配
        for (j,templateROI)in templates.items():
            result=cv2.matchTemplate(roi,templateROI,cv2.TM_CCOEFF)
            (_,score,_,_)=cv2.minMaxLoc(result)
            scores.append(score) #scores中存放了当前轮廓对应0-10中每个数字的概率

        #将分值最大的保留下来
        num=np.argmax(scores)  #np.argmax():获取array的某一个维度中数值最大的那个元素的索引,索引即为对应数字
        output.append(str(num))
        

#12.在原图上绘制识别结果
index=0
(gx,gy,gw,gh)=pidArea[0] #身份证区域位置
for c in numContours:
    (x,y,w,h)=cv2.boundingRect(c) #数字轮廓位置
    num=output[index]
    cv2.putText(idimg,str(num),(gx+x-8 ,gy+y-15),cv2.FONT_HERSHEY_SIMPLEX,0.65,(0,0,255),2) 
    index=index+1    
cv2.imshow("12.done", idimg)

print("识别结果:"+"".join(output))
cv2.waitKey(0)

 运行结果:

模板处理

8.OpenCV-识别身份证号码(Python)

图像处理

8.OpenCV-识别身份证号码(Python)

8.OpenCV-识别身份证号码(Python)

 特别说明:

1.对输入身份证照片有要求,必须是完全的身份证照片,不能有背景,不能变形。

2.只识别了身份证号区域,如需识别其他信息,可以自行修改代码。

3.如无法识别你的图片,请手动调试代码,注释都在代码里,修改对应步骤参数,多试几次。文章来源地址https://www.toymoban.com/news/detail-506320.html

到了这里,关于8.OpenCV-识别身份证号码(Python)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 身份证号码正则表达式详解

    公民身份号码是特征组合码,由十七位数字本体码和一 位 校验码 组成 。排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。 地址码 : ( 身份证号码第一位到第六位 ) 表示编码对象常住户口所在 的 行政区划代码,按

    2024年02月06日
    浏览(30)
  • java 根据身份证号码判断性别

    在Java中,您可以根据身份证号码的规则来判断性别。中国的身份证号码通常采用的是以下规则: 第17位数字代表性别,奇数表示男性,偶数表示女性。 通常,男性的出生日期的第15、16位数字是01,女性是02。 请注意,这只是一个大致的规则,实际上,有些特殊情况下的身份

    2024年02月07日
    浏览(35)
  • 基于Python实现身份证信息识别

    2024年01月19日
    浏览(42)
  • 根据身份证号码判断是否是未成年人

     /****      * 根据身份证号计算年龄      * @param str        * @param currDate       * @return      */     public boolean calcYear(String str, Date currDate){         DateFormat dateFormat = new SimpleDateFormat(\\\"yyyyMMdd\\\");         Long year = Long.parseLong(str.substring(0,4));         Long month = Long.parseLong(st

    2023年04月23日
    浏览(67)
  • Python使用阿里API进行身份证识别

    孟莉苹,女,西安工程大学电子信息学院,2021级硕士研究生,张宏伟人工智能课题组 研究方向:机器视觉与人工智能 电子邮件:2425613875@qq.com 凭借领先的人工智能与知识图谱技术,对身份证正反面自动识别,并提取姓名、出生日期、身份证号、住址、性别、民族、发证机关

    2024年02月07日
    浏览(41)
  • java从身份证号码中提取出生年月日

    给一个String 类型的 身份证号码,需要从这串数字中获取出生日期、性别、年龄

    2024年02月15日
    浏览(27)
  • 身份证号码,格式校验:@IdCard(Validation + 原生实现校验逻辑)

    自定义一个用于校验 身份证号码 格式的注解 @IdCard ,能够和现有的 Validation 参数校验机制兼容,使用方式和其他校验注解保持一致(使用 @Valid 注解接口参数)。 本文使用原生方式实现校验逻辑,校验规则的实现较为基础;Hutool工具提供了更加完善的校验工具,可以考虑使

    2024年02月07日
    浏览(26)
  • 学以致用——Java验证身份证号码是否正确(带校验算法)

    需求: 验证身份证号码是否正确(带校验算法) 源码: 运行结果:

    2024年02月11日
    浏览(40)
  • 身份证号码的正则表达式及验证详解(JavaScript,Regex)

    简言 在做用户实名验证时,常会用到身份证号码的正则表达式及校验方案。本文列举了两种验证方案,大家可以根据自己的项目实际情况,选择适合的方案 身份证号码说明 居民身份证号码,正确、正式的称谓应该是“公民身份号码”。根据【中华人民共和国国家标准 GB 11

    2023年04月20日
    浏览(29)
  • 常用的表单校验规则——邮箱/QQ/身份证号码/微信/电话/数字字母/整数/文本/密码等

    1.邮箱校验规则 2.邮箱校验规则  3.QQ校验规则 4.身份证号码校验规则   5.微信校验规则 6.电话校验规则  7.银行卡号校验规则  8.数字字母校验规则  9.整数校验规则  10.数字校验规则  11.文本校验规则  12.密码校验规则  最后附上 rules 中的使用方法             

    2024年02月05日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包