1.首先下载opencv-python库,这个库的版本一定要固定

pip install opencv-python==4.1.2.30

2.准备下载模板图片,如下,在代码中命名为1.jpg

3.准备一个银行卡图片,在代码中命名为3.jpg

4.处理模板代码如下,该代码是为了匹配银行卡数字模板

import cv2
import numpy as np
import imutils
from imutils import contours# filepath = 'D:\\openCVImage\\bankCard'def cv_show(name, img):cv2.imshow(name, img)cv2.waitKey(0)cv2.destroyAllWindows()# 处理模板
def temp_deal():# 读取模板图像tempImage = cv2.imread("1.jpg")# cv_show("temp", tempImage)# 转换灰度图,颜色改变函数tempGray = cv2.cvtColor(tempImage, cv2.COLOR_BGR2GRAY)# 二值化处理,图像阈值函数,像素值超过127变成0,否则变成255  反二值化,高亮突出数字ret, tempBinary = cv2.threshold(tempGray, 127, 255, cv2.THRESH_BINARY_INV)# image_Binary = cv2.threshold(image_Gray, 177, 255, cv2.THRESH_BINARY_INV)[1]   # 转换为二值化图像,[1]表示返回二值化图像,[0]表示返回阈值177# cv_show("tempBinary", tempBinary)# 返回轮廓信息和轮廓层数contours, hierarchy = cv2.findContours(tempBinary.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)  # 轮廓检测。第1个参数是二值图。第2个参数检测最外层轮廓,第3个参数保留轮廓终点坐标# 绘制轮廓drawTemp = tempImage.copy()  # 复制一份原图像作为画板,不能在原图上画,不然原图会改变res = cv2.drawContours(drawTemp, contours, -1, (0, 0, 255), 2)  # "-1"是指在画板上画出所有轮廓信息,红色,线宽为2# cv_show("drawTempImage", res)# 模板轮廓排序# 详细解释参考:使用Python和OpenCV对轮廓进行排序(从左到右,自上而下)# 原理求每一个轮廓的外接矩形也就是轮廓拟合,根据返回的左上坐标点,就能判断出轮廓的位置,再排序# boxing中存放每次计算轮廓外接矩形得到的x、y、w、h,它的shape为(10,4)。cnt存放每一个轮廓# 轮廓排序核心思想为先求出每个轮廓的外接矩形框,然后通过对外接框按照x或y坐标排序进⽽来实现对轮廓的排序.refCnts = imutils.contours.sort_contours(contours, method="left-to-right")[0]  # 排序,从左到右,从上到下digits = {}# 遍历每一个轮廓for (i, c) in enumerate(refCnts):  # 返回轮廓下标和对应的轮廓值# 计算外接矩形并且resize成合适大小(x, y, w, h) = cv2.boundingRect(c)  # 轮廓拟合,中存放的是每个轮廓1 2 3 。。。。的最小矩形信息roi = tempBinary[y:y + h, x:x + w]  # tempBinary中依次保存的是高和宽,即(y,x)# 将每个区域对应一个数字roi = cv2.resize(roi, (55, 85))  # roi区域统一大小,根据自己需求来定digits[i] = roi# print(digits)return digits

5.然后处理待识别银行卡图片的代码如下

