神经网络降噪python_Python实战图片验证码降噪处理

本文介绍了如何使用Python的OpenCV库对图片验证码进行降噪处理,包括二值化和邻域降噪算法,以提高传统OCR识别的准确性。通过实例展示了处理前后对比,并分享了适用于不同验证码类型的降噪技巧。
摘要由CSDN通过智能技术生成

点击关注州的先生

编程应用、实战教程,不容错过

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

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

第一、需要大量的标注数据。很多公开的基于神经网络识别图片验证码的代码都会使用一个验证码生成库来生成大量的已标注的验证码图片,这一步,直接把实际场景下的会消耗大量时间和经历的步骤给忽略掉了;

第二、需要巨大的算力。没钱没配置的小伙伴,用着低级CPU,还想训练神经网络?还是洗洗睡吧。

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

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

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

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

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

二值化处理

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

import cv2import matplotlib.pyplot as pltimg = 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()方法对图像进行二值化处理,小于某个阈值直接置位白色:

import cv2import matplotlib.pyplot as pltimg = 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代码的实现如下所示:

# 计算邻域非白色个数def calculate_noise_count(img_obj, w, h):"""计算邻域非白色的个数Args:img_obj: img objw: widthh: heightReturns:count (int)"""count = 0width, height,s = img_obj.shapefor _w_ in [w - 1, w, w + 1]:for _h_ in [h - 1, h, h + 1]:if _w_ > width - 1:continueif _h_ > height - 1:continueif _w_ == w and _h_ == h:continueif (img_obj[_w_, _h_,0] < 233) or (img_obj[_w_, _h_,1] < 233) or (img_obj[_w_, _h_,2] < 233):count += 1return 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()函数,其就会返回降噪处理后的图像,而且这个函数还可以重复进行调用,每一次调用都是在前一次降噪的基础上进行降噪。

img2 = operate_img(img2, 4)

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

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

img2 = operate_img(img2, 4)img2 = operate_img(img2, 4)

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

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

# 四周置白色def around_white(img):w, h, s = img.shapefor _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

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

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

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

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

▼点击“阅读原文”,学实战编程

万水千山总是情,点个“在看”行不行▼

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值