博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python-OpenCV信用卡数字识别
阅读量:4101 次
发布时间:2019-05-25

本文共 4956 字,大约阅读时间需要 16 分钟。

© Fu Xianjun. All Rights Reserved

文章目录


前言

随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。


一、数字识别是什么?

进行识别和匹配,将提取出来的数字与模板数字(需要自己创建)进行比较,这里采用两幅图片像素相减的方法,寻找出差值最小的图片即为最匹配的数字

二、使用步骤

1.引入库

代码如下:

import cv2import numpy as np

2.读入数据

代码如下:

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(cnt) for cnt in cnts]    (cnts,boundingBoxes) = zip(*sorted(zip(cnts, boundingBoxes),\                                      key = lambda b: b[1][i],\                                       reverse= reverse))    return cnts, boundingBoxes
# 读取模板图片template = cv2.imread('ocr_a_reference.png')cv_show('template', template)# 模板图片灰度化。这里的模板图片本身就是二值化的因此没有明显区别。template_gray = cv2.cvtColor(template, cv2.COLOR_BGR2GRAY)cv_show('templage_gray', template_gray)# 二值化,转化为数字为白色,背景为黑色的图片。template_binary = cv2.threshold(template_gray, 127, 255, cv2.THRESH_BINARY_INV)[1]cv_show('template_binary', template_binary)
# 根据二值化的模板图,进行轮廓检测cnts, hierarchy = cv2.findContours(template_binary                                                   , cv2.RETR_EXTERNAL                                                   , cv2.CHAIN_APPROX_SIMPLE)# 画出每个数字的轮廓template_rect = cv2.drawContours(template.copy(), cnts, -1, (0,0,255), 2)cv_show('template_rect', template_rect)# 对十个数字根据左上角的位置进行排序,这样数字按照从小到大的顺序排列出来。cnts = sort_contours(cnts, method="left-to-right")[0]number = {}# 根据排列的结果,将每个数字截取出来。将每个数字图片所对应的数字对应起来。# 这里要注意,对像素值进行取值时,数组的行对应的是图片的y轴,列对应的图片的x轴。for (i, cnt) in enumerate(cnts):    (x,y,w,h) = cv2.boundingRect(cnt)    roi = template_binary[y:y+h, x:x+w]    roi = cv2.resize(roi, (57,88))        number[i] = roi


2.对信用卡信息进行处理,去除多余的背景信息。

cv_show(f"number1",number[3])
cardImg = cv2.imread('credit_card_03.png')cardImg = cv2.resize(cardImg, \                    (300, int(float(300 / cardImg.shape[1]) * cardImg.shape[0])),\                     interpolation=cv2.INTER_AREA)cardImg_gray = cv2.cvtColor(cardImg, cv2.COLOR_BGR2GRAY)cv_show('cardImg_gray', cardImg_gray)rectKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (7,7))sqKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))cardImg_tophat = cv2.morphologyEx(cardImg_gray, cv2.MORPH_TOPHAT, rectKernel)cv_show('cardImg_tophat', cardImg_tophat)

3.对信用卡上的数字进行选取,对于非卡号数字进行剔除。

