吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 4611|回复: 9
上一主题 下一主题
收起左侧

[Python 原创] 【萌新向】基于PIL和Tesseract的数字计算验证码识别处理思路

[复制链接]
跳转到指定楼层
楼主
roshinntou 发表于 2021-4-14 17:51 回帖奖励
本帖最后由 roshinntou 于 2021-4-14 17:54 编辑



如图,我们在使用python自动化的时候经常会遇到很多各式各样的验证码。这个是一个数字加法的验证码。

干扰项里包含完整的数字、字母信息,普通的OCR识别可能不是很准确。

但是不管怎们样,咱们先把必要的环境搭建起来,试一下Tesseract的识别结果吧。

  • 1、安装Tesseract:
首先需要下载Tesseract的安装包 官方网址:https://digi.bib.uni-mannheim.de/tesseract/,网上的教程很多推荐安装名称里不带dev的正式版,据说更稳定


  • 配置Tesseract:
安装完毕之后需要配置一下环境变量,分为两步:
1、在path里加入安装路径,及安装路径内的tessdata文件夹路径。



2、新建系统变量{TESSDATA_PREFIX:E:\Program Files (x86)\Tesseract-OCR\tessdata} 这里变量名是固定的TESSDATA_PREFIX,值是刚刚提到的安装路径内下一级tessdata文件夹的完整路径




然后命令行里 安装pytesseract:
[Python] 纯文本查看 复制代码
pip install pytesseract


完成以上步骤之后,请重新启动电脑。

  • 图片无处理识别:
直接调用ocr识别出结果的话,只需要3行代码:
[Python] 纯文本查看 复制代码
import pytesseract
text = pytesseract.image_to_string('图片路径或者内存的图片对象')
print(text)



但是对于这个验证码的效果不是非常好,比如:



要么是没有结果,要么就是一堆乱七八糟的东西。

这样肯定是用不了的

那么只能先处理一下图片了

  • 图片处理识别:

我下载了20张这个网站的二维码,发现了以下规律:
1、验证码内容一定包含“ = 2位数字+2位数字”的
2、验证码内容的颜色是随机的。
3、验证码内容的位置应该是固定的(20张图片的加号都在同一位置)
4、验证码图片的干扰内容包含字母、数字、符号
5、验证码图片的干扰内容颜色没有跟主要内容一模一样,但是每张图的干扰项一定包含主要内容颜色相近的部分。

可以看到,根据字体的不同,显示的时候,主干是棕色的,但是构成这个字的边员颜色是稍微淡一些的。不过20张图里都没有发现有干扰项的颜色跟主要内容颜色一模一样。

所以我的想法是因为存在主干的近似色,所以主要的滤波手段可能导致把图片变得更难处理的可能性,索性不如直接获取主干颜色,其他像素不是主干颜色的全部以白色替代,删除干扰项之后再进行识别。

主干颜色可以使用固定的加号的正中间那一点的坐标获取。(80,23)(80,24)



代码如下:
[Python] 纯文本查看 复制代码
# -*- coding: utf-8 -*-
"""
Created on Wed Apr 14 16:23:47 2021

@author: roshinntou
"""



from PIL import Image
import pytesseract

def images_to_string(index):
    #导入图片,抓取的时候可以直接获取io流
    img1= Image.open('index ('+str(index)+').png')
    
    #获取图片的长宽
    w,h = img1.size
    print('Original image size: %sx%s' % (w, h))
    
    
    '''
    因为是PNG图片,像素不是直接以RGB保存的,PNG的每个像素里还有透明度
    我们不需要处理透明度,tesseract对于白色和不透明的识别是一样的,这里就转成RGB
    如果图片是jpg的,可以直接使用,不需要 convert
    '''
    img1rbg = img1.convert('RGB')
    
    #读取全部的像素数据
    src_strlist = img1rbg.load()
    
    #获取主干颜色
    data = src_strlist[80,23]
    print(data)
    
    #双层循环开始替换全部的像素点颜色
    for x in range(0,w):
        for y in range(0,h):
            #判断当前点颜色是否等于主干颜色
            co = src_strlist[x,y]
            if co !=data:
                src_strlist[x,y] = (245, 245, 255)
    
    
    #直接调用内存里的PIL image对象进行图片识别
    text = pytesseract.image_to_string(img1rbg)
    text = text.replace(" ","").replace("\r\n","").replace(" ","").replace("\r","").replace("\n","")
    #打印结果
    print(text)
    
    #保存图片
    img1rbg.save(text+'.png')
    
    
