Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Python实战图片验证码降噪处理

Python实战图片验证码降噪处理

作者头像
州的先生
发布于 2019-11-06 15:55:07
发布于 2019-11-06 15:55:07
3.2K00
代码可运行
举报
文章被收录于专栏:州的先生州的先生
运行总次数:0
代码可运行

图片验证码算是网络数据采集上的一道拦路虎,虽然有诸多公开的ORC接口、云打码平台,一旦大规模应用起来,还是内部写程序进行识别处理比较好。

而自己写代码进行识别的话,又有很多种方案,比如最近火热的神经网络,一顿炼丹猛如虎,识别准确率99%妥妥的。神经网络训练模型来识别验证码虽然效果好,但是却有两个先天的缺陷:

  • 第一、需要大量的标注数据。很多公开的基于神经网络识别图片验证码的代码都会使用一个验证码生成库来生成大量的已标注的验证码图片,这一步,直接把实际场景下的会消耗大量时间和经历的步骤给忽略掉了;
  • 第二、需要巨大的算力。没钱没配置的小伙伴,用着低级CPU,还想训练神经网络?还是洗洗睡吧。

所以对于一部分小伙伴而言,很现实的状况,还是对图片进行传统的ORC识别比较靠谱。要对图片进行传统的ORC识别,对图片进行各种降噪处理就必不可少,本文,州的先生就介绍一些实际使用到的图片降噪处理方法。

本文所用的示例图片来自于某网站的登录验证码:

可以看到,图片里面大的数据混杂着小的数字和字母,人眼可以迅速地看出来真实的数字,但是对于传统的ORC的话,可能会产生巨大的干扰。我们使用百度AI开放平台中的通用文字识别接口来测试一下:

可以看到,百度的通用文字识别接口将值为3885的数字识别成了38.852,虽然主要的数字都识别出来了,但是却多了许多无关的字符。

我们下面借助OpenCV的Python封装包cv2,对其进行一些降噪处理,使得图片更新清晰和无干扰。

二值化处理

图片处理中,二值化是一个很常见的操作,我们首先将图片转为灰度,然后再根据特定的阈值将图片进行黑白的二值化处理。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import cv2
import matplotlib.pyplot as plt
img = cv2.imread("201910302114.png")
img2 = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
img2 = cv2.inRange(img2, lowerb=160, upperb=255)
plt.subplot(121), plt.imshow(img)  # 原始图片
plt.subplot(122), plt.imshow(img2)  # 降噪图片
plt.show()

在上面的代码中,我们先将图片转换为灰度(cvtColor()步骤),得到的图片如下所示:

左边是原始的图片,右边则是灰度处理后的图片。接着用cv2.inRange()将将阈值内的像素设置黑色,就完成了图片二值化的转换,如下图所示:

阈值不同,得到的二值化图片也会不一样,比如我们之前设置的是160,如果我们将其设置为180,那么得到的二值化图像又会不一样,如下图所示:

可以发现,很多干扰字符也出来的。如何选择合适的阈值,需要根据具体的图片来进行判断。我们将效果最好的图片保存下来,如下图所示:

使用这个图片,我们再去百度AI的通用文字识别接口上测试一下,可以发现相比于之前的识别出错,现在已经完全识别正确了,如下动图所示:

像素降噪

除了上面简单的二值化之外,我们再来看一个更加复杂一点的例子。很多的验证码图片会加上很多干扰点,不仅机器认不出来,有时候连人都认不出来,比如下图这样的验证码图片:

干扰块大量地附着在字符上,甚至有喧宾夺主的趋势。这样的验证码,百度的AI接口也是没辙:

面对这样的验证码,我们要怎么处理呢。下面来看一下。

因为这个图片的底色是白色的,所以我们直接使用cv2的threshold()方法对图像进行二值化处理,小于某个阈值直接置位白色:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import cv2
import matplotlib.pyplot as plt
img = cv2.imread("vcode_2019-10-29141155879867.png")
# 二值化
ret, img2 = cv2.threshold(img, 160, 255, cv2.THRESH_BINARY)
plt.subplot(121), plt.imshow(img)  # 原始图片
plt.subplot(122), plt.imshow(img2)  # 降噪图片
plt.show()

运行上述代码,我们可以得到如下所示的图片:

对比与原始图像,经过二值化后的图像锐利了很多,边缘不再有过渡性的颜色。下一步,我们把那些孤立在图像上的像素点清除掉即可。

如何清除图像中的孤立像素,我们可以选用效果较好的邻域降噪算法。邻域降噪算法通过计算一个像素点邻域的非白色数量来判断是否将其置为白色。其Python代码的实现如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 计算邻域非白色个数
def calculate_noise_count(img_obj, w, h):
    """
    计算邻域非白色的个数
    Args:
        img_obj: img obj
        w: width
        h: height
    Returns:
        count (int)
    """
    count = 0
    width, height,s = img_obj.shape
    for _w_ in [w - 1, w, w + 1]:
        for _h_ in [h - 1, h, h + 1]:
            if _w_ > width - 1:
                continue
            if _h_ > height - 1:
                continue
            if _w_ == w and _h_ == h:
                continue
            if (img_obj[_w_, _h_,0] < 233) or (img_obj[_w_, _h_,1] < 233) or (img_obj[_w_, _h_,2] < 233):
                count += 1
    return count