sobelx = cv2.Sobel(cardImg_tophat, cv2.CV_64F, 1, 0, ksize=3)sobelx = cv2.convertScaleAbs(sobelx)(minX, maxX) = (np.min(sobelx), np.max(sobelx))sobelx = (255 * ((sobelx - minX) / (maxX - minX)))sobelx = sobelx.astype('uint8')cv_show('sobelx', sobelx)cardImg_close = cv2.morphologyEx(sobelx, cv2.MORPH_CLOSE, rectKernel)cv_show('cardImg_close', cardImg_close)cardImg_binary = cv2.threshold(cardImg_close, 0, 255, cv2.THRESH_OTSU | cv2.THRESH_BINARY)[1]cv_show('cardImg_binary', cardImg_binary)cardImg_close = cv2.morphologyEx(cardImg_binary, cv2.MORPH_CLOSE, sqKernel)cv_show('cardImg_close', cardImg_close)
cnts, hierarchy = cv2.findContours(cardImg_close                                             , cv2.RETR_EXTERNAL                                             , cv2.CHAIN_APPROX_SIMPLE)cardImg_cnts = cv2.drawContours(cardImg.copy(), cnts, -1, (0,0,255), 2)locs = []for (i, c) in enumerate(cnts):    (x, y, w, h) = cv2.boundingRect(c)    ar = w / float(h)    if ar > 2.5 and ar < 4.0:        if (w > 40 and w < 55) and (h > 10 and h < 20):            locs.append((x, y, w, h))locs = sorted(locs, key=lambda x: x[0])for (x, y, w, h) in locs:    cv2.rectangle(cardImg_cnts, (x,y),(x+w,y+h),(0,0,255),3)cv_show('cardImg_cnts', cardImg_cnts)

4.得到卡号区域后,对卡号进行数字划分。进行模板匹配,得到每个数字图像所对应的数字。

output = []# 对每个4数字块进行处理for (i, (x, y, w, h)) in enumerate(locs):    group_output = []    group = cardImg_gray[y-5:y + h + 5, x-5:x + w + 5]    group = cv2.threshold(group, 0, 255, cv2.THRESH_OTSU|cv2.THRESH_BINARY)[1]    cv_show('group', group)    group_cnts, group_hierarchy = cv2.findContours(group, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)    group_cnts = sort_contours(group_cnts, method="left-to-right")[0]    # 分割每个数字    for cnt in group_cnts:        (nx,ny,nw,nh) = cv2.boundingRect(cnt)        roi = group[ny:ny+nh, nx:nx+nw]        roi = cv2.resize(roi, (57, 88))#         cv_show('roi', roi)        score = []        # 对每个数字进行模板匹配        for (number_i, number_roi) in number.items():            result = cv2.matchTemplate(roi, number_roi, cv2.TM_CCOEFF)            score_ = cv2.minMaxLoc(result)[1]            score.append(score_)        group_output.append(str(np.argmax(score)))   # 绘制每个数字    cv2.rectangle(cardImg, (x - 5, y - 5),                  (x + w + 5, y + h + 5), (0, 0, 255), 1)    cv2.putText(cardImg, "".join(group_output), (x, y - 15),                cv2.FONT_HERSHEY_SIMPLEX, 0.65, (0, 0, 255), 2)    output.append(group_output)cv_show('cardImg', cardImg)


总结

以上就是今天要讲的内容,本文仅仅简单介绍了python中数字识别的使用,而python提供了大量能使我们快速便捷地处理数据的函数和方法。

转载地址:http://zuusi.baihongyu.com/

你可能感兴趣的文章
一种较方便在Android中添加开机自启动的守护进程的方法
查看>>
android4.0 上定制状态栏
查看>>
Android全屏 去除标题栏和状态栏
查看>>
有效获取状态栏(StatusBar)高度
查看>>
Ubuntu下用eclipse进行源码开发注意事项
查看>>
浅析android UI 定制
查看>>
Android statusBar添加back,home,menu按钮 .
查看>>
android怎么修改状态栏集锦
查看>>
Android基础教程之---Android状态栏提醒(Notification,NotificationManager)的使用! .
查看>>
【Android】状态栏通知Notification、NotificationManager详解
查看>>
如何在Android 4.0 ICS中禁用StatusBar | SystemBar | 状态栏
查看>>
android ics SystemUI详解
查看>>
android systemUI--Notification 整理
查看>>
状态栏SystemUI的启动过程
查看>>
Android状态栏功能介绍
查看>>
Notification的显示过程
查看>>
Android init 启动过程分析1
查看>>
Android init 启动过程分析2
查看>>
关于android 系统开发文章整理
查看>>
状态栏的定制
查看>>