验证码识别之图片处理(一些细节处理)

上一篇我们聊到了图片验证码处理的基本流程,已经可以应付绝大多数图片验证码了。

验证码识别之图片处理(基础流程)------ 链接戳这里

我们来看一下成果:

可以看到应付我们的学习算法需求已经足够。

今天我们来看看一些特殊图片的处理方法:

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)

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值