爬虫Python验证码识别入门
目录
- 爬虫Python验证码识别
- 1、批量下载验证码图片
- 2、识别代码看看效果
- 3、折腾降噪、去干扰
爬虫Python验证码识别
前言:
二值化、普通降噪、8邻域降噪
tesseract、tesserocr、PIL
参考文献--代码地址:https://github.com/liguobao/python-verify-code-ocr
1、批量下载验证码图片
import shutilimport requestsfrom loguru import loggerfor i in range(100):url = 'http://xxxx/create/validate/image'response = requests.get(url, stream=True)with open(f'./imgs/{i}.png', 'wb') as out_file:response.raw.decode_content = Trueshutil.copyfileobj(response.raw, out_file)logger.info(f"download {i}.png successfully.")del response
文章图片
文章图片
2、识别代码看看效果
from PIL import Imageimport tesserocrimg = Image.open("./imgs/98.png")img.show()img_l = img.convert("L")# 灰阶图img_l.show()verify_code1 = tesserocr.image_to_text(img)verify_code2 = tesserocr.image_to_text(img_l)print(f"verify_code1:{verify_code1}")print(f"verify_code2:{verify_code2}")
文章图片
文章图片
毫无疑问,无论是原图还是灰阶图,一无所有。
3、折腾降噪、去干扰
【爬虫Python验证码识别入门】Python图片验证码降噪 - 8邻域降噪
from PIL import Image# https://www.cnblogs.com/jhao/p/10345853.html Python图片验证码降噪 — 8邻域降噪 def noise_remove_pil(image_name, k):"""8邻域降噪Args:image_name: 图片文件命名k: 判断阈值Returns:"""def calculate_noise_count(img_obj, w, h):"""计算邻域非白色的个数Args:img_obj: img objw: widthh: heightReturns:count (int)"""count = 0width, height = img_obj.sizefor _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.getpixel((_w_, _h_)) < 230:# 这里因为是灰度图像,设置小于230为非白色count += 1return countimg = Image.open(image_name)# 灰度gray_img = img.convert('L')w, h = gray_img.sizefor _w in range(w):for _h in range(h):if _w == 0 or _h == 0:gray_img.putpixel((_w, _h), 255)continue# 计算邻域非白色的个数pixel = gray_img.getpixel((_w, _h))if pixel == 255:continueif calculate_noise_count(gray_img, _w, _h) < k:gray_img.putpixel((_w, _h), 255)return gray_imgif __name__ == '__main__':image = noise_remove_pil("./imgs/1.png", 4)image.show()
看下图效果:
文章图片
这样差不多了,不过还可以提升
提升新思路:
文章图片
这边的干扰线是从某个点发出来的红色线条,
其实我只需要把红色的像素点都干掉,这个线条也会被去掉。
from PIL import Imageimport tesserocrimg = Image.open("./imgs/98.png")img.show()# 尝试去掉红像素点w, h = img.sizefor _w in range(w):for _h in range(h):o_pixel = img.getpixel((_w, _h))if o_pixel == (255, 0, 0):img.putpixel((_w, _h), (255, 255, 255))img.show()img_l = img.convert("L")# img_l.show()verify_code1 = tesserocr.image_to_text(img)verify_code2 = tesserocr.image_to_text(img_l)print(f"verify_code1:{verify_code1}")print(f"verify_code2:{verify_code2}")
看起来OK,上面还有零星的蓝色像素掉,也可以用同样的方法一起去掉。
文章图片
文章图片
甚至OCR都直接出效果了
好了,完结撒花。
不过,后面发现,有些红色线段和蓝色点,是和验证码重合的。
这个时候,如果直接填成白色,就容易把字母切开,导致识别效果变差。
当前点是红色或者蓝色,判断周围点是不是超过两个像素点是黑色。
是,填充为黑色。
否,填充成白色。
最终完整代码:
from PIL import Imageimport tesserocrfrom loguru import loggerclass VerfyCodeOCR():def __init__(self) -> None:passdef ocr(self, img):""" 验证码OCRArgs:img (img): imgObject/imgPathReturns:[string]: 识别结果"""img_obj = Image.open(img) if type(img) == str else imgself._remove_pil(img_obj)verify_code = tesserocr.image_to_text(img_obj)return verify_code.replace("\n", "").strip()def _get_p_black_count(self, img: Image, _w: int, _h: int):""" 获取当前位置周围像素点中黑色元素的个数Args:img (img): 图像信息_w (int): w坐标_h (int): h坐标Returns:int: 个数"""w, h = img.sizep_round_items = []# 超过了横纵坐标if _w == 0 or _w == w-1 or 0 == _h or _h == h-1:return 0p_round_items = [img.getpixel((_w, _h-1)), img.getpixel((_w, _h+1)), img.getpixel((_w-1, _h)), img.getpixel((_w+1, _h))]p_black_count = 0for p_item in p_round_items:if p_item == (0, 0, 0):p_black_count = p_black_count+1return p_black_countdef _remove_pil(self, img: Image):"""清理干扰识别的线条和噪点Args:img (img): 图像对象Returns:[img]: 被清理过的图像对象"""w, h = img.sizefor _w in range(w):for _h in range(h):o_pixel = img.getpixel((_w, _h))# 当前像素点是红色(线段) 或者 绿色(噪点)if o_pixel == (255, 0, 0) or o_pixel == (0, 0, 255):# 周围黑色数量大于2,则把当前像素点填成黑色;否则用白色覆盖p_black_count = self._get_p_black_count(img, _w, _h)if p_black_count >= 2:img.putpixel((_w, _h), (0, 0, 0))else:img.putpixel((_w, _h), (255, 255, 255))logger.info(f"_remove_pil finish.")# img.show()return imgif __name__ == '__main__':verfyCodeOCR = VerfyCodeOCR()img_path = "./imgs/51.png"img= Image.open(img_path)img.show()ocr_result = verfyCodeOCR.ocr(img)img.show()logger.info(ocr_result)
文章图片
到此这篇关于爬虫Python验证码识别入门的文章就介绍到这了,更多相关Python验证码识别内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
推荐阅读
- python学习之|python学习之 实现QQ自动发送消息
- 逻辑回归的理解与python示例
- python自定义封装带颜色的logging模块
- 【Leetcode/Python】001-Two|【Leetcode/Python】001-Two Sum
- Python基础|Python基础 - 练习1
- Python爬虫|Python爬虫 --- 1.4 正则表达式(re库)
- Python(pathlib模块)
- python青少年编程比赛_第十一届蓝桥杯大赛青少年创意编程组比赛细则
- Python数据分析(一)(Matplotlib使用)
- 爬虫数据处理HTML转义字符