这段时间实习工作和找工作,导致时间很忙。现在有时间,还是希望把自己最近的工作感触和所完成的项目经验分享给大家。也算是对自己的一个总结。学习漫长的生涯里,作为我这个算法工程师这个职位非常重要,也希望大家互相督促养成好的纪律习惯。今天我要分享的一个项目是公司里爬虫经常用到的项目,破解验证码。博主下面要做很多验证码的破解,喜欢的同学可以跟进我的博客,我做出来都会分享出来的。现在已经完成两个验证码的破解,下面首先给大家介绍数字加减验证码的破解。

一、数据展示:

         

二、场景和目的

在大数据时代,如何借助互联网获得最大数据是很多TOB公司追求的资源。通过这些数据我们能够获得很多有效的智能推荐。

然而在网上进行爬虫数据的过程中会出现验证码的输入,导致爬数据的中断,影响工作进度。如果专职聘请一位员工输入验证码会费钱费力。因此需要机器自动识别和破解出现验证码。例如知道了第一张图,我就能得到28。自动输入数字(这一部分我们不探究),完成数据的持续爬。

三、算法分析

大家可能像我一样开始就会有一些思虑,但是不知道采用那个更有效。针对这种情况,不同的应用场景是有不一样的解决方案的。针对这个问题我们的思虑有下面这些:

1、切割+识别:该方法是大家最常用的方法,他有优点是,算法基础完善,我们只需要完成验证码的切割,就可以进行下一步的深度学习模型训练。但是缺点是,深度学习需要大量的数据,我们还要对切割的数据进行标注,这个过程中需要很大的经理。大家像了解这种方法网上大把,我就不介绍了。

2、CNN和CTC的方法,这个方法有一个场景是上一个方法不能做到的就是可以对缠连的数据进行识别,其中CTC这个方法来源于语音识别里面的思想。该方法能够对缠连数据进行一个合理的分离,能够达到很好的效果。但是缺点是不适合大图的分离,应用也是有局限,不过对长条验证码有很好的效果。另外就是需要大量的标注。

四、本文算法

我今天分享的算法,理论会听起来很简单,不多这个想法不太容易想到,我采用的是结合传统opencv的方法。该方法的想起,还是结合了对数据的分析。前面我们能够看到验证码的形式是一样的。包括 形状位置大小等信息。从而也体现出某局的技术含量有点低,给了我一个走捷径的方法。

数据分析,经过自己的二值化处理和灰度读取的方法对数据进行分析,发现验证码中的字符的像素位置和高度,完全相同。因此,我采用了创建PKL文件,来对每个位置的字符进行保存,从而进行检索匹配。这种方法不用训练,准确率高,效果快。但是有一个缺点,值能应用到该场景或者同等场景的情况。

五、源码及分析

