简单验证码的转灰度、二值化、切割

灰度化:在RGB模型中,如果R=G=B时,则彩色表示一种灰度颜色,其中R=G=B的值叫做灰度值,因此,灰度图像每个像素值只需一个字节存放灰度值(又称强度值、亮度值),灰度范围为0-255。
二值化:二值化可以把灰度图片转换成二值图像,把大于某个临界灰度值的像素灰度设置为灰度极大值,把小于这个值的像素灰度设为灰度极小值,从而实现二值化。

原始图
原始图
灰度图
灰度图
二值化后的图
二值化后的图
我们可以看到对于这张验证码效果还不错,接下来我们用代码实现。
首先我们进行图片转灰度并二值化

def GrayscaleAndBinarization(image):
    '''
    灰度并二值化图片,初步二值化后,会存在一些噪声点,我们使用这样一个方法进行去除(不能实现完全去除),
    即当图片中存在一个点灰度值为0,但其周围九宫格中像素点的灰度值均为255时,我们认为这个点为孤立点,将其
    灰度改为255
    :param image: 处理前的图片
    :return:处理后的图片
    '''
    threshold = 17  # 需要自己调节阈值

    tmp_image = image.convert('L')  # 灰度化
    new_image = Image.new('L', tmp_image.size, 0)

    # 初步二值化
    for i in range(tmp_image.size[1]):
        for j in range(tmp_image.size[0]):
            if tmp_image.getpixel((j, i)) > threshold:
                new_image.putpixel((j, i), 255)
            else:
                new_image.putpixel((j, i), 0)

    # new_image.show()    # 去噪前

    # 去噪,去除独立点,将前后左右等九宫格中灰度通道值均为255的像素点的通道值设为255
    for i in range(1, new_image.size[1] - 1):
        for j in range(1, new_image.size[0] - 1):
            if new_image.getpixel((j, i)) == 0 and new_image.getpixel((j - 1, i)) == 255 and new_image.getpixel((j + 1, i)) == 255 and \
                    new_image.getpixel((j, i - 1)) == 255 and new_image.getpixel((j - 1, i - 1)) == 255 and new_image.getpixel((j + 1, i - 1)) == 255 and\
                new_image.getpixel((j, i + 1)) == 255 and new_image.getpixel((j - 1, i + 1)) == 255 and new_image.getpixel((j + 1, i + 1)) == 255:
                new_image.putpixel((j, i), 255)
    # new_image.show()    # 去噪后

    return new_image

接下来我们找到图片切割点并对图片进行切割,对于这种验证码,我们进行简单的垂直切割。首先,我们找到需要进行切割的位置。

def SplitImage(image):
    '''
    切割图像并保存,关键在于寻找切割位置
    :param image: 待切割的图片
    :return: 无
    '''
    splitSite = []	# 记录切割的位置
    splitSite.append(0)
    new_image = image

    tmp_list = [0 for i in range(image.size[0])]
    for i in range(image.size[0]):
        for j in range(image.size[1]):
            if image.getpixel((i, j)) == 0:
                tmp_list[i] = 1
                break

    # print(tmp_list)
    for index in range(0, len(tmp_list) - 1):
        if tmp_list[index] == 1 and tmp_list[index + 1] == 0:
            splitSite.append(index + 1)

    plt.imshow(image)
    for item in splitSite[1:]:
        plt.plot([item for i in range(image.size[1])], [i for i in range(image.size[1])])
    plt.show()	# 使用 matplotlib 模块进行预览切割效果
    splitSite.append(image.size[0])

    # 对图片进行切割
    for index in range(1, len(splitSite) - 1):
        box = (splitSite[index - 1], 0, splitSite[index], image.size[1])	# box中四个参数,分别为距离图片左侧、上侧、右侧、下侧的像素距离
        new_image = image.crop(box)
        new_image.save('./{}.gif'.format(str(index)))	# 保存切割后的图片,位置在当前目录

切割后效果图

  1. 第一个字母
    原始图
  2. 第二个字母
    原始图
  3. 第三个字母
    原始图
  4. 第四个字母
    原始图
    源码:https://github.com/kingdowliu/ImageProcessing
  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值