Python 轻松去除验证码干扰点,让识别不再犯难

Python 轻松去除验证码干扰点,让识别不再犯难

作者:高玉涵
时间:2024.8.29 21:52
博客:blog.csdn.net/cg_i
环境:Windows10、Python 3.11.3、PIL、Tesseract-OCR

山高月小,水落石出。

引言

在进行爬虫开发或自动化操作时,我们经常会遇到需要登录网页(或软件)的情况。而在登录过程中,验证码是一个常见且需要特别处理的问题。验证码(CAPTCHA)作为一种区分用户是计算机还是真实人类的程序,经常要求用户输入一些只有真实人类才能轻松解读的信息,以此来有效阻止自动化工具或机器人的恶意操作。处理验证码成为了爬虫和自动化操作过程中的一只拦路虎。验证码按展现形式,又分为静态验证码动态验证码,本文主要讨论关于静态验证码的识别。

随着OCR(光学字符识别)技术日趋完善,有些组织或个人免费(大善)提供了开源的OCR引擎(如,Tesseract-OCR),使得从验证码图片中识别出文字变得容易了些。然而,”道高一尺,魔高一丈“,在此消彼长之时,验证码也相应的增加了多种”噪声“技术以干扰OCR的识别。

限于篇幅,本文关于”噪声“技术的讨论,仅限于干扰点噪声。淡到验证码,必然会涉及验证码字符的识别,我给出的例子代码中会出现Tesseract-OCR引擎的调用。这里我不会详细讨论如何使用它们以及环境搭建,此举旨在突出讨论的重心(对图像操作),我只会在实在绕不过的地方,着以笔墨,稍作解释。关于缺失部分,我会另找时间,单独开一篇另行讨论。这里提前声明,也请大家谅解。

一、干扰点噪声

干扰点噪声,作为一种常见的图像降质现象,表现为图像中随机散布的大量孤立点。这些点的灰度值与周围像素点的灰度值存在显著差异,呈现出类似椒盐噪声的特征。如图(1-1)所示为一个登录界面的示例,而图(1-2)则展示了一个带有干扰点噪声的验证码图片。
在这里插入图片描述

(1-1 登录界面示例)

在这里插入图片描述

(1-2 带干扰点的验证码)

在未经任何预处理的情况下,我们尝试使用Tesseract-OCR来识别图(1-2)中的验证码。首先,将验证码图片下载到本地,然后在图片所在的目录下执行了以下命令:

tesseract 2.png output

然而,执行结果却显示页面为空,如下所示:

Estimating resolution as 150
Empty page!!
Estimating resolution as 150
Empty page!!

从这一提示中,我们可以明显看出OCR识别未能成功。进一步查看输出文件output.txt,其内容果然为空。这是因为干扰点噪声会严重影响OCR算法的识别效果。OCR算法依赖于图像中的文字具有相对清晰和连贯的轮廓,而噪声点的存在会破坏这些轮廓,使得算法无法正确识别文字。

二、图片降噪

通过观察,我发现验证码图片中的干扰点相对简单,因为所有干扰点的颜色都相同。针对这一特点,我可以先获取干扰点的颜色,然后清除它,以达到清除干扰点的目的。具体操作是,首先使用Windows自带的画图工具打开验证码图片,接着使用颜色选取器选取干扰点的颜色值(图2-1),之后点击编辑颜色,此时就可以查看到该颜色的RGB值(图2-2)。
在这里插入图片描述

(2-1 颜色选取器)

在这里插入图片描述

(2-2 RGB值)

干扰点清除代码:

from PIL import Image

def get_noise_color(image):
	w = image.size[0]
	h = image.size[1]
	
	for x in range(w):
		for y in range(h):
			(r, g, b) = image.getpixel((x, y))
			# 干扰点颜色
			if (r,g,b) == (44,90,60):
				# 用它前面像素颜色填充它,思想:相近的颜色对原图影响最小
				image.putpixel((x, y), image.getpixel((x - 1, y)))
			
	return image


def clear_save_image(image_path):
	image = Image.open(image_path)
	image = image.convert('RGB')
	image = get_noise_color(image)
	image.save("2_clear.png")
	

if __name__ == '__main__':
	clear_save_image(r'2.png')

这段代码的具体步骤和代码解释如下:

  1. 导入库:
  • from PIL import Image:从PIL(Python Imaging Library,现在称为Pillow)库中导入Image模块,用于图片处理。
  1. 定义get_noise_color函数:
  • 这个函数接收一个Image对象作为输入。
  • 首先,获取图片的宽度w和高度h
  • 然后,遍历图片中的每一个像素。对于每个像素,获取其RGB颜色值。
  • 如果某个像素的颜色是(44, 90, 60)(噪点颜色),则将这个像素的颜色替换为其前一个像素的颜色(即(x - 1, y)位置的颜色)。
  • 最后,返回处理后的Image对象。
  1. 定义clear_save_image函数:
  • 这个函数接收一个图片路径image_path作为输入。
  • 使用Image.open(image_path)打开并读取图片。
  • 使用image.convert('RGB')将图片转换为RGB模式,确保图片有三个颜色通道。
  • 调用get_noise_color函数去除图片中的噪点。
  • 将处理后的图片保存为"2_clear.png"。
  1. 主函数:
  • 如果直接运行这个脚本,将调用clear_save_image函数,传入一个图片路径(这里是’2.png’),对图片进行处理并保存。

三、测试运行结果

首先,执行这个Pyhton程序:

python .\clear_noisy.py

执行后,会生成一个名为2_clear.png的图片(如图3-1所示),这是清除噪点后的验证码图片。
在这里插入图片描述

(图 3-1 清除噪点后的验证码图片)

接着,我们使用Tesseract-OCR来识别处理后的图像。执行以下命令:

tesseract 2_clear.png output
Estimating resolution as 133

此时,明显可以看出较上次,输出的结果明显不同。为了进一步验证,我们打开output.txt文件,可以看出验证码已被正常识别出来了(如图 3-2 所示)。
在这里插入图片描述

(图 3-2 验证码值)

写在最后

首先,衷心感谢你坚持阅读至此。或许在你看来,这篇文章的内容并不复杂,甚至觉得不过如此。但无论你信不信,上述提供的代码背后,是我耗费了大量精力、历经诸多曲折、不断尝试与修正的成果。在无数次的测试与修改中,我删除了大量代码,经历了无数次的失败。最终,在灵光一闪的瞬间,我才得出了这几行简洁而有效的代码。这个过程虽然充满挑战,但也让我深刻体会到了编程的魅力与乐趣。希望我的分享能对你有所启发,也期待你在编程的道路上不断探索与成长。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值