# k邻域降噪
def operate_img(img,k):
    w,h,s = img.shape
    # 从高度开始遍历
    for _w in range(w):
        # 遍历宽度
        for _h in range(h):
            if _h != 0 and _w != 0 and _w < w-1 and _h < h-1:
                if calculate_noise_count(img, _w, _h) < k:
                    img.itemset((_w,_h,0),255)
                    img.itemset((_w, _h,1), 255)
                    img.itemset((_w, _h,2), 255)

    return img

我们将读取的图像传入operate_img()函数,其就会返回降噪处理后的图像,而且这个函数还可以重复进行调用,每一次调用都是在前一次降噪的基础上进行降噪。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
img2 = operate_img(img2, 4)

在进行第一次邻域降噪后,图像如下图所示:

可以看到,图像上已经减少了很多孤立像素块了。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
img2 = operate_img(img2, 4)
img2 = operate_img(img2, 4)

对二值化后的图像调用两次邻域降噪,降噪的效果更加明显了,如下图所示:

可以发现,图像中孤立的像素点都清除掉了,但是图像四周边缘的噪点还是很顽固。我们再来编写一个简单的算法,将图像四周全部置为白色,代码如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 四周置白色
def around_white(img):
    w, h, s = img.shape
    for _w in range(w):
        for _h in range(h):
            if (_w <= 5) or (_h <= 5) or (_w >= w-5) or (_h >= h-5):
                img.itemset((_w, _h, 0), 255)
                img.itemset((_w, _h, 1), 255)
                img.itemset((_w, _h, 2), 255)
    return img

然后,我们再来编写一个简单的处理算法,就是如果一个像素点上下左右四个连接的像素都跟像素点不是同一个颜色,那么我们将其置为白色:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# 邻域非同色降噪
def noise_unsome_piexl(img):
    '''
        查找像素点上下左右相邻点的颜色,如果是非白色的非像素点颜色,则填充为白色
    :param img:
    :return:
    '''
    # print(img.shape)
    w, h, s = img.shape
    for _w in range(w):
        for _h in range(h):
            if _h != 0 and _w != 0 and _w < w - 1 and _h < h - 1:# 剔除顶点、底点
                center_color = img[_w, _h] # 当前坐标颜色
                # print(center_color)
                top_color = img[_w, _h + 1]
                bottom_color = img[_w, _h - 1]
                left_color = img[_w - 1, _h]
                right_color = img[_w + 1, _h]
                cnt = 0
                if all(top_color == center_color):
                    cnt += 1
                if all(bottom_color == center_color):
                    cnt += 1
                if all(left_color == center_color):
                    cnt += 1
                if all(right_color == center_color):
                    cnt += 1
                if cnt < 1:
                    img.itemset((_w, _h, 0), 255)
                    img.itemset((_w, _h, 1), 255)
                    img.itemset((_w, _h, 2), 255)
    return img

最后,我们结合上面的各种降噪算法,最后得到一个处理得比较好的图像,如下图所示:

用它再去百度AI接口上测试,发现已经完全识别正确的:

