目前有许多应用会绑定银行卡,但是再绑定的时候如果是用户一个个卡号输入的话,就会使犯错误的概率大大增加,所以就体现出了我们这个app的作用,无论是什么样的银行卡都可以识别出它的卡号。
对于这个项目,我负责的主要是银行卡号的分割,以及银行卡照片的预处理。
对于图片处理的这一部分,我选择的是opencv,编程语言选择的是python,安装环境这一部分就不做太多介绍了 (百度一下教程就有,我配置环境的时候也踩到许多坑,我之前的博客有介绍),我们要先对图片进行预处理,这样可以帮助我们对银行卡号在银行卡的位置进行判断和寻找。
一、高斯模糊
银行卡照片要先进行高斯模糊对图片进行去除噪音(附简要代码)
blur = cv.GaussianBlur(img, (3, 3), 0) # 高斯模糊
降噪后的照片
二、灰路图像和图片二值化
将进行完高斯模糊的银行卡照片进行灰路图像和图像二值化。(附简要代码)
gray = cv.cvtColor(blur, cv.COLOR_BGR2GRAY) # 将图像变为灰路图像
ret, binary = cv.threshold(gray, 50, 255, cv.THRESH_BINARY) # 二值化
代码实现的结果照片
三、膨胀和腐蚀
将进行完灰路图像和图像二值化的银行卡照片进行膨胀和腐蚀(附简要代码)
kernel = np.ones((1, 50), np.uint8)
erosion = cv.erode(binary, kernel) # 膨胀
dilation = cv.dilate(erosion, kernel) # 腐蚀
代码实现的结果照片
四、总结
通过前面的方法我们就已经可以判断银行卡上的银行卡号的位置了,接下来的部分
就是银行卡号的分割 ,把银行卡号分割成一个一个小的号码,并将其保存为照片。
从上面的方法中,我们已经可以识别出银行卡号的位置了。然后我们再将查找到的位置,用二值化图片来进行存储。(附简要代码)
def num_split(img):
height, width = img.shape
v = [0] * width
z = [0] * height
a = 0
for x in range(0, width):
for y in range(0, height):
if img[y, x] == 255:
continue
else:
a = a + 1
v[x] = a
a = 0
l = len(v)
emptyImage = np.full((height, width), 255, dtype=np.uint8)
for x in range(0, width):
for y in range(0, v[x]):
emptyImage[y, x] = 0
从上面的方法中,我们已经可以得到了银行卡号的二值化照片了,我们就可以利用图像二值化来进行银行卡号的分割,图像二值化的意义就是利用每个卡号之间的白色来将卡号就行分割。(附简要代码)
Position = []
Wstart = 0
Wend = 0
W_Start = 0
W_End = 0
v[0], v[len(v)-1] = 0, 0
for j in range(len(v)):
if v[j] > 0 and Wstart == 0:
W_Start = j
Wstart = 1
Wend = 0
if v[j] <= 0 and Wstart == 1:
W_End = j
Wstart = 0
Wend = 1
if Wend == 1:
Position.append([W_Start, 0, W_End, height])
Wend = 0
for hx in range(h0):
for wx in range(w0):
temp_data.append(float(temp_img[hx, wx]))
data.append(temp_data)
return data
代码实现结果如图
我们可以手动进行确定银行卡号的位置,然后就行后续的操作。最开始的时候处理的图像只能是特别清晰的银行卡照片,但是后面发现银行卡的种类特别多,而且有的还特别不清晰,所以我也改进了我的代码,原因就是因为照片灰度化,对于每种照片处理的不是够精细,然后就来在队友的帮助下也寻找到了更好处理的灰度化的方式,