运维开发网

初识图像处理:从入门到改行

运维开发网 https://www.qedev.com 2020-11-17 09:44 出处:51CTO 作者:dong82222
经历上次的失败后,这一次我学聪明了。我自己做不出东西乱折腾啥也不是,我跟着别人,啃别人的代码,借鉴一下别人的它不香吗。所以这次是用python做银行卡号码识别。话不多说,开始!importcv2importnumpyasnp定义绘图函数defimshow(name,img):cv2.imshow(name,img)cv2.waitKey(0)cv2.destroyAllWindows()12345

经历上次的失败后,这一次我学聪明了。

我自己做不出东西乱折腾啥也不是,我跟着别人,啃别人的代码,借鉴一下别人的它不香吗。

所以这次是用python做银行卡号码识别。

话不多说,开始!

import cv2

import numpy as np

定义绘图函数

def imshow(name, img):

cv2.imshow(name, img)

cv2.waitKey(0)

cv2.destroyAllWindows()

1

2

3

4

5

6

7

8

cv2.imshow()画个图还要一套组合拳,接化发,咱年轻人顶不住,先给个函数打包定义一下。

读取模板图片

0表示读成一个单通道的图片 即灰度图 也可以用

ref = cv2.cvtColor(img_num, cv2.COLOR_BGR2GRAY)转换成灰度图

img_num = cv2.imread('images/ocr_a_reference.png',0)

imshow('img_num',img_num)

1

2

3

4

5

在这里插入图片描述

转换成二值图像

cv2.threshold(输入图像,阈值,赋值,方法) 这里方法是高于阈值取0,低于阈值取255

cv2.threshold返回两个值 第二个值是我需要的处理后的图像

img_num_bin = cv2.threshold(img_num,10,255,cv2.THRESH_BINARY_INV)[1]

imshow('img_num_bin',img_num_bin)

1

2

3

4

在这里插入图片描述

因为接下来的银行卡数字会为白色部分,所以转成白字黑底,方便后续进行模板匹配

轮廓提取

cv2.findContours()函数接受的参数为二值图,即黑白的(不是灰度图),cv2.RETR_EXTERNAL只检测外轮廓,cv2.CHAIN_APPROX_SIMPLE只保留终点坐标

返回的list中每个元素都是图像中的一个轮廓

num_cntslist, =cv2.findContours(img_num_bin.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)

cv2.drawContours(img_num_bin, num_cnts_list, -1, (0,0,255), 3)

imshow('draw_img_num',img_num_bin)

1

2

3

4

5

在这里插入图片描述

轮廓没有显示出来,但是对比上面变窄了,是不是因为轮廓自动变成黑色的了。暂时不管,接下来要把每个轮廓圈起来,到时候看一看就知道了。

轮廓排序

num_rect_list = num_cnts_sort(num_cnts_list)

1

num_cnts_sort是我自定义的函数,用来给轮廓排序,并且按一定的顺序返回

def num_cnts_sort(list,right=1,up=0):

up=1表示从上往下,right=1表示从左往右,-1表示反过来

reverse = False
if up==-1 or right== -1:
    reverse = True

if up == 0:
    # 左右方向排序 权重选x
    i = 0

if right == 0:
    i = 1

# 找到的轮廓用外接矩形框起来 cv2.boundingRect(c)返回x,y,w,h
boundingBoxs = [cv2.boundingRect(c) for c in list] #生成器
# sorted(输入序列,排序规则,reverse=True 由小到大否则由大到小)
# lambda 匿名函数 输入序列的每个元素 输出b[i]
boxs = sorted(boundingBoxs,key= lambda b: b[i],reverse=reverse )

return boxs

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

把每个轮廓外接矩形按顺序画出来

for num_rect in num_rect_list:

(x,y,w,h)=num_rect

num_rect_img = cv2.rectangle(img_num_bin.copy(),(x,y),(x+w,y+h),(255,0,0),2)

imshow('num_rect_img',num_rect_img)

1

2

3

4

5

在这里插入图片描述

排序没有问题,接下来把对应得数字模板截下来和数字对应

把图片和数字对应

num_rect_dic = {}

for (i,num_rect) in enumerate(num_rect_list):

(x, y, w, h) = num_rect

num_rect_item = img_num_bin[y:y+h,x:x+w]
num_rect_item = num_resize(num_rect_item,h_size=88)
# 把数字和截下来的图像对应
num_rect_dic[i]=num_rect_item
imshow('num_rect_item', num_rect_item)

1

2

3

4

5

6

7

8

9

10

num_resize为自定义函数,输入高或宽自动计算缩放

def num_resize(img,w_size=0,h_size=0):

(w,h)=img.shape # size返回总元素个数 和matlab不一样

if w_size == 0:

r = h_size/float(h)

w_size = int(rh)

if h_size == 0:

r = w_size/float(w)

h_size = int(wh)

resized = cv2.resize(img,(w_size,h_size))

return resized

1

2

3

4

5

6

7

8

9

10

11

对银行卡图像预处理

对银行卡图像预处理

读取图像

bank_img = cv2.imread('images/credit_card_01.png')

bank_img_gray = cv2.cvtColor(bank_img,cv2.COLOR_BGR2GRAY)

imshow('bank_img',bank_img)

imshow('bank_img_gray',bank_img_gray)

定义卷积核

rectKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9, 3)) # 矩形卷积核

sqKernel = cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))

顶帽操作 突出明亮的部分

bank_img_tophat = cv2.morphologyEx(bank_img_gray,cv2.MORPH_TOPHAT, rectKernel)

imshow('bank_img_tophat',bank_img_tophat)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

在这里插入图片描述

数字的横线太暗,我想 如果进行二值化要选择一个合适的参数,或者进行一个边缘检测。

边缘检测

X方向边缘检测处理

bank_img_grad = cv2.Sobel(bank_img_tophat,cv2.CV_32F,1,0,ksize=-1)

imshow('bank_img_tophat',bank_img_grad)

归一化

bank_img_grad_abs = np.absolute(bank_img_grad)

(max,min) = (np.max(bank_img_grad_abs),np.min(bank_img_grad_abs))

bank_img_grad_abs = (255*(bank_img_grad_abs-min)/(max-min))

bank_img_grad_abs = bank_img_grad_abs.astype('uint8')

imshow('s',bank_img_grad_abs)

二值化 cv2.THRESH_OTSU会选择合适的阈值进行二值化 cv2.threshold返回的是两个元素 第二个是处理后的图像

bank_img_bin = cv2.threshold(bank_img_grad_abs, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]

imshow('s',bank_img_bin)

扫码领视频副本.gif

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号