if __name__ == '__main__':
    for i in range(1,21):
        images_to_string(i)
    







文件如下:



结语:

准确率我大概看了一下,应该是100%的。以上算是成功破解了对方网站的验证码。


验证码的识别整体思路应该就是这样子了,当然我举得例子是比较简单的验证码。还有各种麻烦的验证码,未来可能需要用到截取、卷积、滤波、清洗等等方法,需要根据实际的情况灵活的使用,但是整体的思路就是:

找到验证码规律,根据规律清洗干扰噪点,然后识别。希望可以启发到大家。

最后的最后,现在已经可以获取验证码的字符串了,计算结果非常简单我就不做了。有兴趣的可以试试,我会把所有图片、源代码打包,大家可以下载了试一下。

Tesseract安装的时候,系统变量那里2步都不能少,少一个程序执行就会报错,切记


yzm.zip (41.49 KB, 下载次数: 21)

免费评分

参与人数 5吾爱币 +15 热心值 +5 收起 理由
thundersword + 1 + 1 我很赞同!
剑来…… + 1 + 1 大佬tql,向大佬学习
xhtdtk + 2 + 1 我很赞同!在刚好的时候遇见了你
苏紫方璇 + 10 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
cckkopit + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

沙发
songxp03 发表于 2021-4-14 20:54
厉害了,学习了
3#
cckkopit 发表于 2021-4-14 22:20
非常有借鉴意义,对于萌新非常友好!

谢谢分享,代码成功执行,很有帮助!
4#
cckkopit 发表于 2021-4-15 10:54
本帖最后由 cckkopit 于 2021-4-15 10:55 编辑

验证码.zip (10.04 KB, 下载次数: 2)

请问遇到这种不规则的验证码,而且验证码有倾斜的情况怎么办?

求一个解题思路,不用代码。能成功就行。






5#
 楼主| roshinntou 发表于 2021-4-15 12:04 |楼主
cckkopit 发表于 2021-4-15 10:54
请问遇到这种不规则的验证码,而且验证码有倾斜的情况怎么办?

求一个解题思路,不用代码。能成功就 ...

还是那几步:
找到规律,清洗,识别

虽然你这个二维码没有一个固定的位置、颜色但是还是有规律的,主干部分的字比干扰项大很多。

那么:第一步获取颜色的时候可以换一个思路除开背景有可能主体颜色的像素点是最多的。不过看这个干扰项,可能干扰项的像素点也不少。

但是既然文字最大,意味着同一个颜色的像素点链接是最多的用坐标轴的方式循环检查一下哪个颜色的连续比较多就可以定位了,然后获取了颜色之后就可以把其他像素点替换成背景色了。


替换完之后还需要进一步处理的,tesseract的识别或者说绝大多数开源基础ocr识别对于倾斜的识别都很成问题。需要摆正。

摆正的话,网上有很多案例可以参考。我经常使用的是X轴投影计算法,普通字体的字母数字都是瘦高的


就像这张图,字母斜着,X轴的投影肯定比正着要长。


然后根据连续性截取这个字母,计算质心,根据质心旋转,每次旋转计算一次X轴投影,直到找到最小的那个,就一定是字母摆正或者摆正180度颠倒的。
PS:实际上,验证码字母很少有反着放的,你反转的时候随便设定一个方向,如果第二次的投影比第一次大,就反方向旋转,直到旋转的这次投影比上一次大为止,就可以获得摆正了。

摆正之后就是识别的问题了。如果字体不常见得稍微训练以下。

你的这个我研究研究一会看看能识别出来不。
6#
 楼主| roshinntou 发表于 2021-4-15 13:34 |楼主
cckkopit 发表于 2021-4-15 10:54
请问遇到这种不规则的验证码,而且验证码有倾斜的情况怎么办?

