本篇讲的主要是对验证码图片的二值去边去线降噪。
最近天热了。人也有点疲惫,不打太多字。
首先安装 opencv :(点击链接查看)
https://blog.csdn.net/weixin_43582101/article/details/88660570
我自己画了个图(下文图片数据根据这张图写的)
图片名:1234567.png:
读入图片1234567.png
代码语言:javascript复制import cv2
im = cv2.imread('1234567.png')
使用cvtColor方法进行颜色空间转换,转成黑白的
代码语言:javascript复制im = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
可以保存下看看:
代码语言:javascript复制 cv2.imwrite('33333.png',im)
然后我们先去除边框:
啥原理呢,就是把这个边框范围的 所有坐标的像素 都变成 255 白色的。这个具体要看你的图片的边框值是多少,需要你看情况。
代码语言:javascript复制def clear_border(img):
h, w = img.shape[:2] # h高、w宽
for y in range(0, w):
for x in range(0, h):
if y < 50 or y > w - 61: # 把在50以内的像素坐标[0,0]到[高,50],[0,宽-50]到[高,宽],都变白色
img[x, y] = 255
if x < 60 or x > h - 60: # 如上
img[x, y] = 255
cv2.imwrite('22222.png',img)
return img
看下 22222.png:
框没了。
现在我们来去除下线:也就是干扰线降噪
这个原理呢,就是来判断这个像素点旁边是不是白的,如果是说明他是干扰线,就把他也变成白的。
代码语言:javascript复制def interference_line(img):
h, w = img.shape[:2]
# opencv矩阵点是反的
# img[1,2] 1:图片的高度,2:图片的宽度
for y in range(1, w - 1):
for x in range(1, h - 1):
count = 0
if img[x, y - 1] > 245:
count = count 1
if img[x, y 1] > 245:
count = count 1
if img[x - 1, y] > 245:
count = count 1
if img[x 1, y] > 245:
count = count 1
if count > 2:
img[x, y] = 255 #判断一圈有多少白的,超过2,就转成白的。
cv2.imwrite('44444.png',img)
return img
看下44444.png:
线去的差不多了。但是还有些干扰点了什么的。
点降噪:
点降噪的话可以自己看情况来写,也可以利用已经封装好的方法。
中值滤波medianBlur:
这个中值滤波 基本思想是用像素点邻域 灰度值的中值 来代替该像素点的灰度值,让周围的像素值接近真实的值从而消除孤立的噪声点。
代码语言:javascript复制import numpy
image = cv2.imread('44444.png')
result = numpy.array(image)
ss = cv2.medianBlur(result,5)
cv2.imwrite('66666.png',ss)
看下66666.png
是不是好多了。你还可以再次调用这个方法。
高斯滤波:GaussianBlur函数:
高斯滤波 是需要对一个像素的周围的像素给予更多的重视。因此,可通过分配权重来重新计算这些周围点的值。这可通过高斯函数(钟形函数,即喇叭形数)的权重方案来解决
代码语言:javascript复制# 将每个像素替换为该像素周围像素的均值
image1 = cv2.imread('66666.png')
result = cv2.blur(image1,(5,5))
gaussianResult = cv2.GaussianBlur(result,(5,5),1.5)
cv2.imwrite('77777.png',gaussianResult)
再看77777.png
好了,先到这吧。其实没多少东西,如果想研究下降噪的原理话,可以与我联系一起再深入学习下。
完整流程代码:
代码语言:javascript复制import cv2
import numpy
def cvt(img):
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
return img
def clear_border(img):
h, w = img.shape[:2] # h高、w宽
for y in range(0, w):
for x in range(0, h):
if y < 50 or y > w - 61: # 把在50以内的像素坐标[0,0]到[高,50],[0,宽-50]到[高,宽],都变白色
img[x, y] = 255
if x < 60 or x > h - 60: # 如上
img[x, y] = 255
cv2.imwrite('22222.png',img)
return img
def interference_line(img):
h, w = img.shape[:2]
# opencv矩阵点是反的
# img[1,2] 1:图片的高度,2:图片的宽度
for y in range(1, w - 1):
for x in range(1, h - 1):
count = 0
if img[x, y - 1] > 245:
count = count 1
if img[x, y 1] > 245:
count = count 1
if img[x - 1, y] > 245:
count = count 1
if img[x 1, y] > 245:
count = count 1
if count > 2:
img[x, y] = 255 #判断一圈都是白的,就转成白的。
return img
def dian_medianBlur(image):
result = numpy.array(image)
image = cv2.medianBlur(result,5)
return image
def dian_GaussianBlur(image):
result = cv2.blur(image,(5,5))
gaussianResult = cv2.GaussianBlur(result,(5,5),1.5)
return gaussianResult
if __name__ == '__main__':
img = cv2.imread('1234567.png')
image = dian_GaussianBlur(dian_medianBlur(interference_line(clear_border(cvt(img)))))
cv2.imwrite('88888.png',image)