上一篇我们聊到了图片验证码处理的基本流程,已经可以应付绝大多数图片验证码了。
验证码识别之图片处理(基础流程)------ 链接戳这里
我们来看一下成果:







可以看到应付我们的学习算法需求已经足够。
今天我们来看看一些特殊图片的处理方法:
1、带边框验证码:
例如:

这种处理方式比较显而易见,循环遍历时直接将
i<2 or i>rows-3 or j<2 or j>cols-3
的点置为白色即可,代码我就不上了。
2、背景色为深色的验证码:
例如:

背景颜色比字母颜色深一些,阈值不好定。
这时我们需要获取图片背景色,处理依据:
一般背景色都为图片中颜色占比最多,我们只要获取出现最多的颜色,然后全部置为白色即可。
即将其变为:

后续就都一样了:






python代码如下:
# 获取图片中像素点数量最多的像素并置为白色
def get_threshold(image):
pixel_dict = defaultdict(int)
# 像素及该像素出现次数的字典
rows, cols = image.size
for i in range(rows):
for j in range(cols):
pixel = image.getpixel((i, j))
pixel_dict[pixel] += 1
count_max = max(pixel_dict.values()) # 获取像素出现出多的次数
pixel_dict_reverse = {v:k for k,v in pixel_dict.items()}
threshold = pixel_dict_reverse[count_max] # 获取出现次数最多的像素点
for i in range(rows):
for j in range(cols):
#剔除边框
if image.getpixel((i, j)) == threshold or i<2 or i>rows-3 or j<2 or j>cols-3:
image.putpixel((i, j), (255, 255, 255, 255))
return image
3、验证码中带有粗粗的干扰线:
我们之前的干扰线处理方式依据为:
干扰线一般相比较于字母来说比较细,在去除噪点的时候就将其一起去除了。
比如这种:

或者是这种(红线是我自己画的。。):

可以看出,我们可以分为两种类型:
①颜色和字母同色
②颜色不和字母同色
1、先看第一种,既然颜色,粗细都和字母差不多,也就是说我们无法从外形上直接区分出来,就算是人工来看,区分的依据也是和我们脑海中的字母一个个匹配,这时候我们只能寄希望于我们的学习算法了,这时候我们图片处理能做的只能是提高图片切割时候的阈值,来保证图片的正确切割:







2、再看第二种,粗细和字母差不多,但是颜色则可以有明显的区分,这时候我们明显第一感觉就可以将其过滤掉,那同样,我们的代码中也是可以实现的。
我们看看干扰线的特点:
①颜色有明显区分度;
②跨X轴很长;
所以我们的处理依据就出来了:
除背景色外,在X轴上投影上出现次数最多的即为干扰线,将该颜色转为白色即可。
注意,这里是在X轴投影上出现过的次数,而不是总次数。(统计X=N的线上出现的颜色,不管在这条线上出现了多少个,都算1次)




python代码如下:
def clear_node_rgb(image):
pixel_list = []
rows, cols = image.size
for i in range(rows):
pixel_rgb = []
for j in range(cols):
rgb = image.getpixel((i, j))
if rgb != (255,255,255) and rgb not in pixel_rgb:
pixel_list.append(rgb)
pixel_rgb.append(rgb)
max_rgb = Counter(pixel_list).most_common(1)[0][0]
for i in range(rows):
for j in range(cols):
pixel = image.getpixel((i, j))
if pixel == max_rgb:
image.putpixel((i, j), (255, 255, 255, 255))
return image
这里我们处理后的图片都有一个很明显的问题:被分割线挡住的部分断掉了。
那追求完美的我们就需要想办法去弥补一下了。
在opencv中有一对图片处理的方法,叫做腐蚀和膨胀。
腐蚀的意思为将图片上的内容边界消除;
膨胀的意思为将图片上的内容边界加粗。
举个例子:
原图:

膨胀后:

腐蚀后:

所以,先膨胀后腐蚀,就能消除图片中的白点,断层等等。
我们来看看效果:

先膨胀,消除断层:

再腐蚀,回到原来的比例即可:

python代码:
import cv2
import numpy as np
def ercode_dilate(img, threshold):
#腐蚀参数, (threshold, threshold)为腐蚀矩阵大小
kernel = np.ones((threshold, threshold), np.uint8)
# 膨胀图片
erosion = cv2.erode(img, kernel, iterations=1)
# 腐蚀图片
eroded = cv2.dilate(erosion, kernel, iterations=1)
return eroded
img = cv2.imread('test.png', 0)
ercode_dilate(img, 6)

1795

被折叠的 条评论
为什么被折叠?