以上就是本文介绍的两种验证码图片降噪处理方法,欢迎留言讨论:)

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-10-31,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 州的先生 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
用Python识别图形验证码,实现自动登陆!
验证码有图形验证码、极验滑动验证码、点触验证码、宫格验证码。这回重点讲讲图形验证码的识别。
小F
2020/10/09
2.3K0
用Python识别图形验证码,实现自动登陆!
Python图片验证码降噪 — 8邻域降噪
图片验证码识别的可以分为几个步骤,一般用 Pillow 库或 OpenCV 来实现,这几个过程是:
jhao104
2019/12/05
2.2K0
Opencv:验证码图像处理
首先安装 opencv :(点击链接查看) https://blog.csdn.net/weixin_43582101/article/details/88660570
李玺
2021/11/22
4830
Opencv:验证码图像处理
Python验证码识别
最近在做爬虫的时候发现手动输入验证码算是比较烦了,就网上搜了一下,结果发现真的有现成的,作者:老板丶鱼丸粗面,写的很完整,看一下。所有源码点击阅读原文。
我被狗咬了
2019/09/23
2.9K0
Python验证码识别
【爬虫系列】1. 无事,Python验证码识别入门
代码地址:https://github.com/liguobao/python-verify-code-ocr
李国宝
2021/08/07
4550
验证码的识别
概要:在爬虫中我们时常会碰见登录时候需要识别验证码的问题, 当然,验证码有很多,本篇文章只说最普通的图片验证码。 1、首先需要下载OCR OCR,光学字符识别,作用是通过扫描图片,将其转换为文本。 百
不断折腾
2019/09/23
1.7K0
验证码的识别
Python | 用机器学习搞定数字验证码,还有谁?!
来源:http://www.hi-roy.com/2017/09/19/Python验证码识别
用户1634449
2018/12/18
2K0
cv2处理图片的模板
from PIL import Image from pytesseract import * from fnmatch import fnmatch from queue import Queue import cv2 import time import os def clear_border(img,img_name): '''去除边框 ''' filename = './out_img/' + img_name.split('.')[0] + '-clearBorder.j
小小咸鱼YwY
2020/07/15
4130
Python_识别弱图片验证码
图片验证码采用加干扰线、字符粘连、字符扭曲方式来增强识别难度,对于以上类型的验证码均不支持。 支持的弱验证码如下:
Java架构师必看
2021/03/22
8080
Python_识别弱图片验证码
基于OpenCV和Python的车牌提取和字符分割
前面对这牌提取做个详细描述,与此相类似,车牌的字符分割也是很重要的一部分,字符分割的思想在其他项目中同样有很重要的作用。因此有必要针对字符分割的思路和实现过程做一个记录。
荣仔_最靓的仔
2021/02/02
5K0
基于OpenCV和Python的车牌提取和字符分割
python图像识别---------图片相似度计算
要识别两张图片是否相似,首先我们可能会区分这两张图是人物照,还是风景照等......对应的风景照是蓝天还是大海......做一系列的分类。
andrew_a
2019/07/30
11.7K0
python图像识别---------图片相似度计算
字符型图片验证码识别完整过程及Python实现
本文讲述如何通过对比学习算法实现手写数字识别,并使用一个基于SVM的算法进行测试。通过对比不同算法的效果,得出结论:使用基于SVM的算法可以较好地识别手写数字。
用户1170933
2018/01/05
6.2K0
字符型图片验证码识别完整过程及Python实现
强智教务系统验证码识别 OpenCV
首先使用代码切割验证码,挑选出切割的比较好的验证码,制作比对库 由于使用matchTemplate函数,要求待匹配图必须比库图小,于是需要放大库图边界
WindRunnerMax
2020/08/27
5590
神器!使用Python 轻松识别验证码
在我们进行自动化测试的过程中,免不了要在登录时遇到验证码,很多时候我们都是只能找开发要万能验证码或者暂时关闭验证码这个功能,但是有时候我们必须要验证码是否能够正常生成,所以在这个时候,我们需要做的就是输入验证码,但是验证码这个东西是随机生成的,不是每一次都一样,所以我们还是需要识别然后输入,脚本是没有眼睛的,只能通过代码来进行识别,所以本文就来给大家介绍一下如何使用Python来轻松识别数字验证码。
霍格沃兹测试开发Muller老师
2024/05/12
5370
用Python机器学习搞定验证码
写爬虫有一个绕不过去的问题就是验证码,现在验证码分类大概有4种: 图像类 滑动类 点击类 语音类 今天先来看看图像类,这类验证码大多是数字、字母的组合,国内也有使用汉字的。在这个基础上增加噪点、干扰线、变形、重叠、不同字体颜色等方法来增加识别难度。 相应的,验证码识别大体可以分为下面几个步骤: 灰度处理 增加对比度(可选) 二值化 降噪 倾斜校正分割字符 建立训练库 识别 由于是实验性质的,文中用到的验证码均为程序生成而不是批量下载真实的网站验证码,这样做的好处就是可以有大量的知道明确结果的数据集。 当
小小科
2018/05/02
1.2K0
用Python机器学习搞定验证码
字符型验证码识别
在开发爬虫的过程中会遇到一种常见的反爬措施,验证码。验证码(CAPTCHA)是“Completely Automated Public Turing test to tell Computers and Humans Apart”(全自动区分计算机和人类的图灵测试)的缩写,是一种区分用户是计算机还是人的公共全自动程序。
润森
2019/09/05
1.8K0
字符型验证码识别
用Python识别验证码
很多网站登录都需要输入验证码,如果要实现自动登录就不可避免的要识别验证码。本文以一个真实网站的验证码为例,实现了基于一下KNN的验证码识别。
数据森麟
2019/09/27
1.3K0
Python应用(一) 识别网站验证码以及识别算法
验证码识别涉及很多方面的内容。入手难度大,但是入手后,可拓展性又非常广泛,可玩性极强,成就感也很足。
码科智能
2019/05/26
1K0
【玩转腾讯云】万物皆可Serverless之使用SCF快速部署验证码识别接口
如果部署在服务器端就需要自己去搭建配置网络环境并编写调用接口,这是一个极其繁琐耗时的过程。
乂乂又又
2020/04/17
3.1K0
【玩转腾讯云】万物皆可Serverless之使用SCF快速部署验证码识别接口
Python 实现识别弱图片验证码
目前,很多网站为了防止爬虫肆意模拟浏览器登录,采用增加验证码的方式来拦截爬虫。验证码的形式有多种,最常见的就是图片验证码。其他验证码的形式有音频验证码,滑动验证码等。图片验证码越来越高级,识别难度也大幅提高,就算人为输入也经常会输错。本文主要讲解识别弱图片验证码。
猴哥yuri
2018/08/16
4.2K0
相关推荐
用Python识别图形验证码,实现自动登陆!
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验