def bankCard_deal(digits):# 初始化卷积核rectKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9, 3))myKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))img = cv2.imread("3.jpg")# cv_show("img", img)img = imutils.resize(img, width=300)gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 礼帽操作,突出更明亮的区域tophat = cv2.morphologyEx(gray, cv2.MORPH_TOPHAT, rectKernel)# cv_show("tophat", tophat)# 利用Sobel算子进行边缘检测gradX = cv2.Sobel(tophat, ddepth=cv2.CV_32F, dx=1, dy=0, ksize=-1)gradY = cv2.Sobel(tophat, ddepth=cv2.CV_32F, dx=0, dy=1, ksize=-1)gradX = np.absolute(gradX)minVal = np.min(gradX)maxVal = np.max(gradX)gradX = (255 * ((gradX - minVal) / (maxVal - minVal)))gradX = gradX.astype("uint8")print(np.array(gradX).shape)# cv_show("gradX", gradX)# 通过闭操作,先膨胀后腐蚀,将数字连接在一块gradX = cv2.morphologyEx(gradX, cv2.MORPH_CLOSE, rectKernel)# cv_show("gradXclose", gradX)thresh = cv2.threshold(gradX, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]# cv_show('threshImg', thresh)# 再来一个闭操作thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, myKernel)# cv_show('gradXclose2', thresh)# 计算轮廓threshCnts, hierarchy = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)cnts = threshCntscur_img = img.copy()cv2.drawContours(cur_img, cnts, -1, (0, 0, 255), 2)# cv_show('imgCopy', cur_img)locs = []# 遍历轮廓,提取轮廓,需要尝试for (i, c) in enumerate(cnts):# 计算矩形(x, y, w, h) = cv2.boundingRect(c)ar = w / float(h)# 选择合适的区域,根据实际任务来,这里的基本都是四个数字一组# [(454, 213, 110, 29), (308, 211, 109, 31), (171, 211, 98, 31), (18, 211, 107, 31)]if 2.5 < ar < 5.0:if (40 < w < 65) and (10 < h < 20):# 符合的留下来locs.append((x, y, w+2, h+2))res = cv2.rectangle(img.copy(), (x, y), (x + w+2, y + h+2), (0, 0, 255), 2)  # "-1"是指在画板上画出所有轮廓信息,红色,线宽为2cv_show("imgRect", res)# 将符合的轮廓从左到右排序locs = sorted(locs, key=lambda o: o[0])output = []# 四组轮廓for (i, (gx, gy, gw, gh)) in enumerate(locs):groupOutput = []group = gray[gy - 5:gy + gh + 5, gx - 5:gx + gw + 5]group = cv2.threshold(group, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]cv_show("groupThreshold", group)  # 1234;5678;digitCnts, his = cv2.findContours(group.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)  # 提取轮廓内数字1,2,3,4digitCnts = imutils.contours.sort_contours(digitCnts, method="left-to-right")[0]  # 对找到的轮廓进行排序  按照X轴坐标# 计算每一组中的每一个数值for c in digitCnts:  # 每组数字1,2,3,4# 找到当前数值的轮廓,resize成合适的大小(x, y, w, h) = cv2.boundingRect(c)  # 具体数字roi = group[y:y + h, x:x + w]  # 数字在每组group中的坐标# 将每个区域对应一个数字roi = cv2.resize(roi, (65, 99))  # roi区域统一大小,根据自己需求来定# cv_show('roi',roi)scores = []for (digitKey, digitROIValue) in digits.items():  # 识别图的roi数字与模板里每个数字matchTemplateresult = cv2.matchTemplate(roi, digitROIValue, cv2.TM_CCOEFF_NORMED)# 返回最值及最值位置,在这里我们需要的是最小值的得分,不同的匹配度计算方法的选择不同min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)scores.append(max_val)  # 最大值score = np.abs(scores)  # 有负数出现,统一成正数,相关系数都变成正数flag = Falsefor val in score:if val > 0.9:flag = Truebreakif not flag:best_index = np.argmax(score)  # score最大值的下标,匹配度最高best_value = str(best_index)  # 下标就是对应的数字,在字典中,key是0对应的是值为0的图片groupOutput.append(best_value)cv2.rectangle(img, (gx - 5, gy - 5), (gx + gw + 5, gy + gh + 5), (0, 0, 255), 1)# 在矩形框上绘图cv2.putText(img, ''.join(groupOutput), (gx, gy - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.65, (0, 0, 255), 2)output.append(groupOutput)cv_show('img', img)# print('数字为:', output)for i in output:for j in i:print(j,end="")

5.如果我们更换图片时,我们需要修改的代码地方有两处,第一处是选择的银行卡的数字区域,自己换图片时需要修改如下参数

        if 2.5 < ar < 5.0:if (40 < w < 65) and (10 < h < 20):# 符合的留下来locs.append((x, y, w+2, h+2))res = cv2.rectangle(img.copy(), (x, y), (x + w+2, y + h+2), (0, 0, 255), 2)  # "-1"是指在画板上画出所有轮廓信息,红色,线宽为2cv_show("imgRect", res)


