当前位置:网站首页>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

参考
边栏推荐
- 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é
- What problems should be considered for outdoor LED display?
- Advanced C language
- Chapter 4 of getting started with MySQL: creation, modification and deletion of data tables
- What value can NPDP bring to product managers? Do you know everything?
- 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 diamond suspension industry
- 适合没口才的人做,加入中视频伙伴计划收益是真香,一个视频拿3份收益
- 关于软件测试的一些思考
- Filter &(登录拦截)
猜你喜欢

idea中新建的XML文件变成普通文件的解决方法.

写在Doris毕业后的第一天

The State Administration of Chia Tai market supervision, the national development and Reform Commission and the China Securities Regulatory Commission jointly reminded and warned some iron ores

The first word of JVM -- detailed introduction to JVM and analysis of runtime data area

JVM performance tuning and practical basic theory part II

Buuctf reinforcement question ezsql

【15. 区间合并】

JVM performance tuning and practical basic theory part II

What problems should be considered for outdoor LED display?

Internet hospital system source code hospital applet source code smart hospital source code online consultation system source code
随机推荐
DirectX修复工具V4.1公测![通俗易懂]
qt捕获界面为图片或label显示
Mongodb second call -- implementation of mongodb high availability cluster
It's suitable for people who don't have eloquence. The benefits of joining the China Video partner program are really delicious. One video gets 3 benefits
Filter &(登录拦截)
Research Report on the development trend and competitive strategy of the global diamond suspension industry
Build your own website (14)
Reorganize the trivial knowledge points at the end of the term
DirectX repair tool v4.1 public beta! [easy to understand]
Problem note - Oracle 11g uninstall
What problems should be considered for outdoor LED display?
Opencv mat class
JVM performance tuning and practical basic theory part II
首届技术播客月开播在即
Yyds dry goods inventory hcie security day13: firewall dual machine hot standby experiment (I) firewall direct deployment, uplink and downlink connection switches
数字化转型:数据可视化赋能销售管理
Salesforce、约翰霍普金斯、哥大 | ProGen2: 探索蛋白语言模型的边界
Mongodb second talk - - mongodb High available Cluster Implementation
Use the npoi package of net core 6 C to read excel Pictures in xlsx cells and stored to the specified server
tensorflow2-savedmodel convert to tflite