求一个解题思路,不用代码。能成功就 ...

识别正确率没办法保证到100%,过滤颜色太粗暴了,字体的颜色都是有主色和多个与主色相比稍淡的颜色组成的,只截取主色的话类似 q  之类的字母斜一点,竖线斜着主色调的部分就少很多,可能竖线的很长一部分就没有了,会被识别成a。

另外单独截取字母出来之后,我没有拼在一起,单独识别也没有设定大小,对于字母的大小写识别不是很理想。 s  j  识别成大写的了






7#
 楼主| roshinntou 发表于 2021-4-15 14:05 |楼主
cckkopit 发表于 2021-4-15 10:54
请问遇到这种不规则的验证码,而且验证码有倾斜的情况怎么办?

求一个解题思路,不用代码。能成功就 ...

关于颜色截取的这个问题,可以根据相似色的筛选办法来做相应的识别。

RGB颜色三个参数对于颜色影响非常大,而且数字差距非常大,一般都不会使用淡出的数字差值来判断。

有一个简单的方法。

设需要比较的两个颜色 RGB分别为 1和2,
那么相差值的计算公式,Python的是:

[Python] 纯文本查看 复制代码
discrepancy = (math.pow((r1-r2),2)+math.pow((g1-g2),2)+math.pow((b1-b2),2))



计算出的结果是一个浮点数字,这个数字越小证明颜色越相近。
比如:

以120来区分的时候结果是这样的:

左边是原来的,右边的小窗口里是120筛选出来的。

然后是150:


然后是180的:


210:

已经有干扰项出来了


打印了一下数值再100-200之间的,结果是:
[Python] 纯文本查看 复制代码
Original image size: 200x62
(107, 1, 70)
126.53458025377884
126.53458025377884
126.53458025377884
169.44910740396364
114.42464769445436
169.44910740396364
142.22517358048822
169.44910740396364
171.36218952849546
169.44910740396364
126.53458025377884
126.53458025377884
169.44910740396364
169.44910740396364
169.44910740396364
126.53458025377884
126.53458025377884
186.82076972328318
169.44910740396364
169.44910740396364
124.54717981552211
169.44910740396364
126.53458025377884
126.53458025377884
126.53458025377884
126.53458025377884
126.53458025377884
126.53458025377884
169.44910740396364
169.44910740396364
126.53458025377884
126.53458025377884
126.53458025377884
169.44910740396364
126.53458025377884
126.53458025377884
169.44910740396364
126.53458025377884
169.44910740396364
169.44910740396364
169.44910740396364
169.44910740396364
126.53458025377884
169.44910740396364
169.44910740396364
169.44910740396364
126.53458025377884
169.44910740396364
169.44910740396364
169.44910740396364
126.53458025377884
126.53458025377884
126.53458025377884
126.53458025377884
126.53458025377884
126.53458025377884
126.53458025377884
126.53458025377884
126.53458025377884
169.44910740396364
169.44910740396364
169.44910740396364
169.44910740396364
126.53458025377884
169.44910740396364
126.53458025377884
169.44910740396364
169.44910740396364
197.71696942852427
136.1396341995967
169.44910740396364
169.44910740396364
169.44910740396364
169.44910740396364
164.10362579784763
126.53458025377884
126.53458025377884
126.53458025377884
126.53458025377884
169.44910740396364
126.53458025377884
169.44910740396364
169.44910740396364
126.53458025377884
169.44910740396364
169.44910740396364
126.53458025377884
126.53458025377884
126.53458025377884
126.53458025377884
126.53458025377884
126.53458025377884
126.53458025377884
126.53458025377884



可以看到170就比较准确了

这样截取的会更完整一些

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
cckkopit + 1 + 1 谢谢,我已经可以扶正验证了,但是字体识别不了。继续研究,谢谢大佬分享思.

查看全部评分

8#
L_Pandas 发表于 2021-4-16 11:59
学习了,根据规律去除部分噪声
9#
剑来…… 发表于 2021-4-18 10:26
真这是真大佬,学习了学习了
10#
yuyuan521 发表于 2023-2-1 11:32
谢谢大哥分享
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-6-7 09:01

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表