6.第二个要修改的地方是匹配数字模板上的银行卡数字图片的宽度和高度

roi = cv2.resize(roi, (65, 99))


7.完整代码如下

import cv2
import numpy as np
import imutils
from imutils import contours# filepath = 'D:\\openCVImage\\bankCard'def cv_show(name, img):cv2.imshow(name, img)cv2.waitKey(0)cv2.destroyAllWindows()# 处理模板
def temp_deal():# 读取模板图像tempImage = cv2.imread("1.jpg")# cv_show("temp", tempImage)# 转换灰度图,颜色改变函数tempGray = cv2.cvtColor(tempImage, cv2.COLOR_BGR2GRAY)# 二值化处理,图像阈值函数,像素值超过127变成0,否则变成255  反二值化,高亮突出数字ret, tempBinary = cv2.threshold(tempGray, 127, 255, cv2.THRESH_BINARY_INV)# image_Binary = cv2.threshold(image_Gray, 177, 255, cv2.THRESH_BINARY_INV)[1]   # 转换为二值化图像,[1]表示返回二值化图像,[0]表示返回阈值177# cv_show("tempBinary", tempBinary)# 返回轮廓信息和轮廓层数contours, hierarchy = cv2.findContours(tempBinary.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)  # 轮廓检测。第1个参数是二值图。第2个参数检测最外层轮廓,第3个参数保留轮廓终点坐标# 绘制轮廓drawTemp = tempImage.copy()  # 复制一份原图像作为画板,不能在原图上画,不然原图会改变res = cv2.drawContours(drawTemp, contours, -1, (0, 0, 255), 2)  # "-1"是指在画板上画出所有轮廓信息,红色,线宽为2# cv_show("drawTempImage", res)# 模板轮廓排序# 详细解释参考:使用Python和OpenCV对轮廓进行排序(从左到右,自上而下)# 原理求每一个轮廓的外接矩形也就是轮廓拟合,根据返回的左上坐标点,就能判断出轮廓的位置,再排序# boxing中存放每次计算轮廓外接矩形得到的x、y、w、h,它的shape为(10,4)。cnt存放每一个轮廓# 轮廓排序核心思想为先求出每个轮廓的外接矩形框,然后通过对外接框按照x或y坐标排序进⽽来实现对轮廓的排序.refCnts = imutils.contours.sort_contours(contours, method="left-to-right")[0]  # 排序,从左到右,从上到下digits = {}# 遍历每一个轮廓for (i, c) in enumerate(refCnts):  # 返回轮廓下标和对应的轮廓值# 计算外接矩形并且resize成合适大小(x, y, w, h) = cv2.boundingRect(c)  # 轮廓拟合,中存放的是每个轮廓1 2 3 。。。。的最小矩形信息roi = tempBinary[y:y + h, x:x + w]  # tempBinary中依次保存的是高和宽,即(y,x)# 将每个区域对应一个数字roi = cv2.resize(roi, (55, 85))  # roi区域统一大小,根据自己需求来定digits[i] = roi# print(digits)return digits# 处理待识别银行卡图片
def bankCard_deal(digits):# 初始化卷积核rectKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9, 3))myKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))img = cv2.imread("3.jpg")# cv_show("img", img)img = imutils.resize(img, width=300)gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 礼帽操作,突出更明亮的区域tophat = cv2.morphologyEx(gray, cv2.MORPH_TOPHAT, rectKernel)# cv_show("tophat", tophat)# 利用Sobel算子进行边缘检测gradX = cv2.Sobel(tophat, ddepth=cv2.CV_32F, dx=1, dy=0, ksize=-1)gradY = cv2.Sobel(tophat, ddepth=cv2.CV_32F, dx=0, dy=1, ksize=-1)gradX = np.absolute(gradX)minVal = np.min(gradX)maxVal = np.max(gradX)gradX = (255 * ((gradX - minVal) / (maxVal - minVal)))gradX = gradX.astype("uint8")# print(np.array(gradX).shape)# cv_show("gradX", gradX)# 通过闭操作,先膨胀后腐蚀,将数字连接在一块gradX = cv2.morphologyEx(gradX, cv2.MORPH_CLOSE, rectKernel)# cv_show("gradXclose", gradX)thresh = cv2.threshold(gradX, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]# cv_show('threshImg', thresh)# 再来一个闭操作thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, myKernel)# cv_show('gradXclose2', thresh)# 计算轮廓threshCnts, hierarchy = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)cnts = threshCntscur_img = img.copy()cv2.drawContours(cur_img, cnts, -1, (0, 0, 255), 2)# cv_show('imgCopy', cur_img)locs = []# 遍历轮廓,提取轮廓,需要尝试for (i, c) in enumerate(cnts):# 计算矩形(x, y, w, h) = cv2.boundingRect(c)ar = w / float(h)# 选择合适的区域,根据实际任务来,这里的基本都是四个数字一组# [(454, 213, 110, 29), (308, 211, 109, 31), (171, 211, 98, 31), (18, 211, 107, 31)]if 2.5 < ar < 5.0:if (40 < w < 65) and (10 < h < 20):# 符合的留下来locs.append((x, y, w+2, h+2))# res = cv2.rectangle(img.copy(), (x, y), (x + w+2, y + h+2), (0, 0, 255), 2)  # "-1"是指在画板上画出所有轮廓信息,红色,线宽为2# cv_show("imgRect", res)# 将符合的轮廓从左到右排序locs = sorted(locs, key=lambda o: o[0])output = []# 四组轮廓for (i, (gx, gy, gw, gh)) in enumerate(locs):groupOutput = []group = gray[gy - 5:gy + gh + 5, gx - 5:gx + gw + 5]group = cv2.threshold(group, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]# cv_show("groupThreshold", group)  # 1234;5678;digitCnts, his = cv2.findContours(group.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)  # 提取轮廓内数字1,2,3,4digitCnts = imutils.contours.sort_contours(digitCnts, method="left-to-right")[0]  # 对找到的轮廓进行排序  按照X轴坐标# 计算每一组中的每一个数值for c in digitCnts:  # 每组数字1,2,3,4# 找到当前数值的轮廓,resize成合适的大小(x, y, w, h) = cv2.boundingRect(c)  # 具体数字roi = group[y:y + h, x:x + w]  # 数字在每组group中的坐标# 将每个区域对应一个数字roi = cv2.resize(roi, (65, 99))  # roi区域统一大小,根据自己需求来定# cv_show('roi',roi)scores = []for (digitKey, digitROIValue) in digits.items():  # 识别图的roi数字与模板里每个数字matchTemplateresult = cv2.matchTemplate(roi, digitROIValue, cv2.TM_CCOEFF_NORMED)# 返回最值及最值位置,在这里我们需要的是最小值的得分,不同的匹配度计算方法的选择不同min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)scores.append(max_val)  # 最大值score = np.abs(scores)  # 有负数出现,统一成正数,相关系数都变成正数flag = Falsefor val in score:if val > 0.9:flag = Truebreakif not flag:best_index = np.argmax(score)  # score最大值的下标,匹配度最高best_value = str(best_index)  # 下标就是对应的数字,在字典中,key是0对应的是值为0的图片groupOutput.append(best_value)cv2.rectangle(img, (gx - 5, gy - 5), (gx + gw + 5, gy + gh + 5), (0, 0, 255), 1)# 在矩形框上绘图cv2.putText(img, ''.join(groupOutput), (gx, gy - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.65, (0, 0, 255), 2)output.append(groupOutput)cv_show('img', img)# print('数字为:', output)print("银行卡号如下:")for i in output:for j in i:print(j,end="")digits=temp_deal()
bankCard_deal(digits)

