算数验证码识别(运算符为中文:加、减、乘)

工作中遇到的需要破解算数验证码的情况

如图:

刚开始 想到的是 切割识别,但是,识别成功率太低了,就放弃了。

然后看到了一篇知乎文章,原文链接:python爬虫验证码识别 (手把手教会你验证码识别)opencv图像处理 图片处理 验证码处理 降噪 简单易懂验证码处理 - 知乎

 借鉴了里面的方法。

我遇到的验证码都是来自此处:https://cmegsb.cma.org.cn/national_project/CheckCodeImageServlet

 第一步:先批量下载图片保存至本地文件夹

def getImg():
    i = 0
    while i < 10:
        html = requests.get('https://cmegsb.cma.org.cn/national_project/CheckCodeImageServlet', verify=False)
        image = Image.open(BytesIO(html.content))
        image.save('img_test/%s.jpg' % i)
        i += 1
        print(i)

第二步:先安装  pip install muggle_ocr  可能会提示下载失败,

可以:pip install  -i https://pypi.douban.com/simple/ muggle_ocr(参考:pip install muggle_ocr 失败,解决办法_lsf_007的博客-CSDN博客

def begin():
    # 图片链接路径
    path = r"D:\img_test"
    import muggle_ocr
    sdk = muggle_ocr.SDK(model_type=muggle_ocr.ModelType.OCR)
    threshold_values = [115, 150, 127, 90, 120, 130, 135, 145, 155, 160, 180]
    for threshold in threshold_values:
        total = len(os.listdir(path))
        errorCount = 0
        for index, i in enumerate(os.listdir(path)):
            right_str = i.split("_")[0]
            print('%s / %s' % (index + 1, total), i + "->" + right_str)
            yzm = cv2.imread(path + '\\' + i)  # 读图片
            yzm = cv2.cvtColor(yzm, cv2.COLOR_BGR2GRAY)  # cv2 方法灰度化
            # 二值化
            thresh, yzm = cv2.threshold(yzm, threshold, 255, cv2.THRESH_BINARY)
            # yzm:表示需要操作的数组
            # threshold:表示阈值 (根据验证码图片特性 可选值:90、115、120、127、130、135、150、155、160、180)、常用【115、150、127】--- 这些都是我一个一个的测试出来的
            # 255 表示最大值
            # 降噪
            yzm = cv2.morphologyEx(yzm, cv2.MORPH_CLOSE, np.ones(shape=(1, 1)))
            # 保存灰度化的图片
            cv2.imwrite('new_img.png', yzm)
            img = open('new_img.png', 'rb').read()
            text = sdk.predict(image_bytes=img)
            if ('乘' in text or '减' in text or '加' in text) and (str(text).replace(' ', '').endswith('=?')):
                # 判断是否为 正常值
                b = text.replace('=', '').replace('?', '')
                a = b.split('乘') if '乘' in text else b.split('加') if '加' in text else b.split('减')
                a1 = a[0]
                a2 = a[1]
                try:
                    a1 = int(a1)
                    a2 = int(a2)
                    print('%s / %s' % (index + 1, total), threshold, ' 正常code: ', text)
                    print(a1, a2, type(a1), type(a2))
                    _id = hashlib.md5(str(datetime.datetime.now()).encode('utf-8')).hexdigest()
                    try:
                        # 用 a、b 代替 =、?
                        new_path = './img_save/%s_%s.png' % (text.replace('?', 'b').replace('=', 'a'), _id)
                        os.rename(path + '\\' + i, new_path)
                        try:
                            os.remove(path + '\\' + i)
                        except:
                            pass
                    except Exception as e:
                        errorCount += 1
                except:
                    errorCount += 1
            else:
                errorCount += 1
        print('运行结束:threshold: %s  共 %s 个, 成功:%s , 失败:%s' % (threshold, total, total - errorCount, errorCount))

用 muggle_ocr 去识别(识别率 55%左右,比较低),

所以,我就用此识别,筛选出有效的 验证码,然后打标记,作为训练集。

最后,强烈推荐一款开源的训练框架: https://github.com/kerlomz/captcha_trainer

用此训练过之后,识别率达到了 95%以上。

识别效果:

 

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值