《Opencv》名誉卡信息识别项目

打印 上一主题 下一主题

主题 689|帖子 689|积分 2067

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
目次

一、项目介绍
二、数据材料介绍
1、模板图片(1张)
2、需要处理处罚的名誉卡图片(5张) 
三、实现过程
1、导入需要用到的库
2、设置下令行参数
3、模板图像中数字的定位处理处罚
4、名誉卡图像处理处罚
5、模板匹配 
四、总结


一、项目介绍

项目的重要目标是实现名誉卡号码和类型的识别。通过图像处理处罚技能,从名誉卡图像中提取出卡号,将每个数字与模板数字进行比对,从而得着名誉卡号码。并根据卡号的第一位数字判断名誉卡的类型。
二、数据材料介绍

1、模板图片(1张)


2、需要处理处罚的名誉卡图片(5张) 

 
 
 
 
 
三、实现过程

1、导入需要用到的库

  1. import numpy as np
  2. import argparse
  3. import cv2
  4. import myutils
复制代码
此中myutils模块为自己编写的工具模块,里面包含了对外貌进行排序的函数以及自动变更图片大小的函数,内容如下:
  1. """myutil.py"""
  2. import cv2
  3. # 排序函数
  4. def sort_contours(cnts, method='left-to-right'):
  5.     # 初始化排序方向和索引
  6.     reverse = False
  7.     axis_index = 0  # 默认按 x 轴排序(从左到右或从右到左)
  8.     # 根据排序方法设置排序方向和索引
  9.     if method == 'right-to-left' or method == 'bottom-to-top':
  10.         reverse = True  # 反向排序
  11.     if method == 'top-to-bottom' or method == 'bottom-to-top':
  12.         axis_index = 1  # 按 y 轴排序(从上到下或从下到上)
  13.     # 计算每个轮廓的边界框
  14.     bounding_boxes = [cv2.boundingRect(c) for c in cnts]
  15.     # 将轮廓和边界框组合在一起
  16.     combined = list(zip(cnts, bounding_boxes))
  17.     # 根据边界框的坐标进行排序
  18.     sorted_combined = sorted(combined, key=lambda x: x[1][axis_index], reverse=reverse)
  19.     # 解包排序后的轮廓和边界框
  20.     sorted_cnts = [item[0] for item in sorted_combined]
  21.     sorted_bounding_boxes = [item[1] for item in sorted_combined]
  22.     return sorted_cnts, sorted_bounding_boxes
  23. # 变换图片大小的函数
  24. def resize(image, width=None, height=None, inter=cv2.INTER_AREA):
  25.     dim = None
  26.     (h, w) = image.shape[:2]
  27.     if width is None and height is None:
  28.         return image
  29.     if width is None:
  30.         r = height / float(h)
  31.         dim = (int(w * r), height)
  32.     else:
  33.         r = width / float(w)
  34.         dim = (width, int(h * r))
  35.     resized = cv2.resize(image, dim, interpolation=inter)
  36.     #参数interpolation指定了在图像大小调整过程中如何处理像素插值的方法。cv2.INTER_AREA具体意味着使用面积插值方法。
  37.     return resized
复制代码
 
2、设置下令行参数



  • --image为名誉卡图片
  • --template为模板图片
  1. ap = argparse.ArgumentParser()
  2. ap.add_argument('-i','--image',required=True,help='')
  3. ap.add_argument('-t','--template',required=True,help='')
  4. args = vars(ap.parse_args())
  5. # 信用卡号码开头对应信用卡的类型
  6. FIRST_NUMBER = {"3":"American Express",
  7.                 "4":"Visa",
  8.                 "5":"MasterCard",
  9.                 "6":"Discover Card"}
  10. # 定义显示图片函数
  11. def cv_show(name, image):
  12.     cv2.imshow(name, image)
  13.     cv2.waitKey(0)
复制代码
3、模板图像中数字的定位处理处罚



  • 读取模板图像(包含 0-9 的数字)。
  • 对模板图像进行灰度化、二值化处理处罚。
  • 使用外貌检测提取每个数字的外貌,并将每个数字裁剪出来,生存为模板。
  1. """模板图像中数字的定位处理"""
  2. # img为模板图像
  3. img = cv2.imread(args['template'])
  4. cv_show('img',img)
  5. # 灰度图
  6. ref = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
  7. cv_show('ref',ref)
  8. # 二值化
  9. ref = cv2.threshold(ref,10,255,cv2.THRESH_BINARY_INV)[1]
  10. cv_show('ref',ref)
  11. # 轮廓
  12. refCnts = cv2.findContours(ref.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)[1]
  13. cv2.drawContours(img,refCnts,-1,(0,0,255),2)
  14. cv_show('img',img)
  15. # 对轮廓进行从左到右排序
  16. refCnts = myutils.sort_contours(refCnts,method="left-to-right")[0]
  17. digits = {}
  18. # 获取每个数字的信息
  19. for (i,c) in enumerate(refCnts):
  20.     (x,y,w,h) = cv2.boundingRect(c)
  21.     roi = ref[y:y+h,x:x+w]
  22.     roi = cv2.resize(roi,(57,88))
  23.     digits[i] = roi
  24.     cv_show('roi',roi)
  25. print(len(digits))