8.代码识别图片如下

9.识别输出的数字如下

计算机视觉-opencv银行卡识别相关推荐

  1. android opencv 银行卡识别,NDK 开发之使用 OpenCV 实现银行卡号识别

    前言 在日常的开发中,我们有时会遇到添加银行卡的需求,这时候,产品可能会让你仿一下支付宝之类的相机扫描识别银行卡号.很多时候,做这样的需求会去找找稳定的第三方,本文通过 OpenCV 结合识别的需求带 ...

  2. Opencv——银行卡识别系统

    目录 前言 一.环境配置与预处理 二.模板处理方法 1.将图片传进来,以copy形式,进行二值化,便于后序识别. 2.二值化: 3.检测外轮廓,找出外接矩形,只要轮廓. 4.为现有的模板进行一个排序 ...

  3. OpenCV——银行卡识别

    之前写过关于车牌识别的项目,银行卡识别和车牌识别类似,也是先从待检测图片中找到银行卡号码的区域,再将号码提取出来. 银行卡识别的难点在于: 1.银行卡种类繁多,不能使用一类固定的算法识别所有的银行卡. ...

  4. 计算机视觉---opencv人脸识别

    import cv2#步骤1:载入图像 img = cv2.imread(r'C:\Users\yu\Desktop\1.jpg') img = cv2.resize(img,(int(img.sha ...

  5. android opencv 银行卡识别,【opencv小应用】银行卡号识别(一)

    银行卡几何校正及卡号定位 一.首先看下效果:                                                                               ...

  6. opencv银行卡识别

  7. 计算机视觉OpenCV之人脸识别的示例(Python)

    计算机视觉之人脸识别看起来很高大上,但是用OpenCV解决很方便,OpenCV真的太强大了.. 直接上代码: #!/usr/bin/env python3import cv2image = cv2.i ...

  8. opencv +数字识别

    现在很多场景需要使用的数字识别,比如银行卡识别,以及车牌识别等,在AI领域有很多图像识别算法,大多是居于opencv 或者谷歌开源的tesseract 识别. 由于公司业务需要,需要开发一个客户端程序 ...

  9. c# opencv车牌识别_opencv +数字识别

    现在很多场景需要使用的数字识别,比如银行卡识别,以及车牌识别等,在AI领域有很多图像识别算法,大多是居于opencv 或者谷歌开源的tesseract 识别. 由于公司业务需要,需要开发一个客户端程序 ...

