from imutils import contours import numpy as np import argparse import cv2 as cv import myutils def cv_show(name,img): cv.imshow(name,img) cv.waitKey(0) cv.destroyAllWindows() # 先处理template tempalte_img = cv.imread("E:/opencv/picture/ocr_a_reference.png") tempalte_gray = cv.cvtColor(tempalte_img, cv.COLOR_BGR2GRAY) tempalte_thres = cv.threshold(tempalte_gray, 0, 255, cv.THRESH_OTSU | cv.THRESH_BINARY_INV)[1] temp_a, tempalte_contours, temp_b = cv.findContours(tempalte_thres.copy (), cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE) cv.drawContours(tempalte_img, tempalte_contours, -1, (0, 255, 0), 2) tempalte_contours = contours.sort_contours(tempalte_contours, method="left-to-right")[0] digits = {} # 构建一个字典 for (i, c) in enumerate(tempalte_contours): (x, y, w, h) = cv.boundingRect(c) tempalte_roi = tempalte_thres[y:y + h, x:x + w] #之前一直检测不出正确答案,原因是这里的roi应该是tempalte_thres一部分 #而不是template_gray的一部分! tempalte_roi = cv.resize(tempalte_roi, (57, 88)) digits[i] = tempalte_roi cv_show('template_single',tempalte_roi) #cv_show('template_single',tempalte_roi) #对银行卡进行处理,之所以要做成数字长条,是想通过长条的尺寸比例大小来将自己想要的数字给抠出来。 rectkernel = cv.getStructuringElement(cv.MORPH_RECT,(9,3)) squrkernel = cv.getStructuringElement(cv.MORPH_RECT,(5,5)) image = cv.imread("E:/opencv/picture/credit_card_02.png") image = myutils.resize(image, width=300) image_gray = cv.cvtColor(image,cv.COLOR_BGR2GRAY) image_tophat= cv.morphologyEx(image_gray,cv.MORPH_TOPHAT,rectkernel) image_close = cv.morphologyEx(image_tophat,cv.MORPH_CLOSE,rectkernel) cv.imshow("image_tophat",image_tophat) cv.imshow('image_close',image_close) image_thres= cv.threshold(image_close,0,255,cv.THRESH_BINARY|cv.THRESH_OTSU)[1] image_contours= cv.findContours(image_thres.copy(),cv.RETR_EXTERNAL,cv.CHAIN_APPROX_SIMPLE)[1] locs = [] for(n,con) in enumerate(image_contours): (gx,gy,gw,gh)= cv.boundingRect(con) ar = gw/float (gh) if ar > 2.5 and ar < 4.0: if (gw > 40 and gw < 55) and (gh > 10 and gh < 20): # 符合的留下来 locs.append((gx, gy, gw, gh)) #sorted和contours.sort_contours的区别:第二个是针对轮廓的排序 # 将符合的轮廓从左到右排序 sorted针对的是一个list 而sort_countours函数是针对多个轮廓数组 locs = sorted(locs, key=lambda x:x[0]) output = [] for(i,(x,y,w,h))in enumerate(locs): groupOutput = [] group = image_gray[y-5:y+h+5,x-5:x+w+5] group = cv.threshold(group,0,255,cv.THRESH_BINARY|cv.THRESH_OTSU)[1] digcnts = cv.findContours(group.copy(),cv.RETR_EXTERNAL,cv.CHAIN_APPROX_SIMPLE)[1] digcnts = contours.sort_contours(digcnts,method="left-to-right")[0] for c in digcnts: (gx,gy,gw,gh) = cv.boundingRect(c) roi = group[gy:gy+gh,gx:gx+gw]#注意这里是对group进行寻找轮廓的,所以得到的轮廓向量的外接矩形的坐标是针对 #group的 roi = cv.resize(roi, (57, 88)) cv_show('roi',roi) # 计算匹配得分 scores = [] # 在模板中计算每一个得分 #先从第一个group的第一个roi开始作为第一个检测对象,遍历模板字典里各个模板,分别得到对应的匹配结果score #我们取score值最大的对应的字符串作为模板匹配后识别到的第一个结果,并加入到groupOutput里去。 #然后再将第一个group的第二个roi作为第二个检测对象,遍历模板字典里各个模板,分别得到对应的匹配结果score #我们取score值最大的对应的字符串作为模板匹配后识别到的第二个结果,并加入到groupOutput里去。 #以此循环,一共有4*4个roi,所以这个过程要循环16次。最终识别到的结果存储到了groupOutput里去 for (digit, digitROI) in digits.items(): # 模板匹配 result = cv.matchTemplate(roi, digitROI, cv.TM_CCOEFF_NORMED) (_, score, _, _) = cv.minMaxLoc(result) scores.append(score) # 得到最合适的数字 groupOutput.append(str(np.argmax(scores))) cv.rectangle(image, (x - 5, y - 5), (x + w + 5, y + h + 5), (0, 0, 255), 1) cv.putText(image, "".join(groupOutput), (x, y - 15), cv.FONT_HERSHEY_SIMPLEX, 0.65, (0, 0, 255), 2) # 得到结果 output.extend(groupOutput) # 打印结果 cv.imshow("Image", image) cv.waitKey(0)
剩余12页未读,继续阅读
- 粉丝: 2
- 资源: 23
- 我的内容管理 收起
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
会员权益专享
最新资源
- 基于Springboot的医院信管系统
- 基于Springboot的冬奥会科普平台
- 基于Springboot的社区医院管理服务系统
- 基于Springboot的实习管理系统
- TI-TCAN1146.pdf
- 基于Springboot的留守儿童爱心网站
- S32K3XXRM.pdf
- Ansible Automation Platform 快速安装指南 v3.8.1
- Ansible Tower 发行注记 v3.8.1-76页
- C语言笔记-考研版(进阶)
- Design_of_Analog_CMOS_Integrated_Circuit20200602-85440-9wt61m-with-cover-page-v2 (1).pdf
- Ansible Automation Platform 安装和参考指南 v3.8.1-59页
- 浅析5G技术在工业互联网领域的应用研究
- 查重17 岑彩谊-基于otn技术的本地承载网-二稿 .docx
- 自考计算机应用基础知识点.doc
- 数据库系统安全、技术操作规程.doc