复制代码
 
4、名誉卡图像处理处罚



  • 读取名誉卡图像。
  • 对名誉卡图像进行灰度化、顶帽使用(去除背景)、闭使用(将数字连在一起)、自顺应二值化等处理处罚。
  • 使用外貌检测找到名誉卡上的数字地区。
  1. """信用卡的图像处理"""
  2. image = cv2.imread(args['image'])
  3. cv_show('image',image)
  4. # 变换图片大小
  5. image = myutils.resize(image,width=300)
  6. gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
  7. cv_show('gray',gray)
  8. # 设置核
  9. rectKernel = cv2.getStructuringElement(cv2.MORPH_RECT,(9,3))
  10. sqKernel = cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))
  11. # 顶帽
  12. tophat = cv2.morphologyEx(gray,cv2.MORPH_TOPHAT,rectKernel)
  13. # 开运算
  14. open = cv2.morphologyEx(gray,cv2.MORPH_OPEN,rectKernel)
  15. cv_show('open',open)
  16. cv_show('tophat',tophat)
  17. # 找数字边框
  18. # 闭操作,将数字连在一起
  19. closeX = cv2.morphologyEx(tophat,cv2.MORPH_CLOSE,rectKernel)
  20. cv_show('closeX',closeX)
  21. # 自适应二值化
  22. thresh = cv2.threshold(closeX,0,255,cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
  23. cv_show('thresh',thresh)
  24. # 闭操作
  25. thresh = cv2.morphologyEx(thresh,cv2.MORPH_CLOSE,sqKernel)
  26. cv_show('thresh1',thresh)
  27. # 计算轮廓
  28. threshCnts = cv2.findContours(thresh.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)[1]
  29. cnts = threshCnts
  30. cur_img = image.copy()
  31. cv2.drawContours(cur_img,cnts,-1,(0,0,255),3)
  32. cv_show('img',cur_img)
  33. # 遍历轮廓,找到数字部分
  34. locs = [] # 存放每组数字的x,y,w,h
  35. for (i,c) in enumerate(cnts):
  36.     (x,y,w,h) = cv2.boundingRect(c)
  37.     ar = w/float(h)
  38.     if 2.5 < ar < 4.0:
  39.         if (40 < w < 55) and (10 < h < 20):
  40.             locs.append((x,y,w,h))
  41. locs = sorted(locs,key=lambda x: x[0])
复制代码
 

 
5、模板匹配 



  • 将名誉卡图像中的每个数字地区与模板中的数字进行匹配,找到最相似的数字。
  • 根据匹配效果识别名誉卡号码。
  1. output = []
  2. # 遍历每一组数字
  3. for (i,(gx,gy,gw,gh)) in enumerate(locs):
  4.     groupOutput = []
  5.     group = gray[gy-5:gy+gh+5,gx-5:gx+gw+5]
  6.     cv_show('group',group)
  7.     group = cv2.threshold(group,0,255,cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
  8.     cv_show("group",group)
  9.     # 寻找每组数字的轮廓并根据顺序放入digitCnts
  10.     digitCnts = cv2.findContours(group.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)[1]
  11.     digitCnts = myutils.sort_contours(digitCnts)[0]
  12.     for c in digitCnts:
  13.         (x,y,w,h) = cv2.boundingRect(c)
  14.         roi = group[y:y+h,x:x+w]
  15.         roi = cv2.resize(roi,(57,88))
  16.         cv_show('roi',roi)
  17.         """模板匹配,计算得分"""
  18.         scores = []
  19.         # 在模板中计算每一个得分
  20.         for (digit,digitROI) in digits.items():
  21.             # 模板匹配
  22.             result = cv2.matchTemplate(roi,digitROI,cv2.TM_CCOEFF)
  23.             # minVal, maxVal, minLoc, maxLoc = cv2.minMaxLoc(src, mask=None)
  24.             score = cv2.minMaxLoc(result)[1]
  25.             scores.append(score)
  26.         # 得到匹配分数最大值的索引
  27.         groupOutput.append(str(np.argmax(scores)))
  28.     cv2.rectangle(image,(gx-5,gy-5),(gx+gw+5,gy+gh+5),(0,0,255),1)
  29.     cv2.putText(image,"".join(groupOutput),(gx,gy-15),cv2.FONT_HERSHEY_SIMPLEX,0.65,(0,255,0),2)
  30.     output.extend(groupOutput)
  31. # 打印结果
  32. print("信用卡类型:{}".format(FIRST_NUMBER[output[0]]))
  33. print("信用卡号码:{}".format("".join(output)))
  34. cv_show("Image",image)
复制代码
 
 
 
四、总结

这个项目通过图像处理处罚和模板匹配技能,实现了名誉卡号码的自动识别。它展示了如何结合 OpenCV 和 Python 实现一个实用的图像处理处罚应用。
 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

星球的眼睛

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表