最新文章

  1. Python基础教程:列表的四种常用方法
  2. crontab命令简介
  3. Micropython教程之TPYBoard制作蓝牙+红外循迹小车
  4. python循环顶帖_设计Python数据库连接池1-对象的循环引用问题
  5. 5分绩点转4分_高考语文如何考上120分?衡中老师建议:这5点高中生必须重视
  6. 怎么把css改成打印,css 打印print
  7. VMware Horizon7安装-分步指南
  8. python 网页调试_使用Django 2.0构建Python Restful Web服务:七)在浏览器中浏览和调试restful接口...
  9. mac下宿主机与virtualbox中的Ubuntu建立ssh连接
  10. Ibatis结合MySQL数据库的使用方法
  11. deque python_python3 deque(双向队列)的详细介绍
  12. 计算机管理员英语怎么说,电脑管理员英文administrator写法
  13. 浙大中控T9100系统在压缩机上的应用
  14. ZZNUOJ_C语言1007:鸡兔同笼(完整代码)
  15. android 软电话,基于Android平台及SIP协议的软电话系统的研究
  16. 使用Pinyin4Swift进行汉字拼音转换
  17. 【5GC】三种SSC(Session and Service Continuity)模式介绍
  18. 硬件设备使用网线连接PC并访问外网
  19. Jsp中的forward 和 redirect
  20. 怎样在一张图片上叠加另一张图片

热门文章

  1. window.print();html 打印 之 print.js
  2. linux 开机启动脚本或者服务
  3. 决战Go语言从入门到入土v0.1
  4. JavaScript特效:划词搜索
  5. 爱默生电梯维修服务器,爱默生电梯故障代码 爱默生电梯怎么看故障代码
  6. 威迅教育软件工厂正式入驻无锡软件园
  7. eaby技术架构变迁
  8. PHP 最新精品面试题
  9. mm1 matlab,(高质)MM1排队系统仿真matlab实验报告.doc
  10. 开关电源基础01:电源变换器基础(3)