当前位置:网站首页>opencv学习笔记四--银行卡号识别
opencv学习笔记四--银行卡号识别
2022-07-01 14:52:00 【Cloudy_to_sunny】
前期步骤
导入工具包
from imutils import contours
import numpy as np
import argparse
import cv2
import myutils
import matplotlib.pyplot as plt#Matplotlib是RGB
指定信用卡类型
# 指定信用卡类型(根据卡号第一位数字)
FIRST_NUMBER = {
"3": "American Express",
"4": "Visa",
"5": "MasterCard",
"6": "Discover Card"
}
定义绘图函数
# 绘图展示
def cv_show(name,img):
b,g,r = cv2.split(img)
img_rgb = cv2.merge((r,g,b))
plt.imshow(img_rgb)
plt.show()
def cv_show1(name,img):
plt.imshow(img)
plt.show()
cv2.imshow(name,img)
cv2.waitKey()
cv2.destroyAllWindows()
读入数据
# 读取一个模板图像
img = cv2.imread("./ocr_a_reference.png")
cv_show('img',img)

# 灰度图
ref = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv_show1('ref',ref)

# 二值图像
ref = cv2.threshold(ref, 10, 255, cv2.THRESH_BINARY_INV)[1]
cv_show1('ref',ref)

模板处理
计算轮廓
#cv2.findContours()函数接受的参数为二值图,即黑白的(不是灰度图),cv2.RETR_EXTERNAL只检测外轮廓,cv2.CHAIN_APPROX_SIMPLE只保留终点坐标
#返回的list中每个元素都是图像中的一个轮廓
ref_, refCnts, hierarchy = cv2.findContours(ref.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(img,refCnts,-1,(0,0,255),3)
cv_show1('img',img)

print (np.array(refCnts).shape)
refCnts = myutils.sort_contours(refCnts, method="left-to-right")[0] #排序,从左到右,从上到下
digits = {
}
(10,)
d:\Miniconda3\envs\learnCV\lib\site-packages\ipykernel_launcher.py:1: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray
"""Entry point for launching an IPython kernel.
# 遍历每一个轮廓
for (i, c) in enumerate(refCnts):
# 计算外接矩形并且resize成合适大小
(x, y, w, h) = cv2.boundingRect(c)
roi = ref[y:y + h, x:x + w]
roi = cv2.resize(roi, (57, 88))
# 每一个数字对应每一个模板
digits[i] = roi
# 初始化卷积核
rectKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9, 3))
sqKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
卡片处理
#读取输入图像,预处理
image = cv2.imread("./images/credit_card_01.png")
cv_show('image',image)
image = myutils.resize(image, width=300)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
cv_show1('gray',gray)


#礼帽操作,突出更明亮的区域
tophat = cv2.morphologyEx(gray, cv2.MORPH_TOPHAT, rectKernel)
cv_show1('tophat',tophat)
# 计算x方向图像梯度
gradX = cv2.Sobel(tophat, ddepth=cv2.CV_32F, dx=1, dy=0, #ksize=-1相当于用3*3的
ksize=-1)

gradX = np.absolute(gradX)
(minVal, maxVal) = (np.min(gradX), np.max(gradX))
gradX = (255 * ((gradX - minVal) / (maxVal - minVal)))
gradX = gradX.astype("uint8")
print (np.array(gradX).shape)
cv_show1('gradX',gradX)
(189, 300)

#通过闭操作(先膨胀,再腐蚀)将数字连在一起
gradX = cv2.morphologyEx(gradX, cv2.MORPH_CLOSE, rectKernel)
cv_show1('gradX',gradX)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8AcGUyGC-1656380868739)(https://gitcode.net/weixin_41756645/csdnimage/-/raw/master/ocr_match_files/ocr_match_19_0.png)]
#THRESH_OTSU会自动寻找合适的阈值,适合双峰,需把阈值参数设置为0
thresh = cv2.threshold(gradX, 0, 255,
cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
cv_show1('thresh',thresh)

#再来一个闭操作
thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, sqKernel) #再来一个闭操作
cv_show1('thresh',thresh)

# 计算轮廓
thresh_, threshCnts, hierarchy = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
cnts = threshCnts
cur_img = image.copy()
cv2.drawContours(cur_img,cnts,-1,(0,0,255),3)
cv_show('img',cur_img)
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])
output = []
# 遍历每一个轮廓中的数字
for (i, (gX, gY, gW, gH)) in enumerate(locs):
# initialize the list of group digits
groupOutput = []
# 根据坐标提取每一个组
group = gray[gY - 5:gY + gH + 5, gX - 5:gX + gW + 5]
cv_show1('group',group)
# 预处理
group = cv2.threshold(group, 0, 255,
cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
cv_show1('group',group)
# 计算每一组的轮廓
group_,digitCnts,hierarchy = cv2.findContours(group.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
digitCnts = contours.sort_contours(digitCnts,
method="left-to-right")[0]
# 计算每一组中的每一个数值
for c in digitCnts:
# 找到当前数值的轮廓,resize成合适的的大小
(x, y, w, h) = cv2.boundingRect(c)
roi = group[y:y + h, x:x + w]
roi = cv2.resize(roi, (57, 88))
cv_show1('roi',roi)
# 计算匹配得分
scores = []
# 在模板中计算每一个得分
for (digit, digitROI) in digits.items():
# 模板匹配
result = cv2.matchTemplate(roi, digitROI,
cv2.TM_CCOEFF)
(_, score, _, _) = cv2.minMaxLoc(result)
scores.append(score)
# 得到最合适的数字
groupOutput.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(groupOutput), (gX, gY - 15),
cv2.FONT_HERSHEY_SIMPLEX, 0.65, (0, 0, 255), 2)
# 得到结果
output.extend(groupOutput)
























# 打印结果
print("Credit Card Type: {}".format(FIRST_NUMBER[output[0]]))
print("Credit Card #: {}".format("".join(output)))
cv_show("Image", image)
#cv2.waitKey(0)
Credit Card Type: Visa
Credit Card #: 4000123456789010

参考
边栏推荐
- idea中新建的XML文件变成普通文件的解决方法.
- MIT团队使用图神经网络,加速无定形聚合物电解质筛选,促进下一代锂电池技术开发
- Markdown编辑器使用基本语法
- What problems should be considered for outdoor LED display?
- 三十之前一定要明白的职场潜规则
- 竣达技术丨室内空气环境监测终端 pm2.5、温湿度TVOC等多参数监测
- One of the data Lake series | you must love to read the history of minimalist data platforms, from data warehouse, data lake to Lake warehouse
- En utilisant le paquet npoi de net Core 6 c #, lisez Excel.. Image dans la cellule xlsx et stockée sur le serveur spécifié
- Solidty智能合约开发-简易入门
- Leetcode (69) -- square root of X
猜你喜欢

Chapter 4 of getting started with MySQL: creation, modification and deletion of data tables

The markdown editor uses basic syntax

Fundamentals of C language

Filter &(登录拦截)

2022-2-15 learning xiangniuke project - Section 1 filtering sensitive words

Microservice development steps (Nacos)

Leetcode (69) -- square root of X

sqlilabs less10

MIT团队使用图神经网络,加速无定形聚合物电解质筛选,促进下一代锂电池技术开发

户外LED显示屏应该考虑哪些问题?
随机推荐
[leetcode 324] 摆动排序 II 思维+排序
The data in the database table recursively forms a closed-loop data. How can we get these data
[15. Interval consolidation]
241. 为运算表达式设计优先级
炎炎夏日,这份安全用气指南请街坊们收好!
Demand prioritization method based on value quantification
TypeScript:const
C 语言进阶
MongoDB第二話 -- MongoDB高可用集群實現
The first word of JVM -- detailed introduction to JVM and analysis of runtime data area
Research Report on the development trend and competitive strategy of the global axis measurement system industry
Minimum spanning tree and bipartite graph in graph theory (acwing template)
从零开发小程序和公众号【第三期】
期末琐碎知识点再整理
Tensorflow 2. X realizes iris classification
Don't want to knock the code? Here comes the chance
Opencv mat class
Take you to API development by hand
[stage life summary] I gave up the postgraduate entrance examination and participated in the work. I have successfully graduated and just received my graduation certificate yesterday
Leetcode (69) -- square root of X