美文网首页
验证码去除干扰线

验证码去除干扰线

作者: ddm2014 | 来源:发表于2018-09-18 17:47 被阅读0次

在邦购登陆时,选择了人工检验验证码,这次用机器检测试试。
先说基本逻辑:载入图像,转灰度,二值化,连通域检测,去除连通域小的,根据各连通域的范围切割图像。

先下载图片。

def getcaptcha():
    for i in range(1,10):
        with open('test1-{}.png'.format(i),'wb') as f:
            url ='https://passport.banggo.com/CASServer//custom/loginCode.do'
            res = requests.get(url,stream =True)
            f.write(res.content)

得到的验证码长这样:


可以看到验证码有干扰线,好在干扰线比较细,而且验证码之间没有粘连。看看别家怎么弄得,在python验证码识别
写到了一些验证码识别的方法,但是几乎都是针对像素级别,不过提供了一个思路叫连通域,就是一个笔画里含有的像素较多,删除那些小的联通域就能去除干扰线了。

我看到的大多是自己写的像素级别的函数,既然这是降噪领域的主要思想,就会有现成的轮子啊,直到我发现了scikit-image,有自己的文档,这篇文章进行了少量总结api总结,搬运如下

api

其中有专门针对连通域的api,
from skimage import measure
labels = measure.label(二值图像,connectivity=None)
通过label_att = measure.regionprops(labels)得到各连通域的属性如下。label_att是一个list,有几个连通域就有几项。


属性

更好的是skimage还提供了剔除较小连通域的函数,
from skimage import morphology
img1 = morphology.remove_small_objects(ar, min_size=要删除的连通域大小阈值, connectivity=1,in_place=False)
怎么知道连通域的大小呢,就是label属性里的area,第二个bbox用来切割图像简直不要太方便。
二者联合起来就是现成的去掉干扰线+切割图像的方法。

from skimage import io,filters,measure,morphology
import warnings
from matplotlib import pyplot as plt
def skim():
    img = io.imread('1.png',as_gray=True)  #变成灰度图
    thresh = filters.threshold_otsu(img) #自动确定二值化的阈值
    bwimg =(img<=thresh) #留下小于阈值的部分,及黑的部分
    b = morphology.remove_small_objects(bwimg, 40) #去掉小于40的连通域,可以先全局看看连通域的大小和位置后决定去掉的阈值
    labels = measure.label(b)  
    label_att = measure.regionprops(labels)
    arr =[]
    for la in label_att:
        (x,y,w,h) =la.bbox
        #print((x,y,w,h))
        bei = round((h-y)/15)
        if bei >1: #宽度超过30像素的,说明有粘连,从中切开
            for i in range(bei):
                arr.append((x, y+round((h-y)/2)*i, w, y+round((h-y)/2)*(i+1)))
        elif (y>10) and (h<100) :
            arr.append((x, y, w, h))

    b =b*img
    b[np.where(b != 0)] = 1
    with warnings.catch_warnings():
        warnings.simplefilter("ignore")
        fig = plt.figure()
        for id, (x, y, w, h) in enumerate(arr):
            roi = b[x:w,y:h]
            thr = roi.copy()
            # io.imsave('seg1-{}.jpg',thr)
            ax = fig.add_subplot(1,4,id+1)
            ax.imshow(thr)
    plt.show()

反思:
1.这个验证码相对规整,可以发现他家的验证码多是验证码本身是有色彩的,而干扰线一直是黑色的,可以直接将小于15的像素变成255,效果也不错,但是出现的问题是会把验证码本身连通域打断,需要再次填充。

def ty():
    # for i in range(1,10):
    img = io.imread('{}.png'.format(4))
    img[np.where(img>235)] =255
    img[np.where(img < 15)] = 255
    imgray = color.rgb2gray(img)
    thresh = filters.threshold_otsu(imgray)
    # bwimg =(imgray <= thresh)
    bwimg = morphology.closing(imgray <= thresh, morphology.square(3))
    b = morphology.remove_small_objects(bwimg, 20)
    labels = measure.label(b)
    label_att = measure.regionprops(labels)
    arr =[]

    for la in label_att:
        (x, y, w, h) = la.bbox
        bei = round((h - y) / 15)
        if bei > 1:
            for i in range(bei):
                arr.append((x, y + round((h - y) / 2) * i, w, y + round((h - y) / 2) * (i + 1)))
        elif (y > 10) and (h < 100) :
            arr.append((x, y, w, h))
            if (len(arr)>1) and (h-y)<12 and (arr[-2][3]-arr[-2][1] <12): #干扰线去狠了导致断开验证码断开了要拼接一下
                arr[-1] = ((x, arr[-2][1], w, h))
                del arr[-2]

    b = b * imgray
    b[np.where(b != 0)] = 1
    with warnings.catch_warnings():
        warnings.simplefilter("ignore")
        fig = plt.figure()
        for id, (x, y, w, h) in enumerate(arr):
            roi = b[x:w, y:h]
            thr = roi.copy()
            # io.imsave('new{}-{}.png'.format(1,id+1), thr)
            ax = fig.add_subplot(1, len(arr), id + 1)
            ax.imshow(thr)
        plt.show()

2.验证码相对规整,而且放置位置也相对固定,可以直接用经验值切割,但是有些比较胖就比较麻烦了。

3.在使用skimage时,确是遇到二值图直接转rgb会变成的黑图或者很灰的图,像这样。

b = b * imgray
b[np.where(b != 0)] = 1
就是把图调亮,因为float类型,[0,1]0是黑色,1是白色,这样存的图就是黑白的了。
另在float转rgb的时候会引发warnings说,向下保存会引起精度下降,用with就好了,官方文档推荐。

4.验证码需观察其特点对症下药比较快。

相关文章

  • 阿里汇川验证码图像处理

    验证码获取地址 去除图片干扰线 修复图像 图片转为灰度并且去除噪点

  • 验证码去除干扰线

    在邦购登陆时,选择了人工检验验证码,这次用机器检测试试。先说基本逻辑:载入图像,转灰度,二值化,连通域检测,去除连...

  • 前端绘制图形验证码

    一、功能分析 图形验证码由验证码、干扰线、干扰点组合而成 验证码由数字和字母随机组合形成 每次切换验证码,验证码字...

  • 彩色干扰线验证码

    利用Quartz2D实现:绘图步骤: 1.获取上下文 2.描述路径 3.把路径添加到上下文 4.渲染上下文draw...

  • tess4j解析数字验证码

    网上看到了验证码破解,除了像12306越升级越变态的验证码很难破解外,其他比如数字、字母、干扰线之类的还是可以轻松...

  • php验证码

    理论分析 1、实现验证码底图 2、实现数字验证码 输出 3、增加干扰元素 (1)、追加干扰点 输出 (2)、追加干...

  • Java Web 项目关于 Kaptcha 验证码的生成与使用

    Web 端中,为了防止恶意的流量攻击或者为了防止自动化提交,都会在页面中引入验证码。验证码一般是一些加入了干扰线...

  • 产生验证码带干扰线js

  • 2018-03-29

    Java中常用工具类 (1)生成随机ID和随机码-UUIDUtils (2)生成随机验证码-带有干扰线效果-Ver...

  • js 滑动拼图验证码

    以前的验证码很简单,就是一个带些背景色或背景图和干扰线的纯数字字母类的验证码,现在已经发展变得很丰富了。我见过的就...

网友评论

      本文标题:验证码去除干扰线

      本文链接:https://www.haomeiwen.com/subject/hukdnftx.html