#!/usr/bin/env python3
# coding=utf-8"""    @File: Patent-Crack.py@Desc: @Author: lv junling@Date Created: 2018/10/22
"""
import os
import pickle
import cv2
import numpy as np
from PIL import Imageclass PatentCrack(object):def __init__(self, pkl_fn=None):if pkl_fn is None:print('[error]Must specify the pickle filename.')returnself.pkl_fn = pkl_fnif os.path.exists(pkl_fn):self._load_pkl()else:self.gen_pkl_fn()def gen_pkl_fn(self):imgs_path = u'./data'      # 从下面这些数字截取第一个位置的数字chi_1_imgs = ['1.jpeg', '2.jpeg', '3.jpeg', '4.jpeg', '5.jpeg','6.jpeg', '7.jpeg', '8.jpeg', '9.jpeg']chi_2_imgs = ['10.jpeg', '11.jpeg', '12.jpeg', '13.jpeg', '14.jpeg', '15.jpeg','16.jpeg', '17.jpeg', '18.jpeg', '19.jpeg']# 截取第三个位置,也就是加减的矩阵数据op_imgs    = ['1.jpeg', '7.jpeg']chi_3_imgs = ['100.jpeg', '101.jpeg', '102.jpeg', '103.jpeg', '104.jpeg', '105.jpeg','106.jpeg', '107.jpeg', '108.jpeg', '109.jpeg']chi_1_arr = np.zeros([10, 20, 11], dtype=np.bool)# 把每个位置的字符保存成矩阵的形式for idx, img_fn in enumerate(chi_1_imgs):c1, _, _, _ = self._get_split_img(os.path.join(imgs_path, img_fn))chi_1_arr[idx+1] = c1chi_2_arr = np.zeros([10, 20, 9], dtype=np.bool)for idx, img_fn in enumerate(chi_2_imgs):_, c2, _, _ = self._get_split_img(os.path.join(imgs_path, img_fn))chi_2_arr[idx] = c2op_arr = np.zeros([3, 20, 12], dtype=np.bool)for idx, img_fn in enumerate(op_imgs):_, _, op, _ = self._get_split_img(os.path.join(imgs_path, img_fn))op_arr[idx] = opchi_3_arr = np.zeros([10, 20, 10], dtype=np.bool)for idx, img_fn in enumerate(chi_3_imgs):_, _, _, c3 = self._get_split_img(os.path.join(imgs_path, img_fn))chi_3_arr[idx] = c3# 把每个位置的矩阵和标签储存到pkl文件中fout = open(self.pkl_fn, 'wb')data = {'chi_1': chi_1_arr, 'chi_2': chi_2_arr, 'op': op_arr, 'chi_3': chi_3_arr}pickle.dump(data, fout)fout.close()self._load_pkl()def _load_pkl(self):data = pickle.load(open(self.pkl_fn, 'rb'))self.chi_1_arr = data['chi_1']self.op_arr = data['op']self.chi_2_arr = data['chi_2']self.chi_3_arr = data['chi_3']@staticmethoddef _get_split_img(img_fn):img_arr = np.array(Image.open(img_fn).convert('L'))img_arr[img_arr < 156] = 1img_arr[img_arr >= 156] = 0img_arr = img_arr.astype(np.bool)chi_1_arr = img_arr[:,  6:17]chi_2_arr = img_arr[:, 19:28]op_arr    = img_arr[:, 32:44]chi_3_arr = img_arr[:, 45:55]return chi_1_arr, chi_2_arr, op_arr, chi_3_arr@staticmethoddef _cal_result(num1, num2, num3,op):if op == 0:return num1*10 + num2 + num3elif op == 1:return num1*10 + num2 - num3elif op == 2:return num1 * num2else:return int(num1 / num2)# 获得结果的方法def feed(self, img_fn):chi_1_arr, chi_2_arr, op_arr, chi_3_arr = self._get_split_img(img_fn)chi_1_arr = np.tile(chi_1_arr[np.newaxis, :], [10, 1, 1])op_arr = np.tile(op_arr[np.newaxis, :], [3, 1, 1])chi_2_arr = np.tile(chi_2_arr[np.newaxis, :], [10, 1, 1])chi_1_sum = np.sum(np.sum(np.bitwise_and(chi_1_arr, self.chi_1_arr), axis=2), axis=1)chi_2_sum = np.sum(np.sum(np.bitwise_and(chi_2_arr, self.chi_2_arr), axis=2), axis=1)op_sum = np.sum(np.sum(np.bitwise_and(op_arr, self.op_arr), axis=2), axis=1)op_sum[1] += 1   # 区分减号和加号chi_3_sum = np.sum(np.sum(np.bitwise_and(chi_3_arr, self.chi_3_arr), axis=2), axis=1)num1 = chi_1_sum.argmax()num2 = chi_2_sum.argmax()op = op_sum.argmax()num3 = chi_3_sum.argmax()result = self._cal_result(num1, num2,num3, op)print (result)def test():crack = PatentCrack('Patent.pkl')crack.feed(os.path.join('86-0.jpeg'))# fn_list = [fn for fn in os.listdir(u'../04_data/企业证书/cnca')]# fn_list.sort()# for fn in fn_list[:50]:#     crack.feed(os.path.join(u'../04_data/企业证书/cnca', fn))if __name__=='__main__':test()

五、总结

上面就是我对理论和代码的分析,如果想获得完整的工程请到我的github上下载(https://github.com/machine-lv/Verification-code-cracking)

深度学习(七)——图像验证码破解(数字加减验证码)相关推荐

  1. 用深度学习玩图像的七重关卡

    用深度学习玩图像的七重关卡 第一个重境界: 图像识别 如果你开始了解深度学习的图像处理, 你接触的第一个任务一定是图像识别 : 比如把你的爱猫输入到一个普通的CNN网络里, 看看它是喵咪还是狗狗. 一 ...

  2. 【AI初识境】近20年深度学习在图像领域的重要进展节点

    文章首发于微信公众号<有三AI> [AI初识境]近20年深度学习在图像领域的重要进展节点 这是专栏<AI初识境>的第3篇文章.所谓初识,就是对相关技术有基本了解,掌握了基本的使 ...

  3. 【AI白身境】深度学习必备图像基础

    文章首发于微信公众号<有三AI> [AI白身境]深度学习必备图像基础 今天是新专栏<AI白身境>的第四篇,所谓白身,就是什么都不会,还没有进入角色. 我们已经说了linux基础 ...

  4. AI Studio 飞桨 零基础入门深度学习笔记6.3-手写数字识别之数据处理

    AI Studio 飞桨 零基础入门深度学习笔记6.3-手写数字识别之数据处理) 概述 前提条件 读入数据并划分数据集 扩展阅读:为什么学术界的模型总在不断精进呢? 训练样本乱序.生成批次数据 校验数 ...

  5. 在Tensorflow中使用深度学习构建图像标题生成器

    by Cole Murray 通过科尔·默里(Cole Murray) 在Tensorflow中使用深度学习构建图像标题生成器 (Building an image caption generator ...

  6. 深度学习:图像检测概述rcnn, fastrcnn, fasterrcnn,yolo,ssd

    RCNN,Fast RCNN ,faster Rcnn :https://www.cnblogs.com/dudumiaomiao/p/6560841.html 一文看懂目标检测 rcnn fast ...

  7. 基于深度学习的图像超分辨率重建技术的研究

    1 超分辨率重建技术的研究背景与意义 图像分辨率是一组用于评估图像中蕴含细节信息丰富程度的性能参数,包括时间分辨率.空间分辨率及色阶分辨率等,体现了成像系统实际所能反映物体细节信息的能力.相较于低分辨 ...

  8. python opencv 录制视频_如何使用OpenCV、Python和深度学习在图像和视频中实现面部识别?...

    Face ID 的兴起带动了一波面部识别技术热潮.本文将介绍如何使用 OpenCV.Python 和深度学习在图像和视频中实现面部识别,以基于深度识别的面部嵌入,实时执行且达到高准确度. 以下内容由 ...

  9. 学习笔记之——基于深度学习的图像超分辨率重建

    最近开展图像超分辨率( Image Super Resolution)方面的研究,做了一些列的调研,并结合本人的理解总结成本博文~(本博文仅用于本人的学习笔记,不做商业用途) 本博文涉及的paper已 ...

最新文章

  1. 熟悉的亲切-老外婆教做的豌豆蔬菜汤
  2. tcga数据下载_好东西丨零基础入门TCGA
  3. H5在原生手机上显示选中文字效果
  4. python找到文件夹下指定文件类型_python 读取指定文件夹中的指定文件类型的文件名...
  5. 各种存储分配算法java代码实现_Java实现操作系统中四种动态内存分配算法:BF+NF+WF+FF...
  6. 一种提升语音识别准确率的方法与流程
  7. 转:Android ViewPager多页面滑动切换以及动画效果
  8. Linux运维跳槽40道面试精华题
  9. Linux文件系统(七)---系统调用之open操作(一)
  10. nec编码红外遥控原理整理
  11. Python进行拉勾网数据爬取框架与思路
  12. android 谷歌地图_Google天空地图可将您的Android手机变成数码望远镜
  13. 感慨一下中年人的焦虑
  14. 不要轻易在简历上写我热爱编程,我热爱学习
  15. 快速应对面试--分门别类--8.二叉树和递归
  16. HDU - 1548 A strange lift
  17. 怎么用计算机搜索文件,如何查找文件 巧用Win7快速查找文件
  18. 【新周报(049)】Datawhale组队学习
  19. NBA名人堂之-约翰·哈夫利切克|杰里·卢卡斯|詹姆斯·沃西|乔治·格温|沃尔特·弗雷泽
  20. 三级网络技术_无线局域网设备安装与调试

热门文章

  1. 华科大考研计算机系834大纲之数据结构(六)
  2. Qt中Q_D宏及d指针
  3. 用opacity方法来隐藏元素后,照样可以触发绑定在其身上的点击事件
  4. 手把手教你用Python打造一款属于你自己的个性二维码
  5. Python的下载及安装
  6. “互联网” 的群星闪耀时
  7. 【第83期】10 款你不知道的 Linux 环境下的替代工具!
  8. win10计算机自带的游戏怎么打开方式,win10自带游戏及应用打不开,应用商店闪退无法使用...
  9. OpenCV 各版本百度云下载
  10. android wifi 共享网络,安卓手机怎么共享XP的网络 无线wifi共享教程【详解】