天天新消息丨Python+OpenCV实现信用卡数字识别的方法详解
目录
一、模板图像处理二、信用卡图片预处理一、模板图像处理
(1)灰度图、二值图转化
(相关资料图)
template = cv2.imread("C:/Users/bwy/Desktop/number.png") template_gray = cv2.cvtColor(template, cv2.COLOR_BGR2GRAY) cv_show("template_gray", template_gray) # 形成二值图像,因为要做轮廓检测 ret, template_thresh = cv2.threshold(template_gray, 127, 255, cv2.THRESH_BINARY_INV) cv_show("template_thresh", template_thresh)
结果如图所示:
(2)进行轮廓提取接受参数为二值图像,得到数字的信息,RETR_EXTERNAL 就是只是需要外轮廓,cv2.CHAIN_APPROX_SIMPLE只保留终点坐标。
template_contours, hierarchy = cv2.findContours(template_thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) cv2.drawContours(template,template_contours,-1,(0,0,255),2) cv_show("template",template)
-1:代表所的轮廓,我们这里画出来10个轮廓。(可以用代码验证一下)
print(np.array(refCnts,-1,(0,0,255),3)
结果:10
结果如图所示:
(3)我们需要将轮廓进行大小排序(我们拿到的数据模板不一定向我们前面所展示的从0-9按顺序的,所以我们需要进行排序、resize。
def contours_sort(contours, method=0): if method == 0: contours = sorted(contours, key=lambda x: cv2.boundingRect(x)[0]) else: contours = sorted(contours, key=lambda x: cv2.boundingRect(x)[0], reverse=True) return contours
我们调用函数#将轮廓排序,位置从小到大就是数字的信息。然后我们遍历模板,使用cv2.boudingRect获得轮廓的位置,提取位置对应的图片,与数字结合构造成模板字典,dsize = (55, 88),统一大小。
dict_template = {} for i, contour in enumerate(template_contours): # 画出其外接矩阵,获得其位置信息 x, y, w, h = cv2.boundingRect(contour) template_img = template_thresh[y:y + h, x:x + w] # 使用cv2.resize变化模板的大小 template_img = cv2.resize(template_img, dsize) cv_show("template_img{}".format(i), template_img) dict_template[i] = template_img
结果如图所示:
。。。。。。。。。。
二、信用卡图片预处理
(1)进行灰度值
card_gray = cv2.cvtColor(card, cv2.COLOR_BGR2GRAY) cv_show("card_gray",card_gray)
(2)形成二值图像,因为要做轮廓检测,解释参数:THRESH_OTSU会自动寻找合适的阈值,适合双峰,需要阈值参数设置为零 二值化
card_thresh =cv2.threshold(card_gray,0,255,cv2.THRESH_BINARY|cv2.THRESH_OTSU)[1] cv_show("card_thresh",card_thresh)
结果如图所示:
(3)我们观察一下图片,我们识别图片上的数字但也会存在黄框和红框中的干扰,这时候我们可以想到前面所学到的形态学操作礼帽,闭运算...
先进行礼帽操作,突出更明亮的区域:
kernel=np.ones((9,3),np.uint8) card_tophat=cv2.morphologyEx(card_gray,cv2.MORPH_TOPHAT,kernel) cv_show("card_tophat",card_tophat)
结果如图:
(4)我们进行图像的轮廓检测只取外轮廓。在这个图上有不同的区域,我们如何区分呢,我们可以用h的大小进行估计,这个数据根据项目而定
bankcard_contours, hierarchy = cv2.findContours(card_thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) banck_card_cnts = [] draw_img = card.copy() for i, contour in enumerate(bankcard_contours): x, y, w, h = cv2.boundingRect(contour) # 数字的x 坐标在 一定的位置范围 if 0.5 * card_h < y < 0.6 * card_h: banck_card_cnts.append((x, y, w, h)) draw_img = cv2.rectangle(draw_img, pt1=(x, y), pt2=(x + w, y + h), color=(0, 0, 255), thickness=2) # 画出这个矩形,会在原图上画 cv_show_image("rectangle_contours_img", draw_img)
结果如图:
(5)模板匹配,读出图像。
for i, locs in enumerate(banck_card_cnts): x, y, w, h = locs[:] # 保留了在原始图像的位置信息 dst_img = card_thresh[y:y + h, x:x + w] # 获得当前图像的位置和区域 dst_img = cv2.resize(dst_img, dsize) cv_show("rectangle_contours_img", dst_img) tm_vals = {} for number, temp_img in dict_template.items(): # 模板匹配,采用计算相关性系数,值越大越相关 res = cv2.matchTemplate(dst_img, temp_img, cv2.TM_CCOEFF_NORMED) min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res) tm_vals[number] = max_val number_tm = max(tm_vals, key=tm_vals.get) # 在图像上画出结果来 draw_img = cv2.rectangle(draw_img, pt1=(x, y), pt2=(x + w, y + h), color=(0, 0, 255), thickness=2) cv2.putText(draw_img, str(number_tm), (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.65, color=(0, 0, 255), thickness=2) cv_show_image("final_result", draw_img)
结果如图所示:
只是展示一部分(倒序输出)
到此这篇关于Python+OpenCV实现信用卡数字识别的方法详解的文章就介绍到这了,更多相关Python OpenCV信用卡数字识别内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
X 关闭
X 关闭
- 15G资费不大降!三大运营商谁提供的5G网速最快?中国信通院给出答案
- 2联想拯救者Y70发布最新预告:售价2970元起 迄今最便宜的骁龙8+旗舰
- 3亚马逊开始大规模推广掌纹支付技术 顾客可使用“挥手付”结账
- 4现代和起亚上半年出口20万辆新能源汽车同比增长30.6%
- 5如何让居民5分钟使用到各种设施?沙特“线性城市”来了
- 6AMD实现连续8个季度的增长 季度营收首次突破60亿美元利润更是翻倍
- 7转转集团发布2022年二季度手机行情报告:二手市场“飘香”
- 8充电宝100Wh等于多少毫安?铁路旅客禁止、限制携带和托运物品目录
- 9好消息!京东与腾讯续签三年战略合作协议 加强技术创新与供应链服务
- 10名创优品拟通过香港IPO全球发售4100万股 全球发售所得款项有什么用处?