Opencv Python 综合练习1---读取银行卡卡号

import os
import cv2
import numpy as np

path = os.path.dirname(__file__)
os.chdir(path)
test_mode=1


#读取图片,cv2.IMREAD_GRAYSCALE可以只提取灰度信息
img = cv2.imread("yinghanka_2.jpg",cv2.IMREAD_GRAYSCALE)
img=cv2.GaussianBlur(img,(3,3),cv2.THRESH_BINARY_INV)
cv2.imshow("img",img)

#该银行卡的数字为黑色
ret, img=cv2.threshold(img,122,255,cv2.THRESH_BINARY_INV)

#开始形态学操作,弄出合适的图片,用于寻找轮廓
image=img
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(3,1))
image=cv2.dilate(image,kernel,iterations=10)
#image=cv2.erode(image,kernel,iterations=2)

kernel2 = cv2.getStructuringElement(cv2.MORPH_RECT,(1,3))
#image=cv2.dilate(image,kernel2,iterations=5)
#image=cv2.erode(image,kernel2,iterations=5)
cv2.imshow("image",image)

y_list=[]
img_cor=[]
image_rect_list=[] #用于保存数字块的图像列表

#选择合适的轮廓,该银行卡数字为4个1组,最后1组为3个,另外进行了膨胀和腐蚀 所以wh比例应该在2-5之间
contours, heirarchy=cv2.findContours(image,cv2.RETR_EXTERNAL ,cv2.CHAIN_APPROX_SIMPLE) 
#cv2.drawContours(image,contours,-1,(128,128,0),10)
#cv2.imshow("canny2",image)
for contour in reversed(contours):#倒序循环,默认的轮廓是从右往左的
    x,y,w,h = cv2.boundingRect( contour ) #外切矩形,这里暂时不考虑图片旋转的问题
    if(x > 0) and (h > 10) and (w>=2*h) and (w<=5*h):  
        #cv2.rectangle(img,(x,y),(x+w,y+h),(255,255,255),2)
        print(x,y,w,h)
        #这里我们看到出来了5+2个合适的矩形,多出来的2个是日期之类的WH也符合要求,但是我们可以看到这2类不是同一行的qq
        y_list.append(y)
        img_cor.append((x,y,w,h))
        
y_list.sort()
#这里我们直接取出列表的前5个,另外还有种做法应该也可以,就是求2阶导数,出现负的就是上升沿,代表另一个等级的数据
print("-------")
for img_c in img_cor:
    if(img_c[1]<=y_list[5]):
       x,y,w,h =img_c
       print(x,y,w,h)
       #cv2.rectangle(img,(x,y),(x+w,y+h),(255,255,255),2)
       image_digit_rect=np.zeros((w,h,1))
       image_digit_rect= img[y:y+h,x:x+w]  # 裁剪坐标为[y0:y1, x0:x1]
       image_rect_list.append(img[y:y+h,x:x+w])


def cut_img(img,digital_list):
    image=img #直接复制,为引用,会全局修改
    
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(2,1))
    #image=cv2.erode(image,kernel,iterations=2)
    #image=cv2.dilate(image,kernel,iterations=2)
    

    
    contours, heirarchy=cv2.findContours(image,cv2.RETR_EXTERNAL ,cv2.CHAIN_APPROX_SIMPLE) 
    #cv2.drawContours(image,contours,-1,(128,128,0),3)
    #cv2.imshow("canny2",image)
    for contour in reversed(contours):
        x,y,w,h = cv2.boundingRect( contour )
        #cv2.rectangle(image,(x,y),(x+w,y+h),(255,255,255),2)
        digital=np.zeros((w,h,1))
        digital= image[y:y+h,x:x+w]  # 裁剪坐标为[y0:y1, x0:x1]
        digital_list.append(digital)
        
    #cv2.imshow("rect",image)
    #cv2.waitKey(1000)
    #cv2.destroyWindow("rect") 


digital_list=[]
test=0
if test == 1:
    cut_img(image_rect_list[4],digital_list)
    print("111test")
else:
    for img_s in image_rect_list:
        cut_img(img_s,digital_list)
        
    cv2.waitKey(1000)
    for digital in digital_list:
        cv2.imshow("digital",digital)
        cv2.waitKey(500)
        cv2.destroyWindow("digital")
    
cv2.imshow("ori_img",img)
cv2.waitKey()
cv2.destroyAllWindows()

来自百度的图片
从实验效果看,勉强能用,但是还是有许多地方需要更进一步优化的:
1:2值化的阈值取值问题,影响了部分数字的连续性,比如最后的一个数字5
2:形态学操作中,循环的次数是否是经验值,是否具备鲁棒性
3:没有考虑图片的旋转等特性
4:最后数字的识别还未添加,是使用ocr还是模板识别等需要后续支持

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值