银行卡数字识别
下面展示一些 内联代码片
。
import cv2
import matplotlib.pyplot as py
import numpy as np
import myutils
def cv_show(name,image):
cv2.imshow(name,image)
cv2.waitKey(0)
cv2.destroyAllWindows()
def sort_contours(contours, 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 contours] # 用一个最小的矩形,把找到的形状包起来x,y,h,w
(cnts, boundingBoxes) = zip(*sorted(zip(contours, boundingBoxes),
key=lambda b: b[1][i], reverse=reverse))
return cnts, boundingBoxes
def resize(image, width=None, height=None, inter=cv2.INTER_AREA):
dim = None
(h, w) = image.shape[:2]
if width is None and height is None:
return image
if width is None:
r = height / float(h)
dim = (int(w * r), height)
else:
r = width / float(w)
dim = (width, int(h * r))
resized = cv2.resize(image, dim, interpolation=inter)
return resized
# 读入数字图片
card = cv2.imread('E:/pythoncode/imageofopencv/ocr_a_reference.png')
cv_show('card',card)
# 彩色图片转换为灰度图
card1 = cv2.cvtColor(card,cv2.COLOR_BGR2GRAY)
cv_show('card1',card1)
# 灰度图转换为二值图
card2 = cv2.threshold(card1,10,255,cv2.THRESH_BINARY_INV)[1]
cv_show('card2',card2)
# 查找轮廓(cv2.RETR_EXTERNAL----只检测外轮廓 cv2.CHAIN_APPROX_SIMPLE------只保留终点坐标)
contours,hierarchy = cv2.findContours(card2.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
# 绘制轮廓(-1---代表绘制所有轮廓)
card3 = cv2.drawContours(card,contours,-1,(0,0,255),5)
cv_show('card3',card3)
# 对外轮廓进行排序
contours = sort_contours(contours,method = 'left-to-right')[0]
# 把每一个轮廓组成字典(0轮廓对应数字0)
a1 = {}
for (c,d) in enumerate(contours):
x,y,w,h = cv2.boundingRect(d)
e = card2[y:y+h,x:x+w]
e = cv2.resize(e,(60,100))
a1[c] = e
# 生成两个核
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(9,3))
kernel1 = cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))
# 读入图片
image = cv2.imread('E:/pythoncode/imageofopencv/credit_card_01.png')
cv_show('image',image)
# 设置图片大小
image = resize(image,width = 300)
# 彩色图转化为灰度图
image1 = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
cv_show('image1',image1)
# 礼帽操作,使得亮的的区域更加明亮
image2 = cv2.morphologyEx(image1,cv2.MORPH_TOPHAT,kernel)
cv_show('image2',image2)
# 使用sobel算子提取边缘信息
sobelx = cv2.Sobel(image2,cv2.CV_64F,1,0)
sobely = cv2.Sobel(image2,cv2.CV_64F,0,1)
sobelx = cv2.convertScaleAbs(sobelx)
sobely = cv2.convertScaleAbs(sobely)
sobelxy = cv2.addWeighted(sobelx,0.5,sobely,0.5,0)
cv_show('sobelxy',sobelxy)
# 通过闭操作,把数字连到一起。
image3 = cv2.morphologyEx(sobelxy,cv2.MORPH_CLOSE,kernel)
cv_show('image3',image3)
# 二值化
image4 = cv2.threshold(image3,0,255,cv2.THRESH_OTSU)[1]
cv_show('image4',image4)
# 在进行一次闭操作使得数字连接的更紧密
image5 = cv2.morphologyEx(image4,cv2.MORPH_CLOSE,kernel1)
cv_show('image5',image5)
# 查找轮廓(cv2.RETR_EXTERNAL----只检测外轮廓 cv2.CHAIN_APPROX_SIMPLE------只保留终点坐标)
contours,hierarchy = cv2.findContours(image5.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
# 绘制轮廓(-1---代表绘制所有轮廓)
image6 = cv2.drawContours(image.copy(),contours,-1,(0,0,255),3)
cv_show('image6',image6)
# 过滤一些轮廓
x1 = []
for m,n in enumerate(contours):
x,y,w,h = cv2.boundingRect(n)
l = w /float(h)
if 2.5 < l < 4.0:
if (40 < w < 55) and ( 10 < h < 20):
x1.append((x,y,w,h))
x1 = sorted(x1,key=lambda k:k[0])
# 把想要的轮廓截取出来
for q,(gx,gy,gw,gh) in enumerate(x1):
n = []
image7 = image1[gy-5:gy+gh+5,gx-5:gx+gw+5]
cv_show('image7',image7)
image7 = cv2.threshold(image7, 0, 255, cv2.THRESH_OTSU)[1] # 二值化
contours, hierarchy = cv2.findContours(image7.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 寻找轮廓
contours = sort_contours(contours, method='left-to-right')[0]
for i in contours:
x, y, w, h = cv2.boundingRect(i)
e = image7[y:y + h, x:x + w]
e = cv2.resize(e, (60, 100))
cv_show('e',e)
scores = []
for a,b in a1.items():
result = cv2.matchTemplate(e,b,cv2.TM_CCOEFF)
_,g,_,_ = cv2.minMaxLoc(result)
scores.append(g)
n.append(str(np.argmax(scores)))
#画出来每一个轮廓
cv2.rectangle(image,(gx-5,gy-5),(gx+gw+5,gy+gh+5),(0,0,255),1)
cv2.putText(image,''.join(n),(gx,gy-20),cv2.FONT_HERSHEY_SIMPLEX,0.65,(0,0,255),2)
cv_show('image',image)