本篇博客的学习视频: 基于python的Opencv项目实战-09项目实战-信用卡数字识别
实现与分析
- 信用卡
输出序列:4000 1234 5678 9010
- 如何实现?
使用模板匹配
要
选择合适的模板
,例如上图中的两幅图中的8的模样要是相同的,6、1等数字都要相同才可以称作一个模板。
- 现在有模板了,那如何单独拿出模板中的数字呢?
轮廓检测
具体步骤:
- 对模板和输入图像进行轮廓检测,一般得到两个轮廓:外轮廓、内轮廓。本项目选择
外轮廓
。- 得到轮廓之后需要得到当前检测的轮廓的
外接矩形
。(模板和输入图像都需要)- 使用信用卡中的数字对模板中的数字进行for循环(10次:一共10个数字),匹配过程中需要
resize
(保证外接矩形大小相同)。- 需要过滤信用卡中的不符合数字的轮廓
一、代码步骤解析
- 项目源码
关于这个项目的源码网络上有很多,在此给大家一个链接:python OpenCV 信用卡数字识别
- 步骤详细解析
我的步骤和别人的步骤不同,我是将所有代码写在一个文件,具体看代码中的调用就会发现
import cv2
import numpy as np
# 对轮廓进行排序
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
#用一个最小的矩形,把找到的形状包起来x,y,h,w
boundingBoxes = [cv2.boundingRect(c) for c in cnts]
# print(boundingBoxes)
(cnts, boundingBoxes) = zip(*sorted(zip(cnts, boundingBoxes),
key=lambda b: b[1][i], reverse=reverse))
print('i=',i)
return cnts,boundingBoxes
zip(*sorted(zip(cnts, boundingBoxes),key=lambda b: b[1][i], reverse=reverse))
- 这句代码有疑问的看这篇文章:python-zip()函数、lambda、map的单独与结合使用
这篇文章也是我写的,因为我第一次看到这句代码时也是不懂得,自己就查资料总结在一起
# 重新调整大小
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
# 显示图像 -写成了方法
def cv_show(name,img):
cv2.imshow(name,img)
# cv2.imshow()方法一定要和下面两条代码一起使用
cv2.waitKey(0)
cv2