问题

登录某网站,需要输入验证码,其中图形验证码需要按照描述的汉字顺序,点击潜藏在图片中的汉字,以完成验证

分析

如果使用神经网络去进行识别中文验证码,则因为汉字数量庞大需要比较大的算力和大数据积累,想想知难后退了。

后来,想到openCV中存在模板匹配度的接口cv.matchTemplate,而且此登录网站的字体比较规整,没有任何倾斜和模糊,可能能够使用opencv完成识别

解决方案

采集网站提示的中文点击顺序,然后逐汉字形成匹配模板,最后,对于验证码图片作为输入源,进行模板匹配。

特别地,在调用opencv后得到匹配位置上,需要再通过模板图片大小,来计算鼠标中心位置。

虽然,此解决方案的识别率并不是很高,可能只在10%左右。但好在网站没有对于反复的尝试登录,采取封IP或者账户的“冰冻”纵深防御技术,所以,虽然有点蹩脚,但也是暂时可以使用的:)


附录

import os,sys,shutil,math
import cv2 as cv
import numpy as np
from PIL import Image, ImageDraw, ImageFont
import base64,re# 'TM_CCORR' is not so good
methods  = ['cv.TM_CCOEFF', 'cv.TM_CCOEFF_NORMED', 'cv.TM_CCORR_NORMED', 'cv.TM_SQDIFF', 'cv.TM_SQDIFF_NORMED']# openCV识别图片存在某些左上角点存在比较小的差异,可以认为是同一个位置
def reduceSmallDifference(posList):uniqueSet = set(posList)#ColorLog.info("original posList: {}, uniqueSet: {}".format(posList, uniqueSet))tmpList   = list(uniqueSet)setSize   = len(uniqueSet)if setSize == 2 and math.dist(tmpList[0], tmpList[1]) > 2 :#ColorLog.info("only has two item and distance is bigger")return posListwhile setSize > 1 :unique = uniqueSet.pop()for i,e in enumerate(posList):dist = math.dist(unique, e)if dist > 0 and dist < 2 :posList[i]  = uniqueif e in uniqueSet:uniqueSet.remove(e)setSize  = len(uniqueSet)return posList# openCV模板匹配
def recognizeTemplate(img, template):h,w,l       = template.shape[::]# All the 6 methods for comparison in a listtopLeftSet  = set()topLeftList = [];for meth in methods:method = eval(meth)# Apply template Matchingres    = cv.matchTemplate(img, template, method)min_val, max_val, min_loc, max_loc = cv.minMaxLoc(res)# If the method is TM_SQDIFF or TM_SQDIFF_NORMED, take minimumif method in [cv.TM_SQDIFF, cv.TM_SQDIFF_NORMED]:top_left = min_locelse:top_left = max_locbottom_right = (top_left[0] + w, top_left[1] + h)topLeftList.append(top_left)topLeftSet          = set(topLeftList)#ColorLog.info('topLeftList:{},topLeftSet:{}'.format(topLeftList, topLeftSet))reduceSmallDifference(topLeftList)topLeftSet          = set(topLeftList)#ColorLog.info('reduce topLeftList:{}, topLeftSet:{}'.format(topLeftList, topLeftSet))max_percent        = 0.0max_percent_unique = (0, 0)for unique in topLeftSet:stat = [ x for x in topLeftList if x == unique ]max_percent_tmp     = (len(stat)/float(len(methods)))# always has value when fail can produce randommax_percent_unique  = uniqueif max_percent_tmp > 0.5:max_percent            = max_percent_tmpbreak#ColorLog.info('max_percent: {}, topLeft: {}'.format(max_percent, max_percent_unique))return max_percent, max_percent_unique# 从汉字形成模板图片
def formChineseTemplate(text, templateSize=(34, 34), textSize=24):img      = np.uint8(np.zeros(templateSize))img      = Image.fromarray(img)img_draw = ImageDraw.Draw(img)ttf      = ImageFont.truetype("font/msyh.ttc", size=textSize, encoding="utf-8")img_draw.text((1, 0),  text, font=ttf, fill=255, stroke_width=1)img      = np.asarray(img)return imgdef recognizeChineseChar(img, text):template          = formChineseTemplate(text)# to three channelstemplate          = cv.cvtColor(template, cv.COLOR_GRAY2BGR)percent, top_left = recognizeTemplate(img, template)center  = (0,0)if top_left != (0,0):center = (int(top_left[0] + template.shape[1]/2 - 5), int(top_left[1] + template.shape[0]/2 - 5))return center# 如果从网站上截图,可以采用base64编码,以避免读写IO
def base642np(base64_str):base64_str = re.sub('^data:image/.+;base64,', '', base64_str)#print('base64_str:', type(base64_str))# base64解码img_data_bytes  = base64.b64decode(base64_str)# 转换为np数组img_array      = np.fromstring(img_data_bytes, np.uint8)# 转换成opencv可用格式img            = cv.imdecode(img_array, cv.COLOR_RGB2BGR)return img# 对于图片截取验证码区域
def recognizeChineseCharBase64(base64_str, checkcodeRect, text, savedFile=None):img          = base642np(base64_str)img          = cv.cvtColor(img, cv.COLOR_BGR2GRAY)ret,  img    = cv.threshold(img, 127, 255, cv.THRESH_BINARY)img          = cv.cvtColor(img, cv.COLOR_GRAY2BGR)img          = img[int(checkcodeRect['y']):int(checkcodeRect['height'] + checkcodeRect['y']), int(checkcodeRect['x']):int(checkcodeRect['width'] + checkcodeRect['x']), :]#print('img.shape', img.shape)if savedFile :cv.imwrite(savedFile, img)return recognizeChineseChar(img ,text)

参考资料

Template Matching

一个蹩脚的图形中文验证码自动识别实现相关推荐

  1. PIL模块与随机生成中文验证码

    今天我们要学习的内容是如何利用Python生成一个随机的中文验证码,并将图片保存为.jpeg格式. 在这之前,你首先得了解Python中的PIL库.PIL是Python Imaging Library ...

  2. iis开启php验证码,php结合GD库实现中文验证码的简单方法

    前言 上一次写了一个常见的验证码,现在玩一下中文的验证码,顺便升级一下写的代码 流程基本差不多 先看GD库开启了没 生成中文5位验证码 开始画图 画干扰素 生成图形 完事 生成中文验证码 //小小心机 ...

  3. web网站验证码自动识别

    验证码自动识别 在很多WEB网站登录的时候,都需要输入验证码,Python提供了一些库(例如常用的OCR库)来识别和使用在线图片中的文字. 将图像翻译成文字一般被称为光学文字识别(Optical Ch ...

  4. javaweb生成中文验证码

    javaweb生成中文验证码 整理一份四字的文字列表的text文档 配置web.xml 创建java代码 书写index.jsp访问页 看到有的网页的验证码是中文的,就想着自己也写一个,百度了下有关知 ...

  5. php验证码百度ocr识别,利用百度OCR实现验证码自动识别

    在爬取网站的时候都遇到过验证码,那么我们有什么方法让程序自动的识别验证码呢?其实网上已有很多打码平台,但是这些都是需要money.但对于仅仅爬取点数据而接入打码平台实属浪费.所以百度免费ocr正好可以 ...

  6. php怎样验证验证码对错,PHP生成中文验证码并检测对错实例

    PHP生成中文验证码并检测对错实例,中文验证码的例子还是比较少的,今天给大家分享一下,支持自定义中文.字体.背景色等 生成验证码,注意font字体路径要对,否则显示图片不存在session_start ...

  7. Winform中实现中文验证码(附代码下载)

    场景 中文验证码效果 注: 博客主页: https://blog.csdn.net/badao_liumang_qizhi 关注公众号 霸道的程序猿 获取编程相关电子书.教程推送与免费下载. 实现 新 ...

  8. 一个好用的PHP验证码类

    一个好用的PHP验证码类 分享一个好用的php验证码类,包括调用示例. 说明: 如果不适用指定的字体,那么就用imagestring()函数,如果需要遇到指定的字体,就要用到imagettftext( ...

  9. Python自动打码,DdddOcr通用验证码自动识别库

    在Python爬虫中,或者使用POST提交的过程中,往往需要提交验证码来验证,除了人工打码,付费的api接口(打码接口),深度学习识别验证码,当然还有适合新人使用的OCR验证码识别库,简单的验证码是可 ...

  10. 验证码机制之验证码自动识别

    介绍 当验证码设计不存在逻辑层面的问题时,就要涉及到与验证码机制本身的正面对抗,也就是验证码识别技术这里的验证码主要是指图片验证码. 验证码自动识别就是指通过自动化的技术对图片验证码中的字符或公式等内 ...

最新文章

  1. 某程序员求助:因考虑不周,签字确认后又拒了虾皮offer,被hr告知进入黑名单,永不录用!以后还能进虾皮吗?...
  2. 一位技术人员成长的烦恼及我的分析(转)
  3. Asp.Net源码(转载)
  4. VS2019错误提示:_CRT_SECURE_NO_WARNINGS的解决方法
  5. (7)Java数据结构--集合map,set,list详解
  6. SQLmap的下载和安装,以及其参数大全和使用教程(值得收藏)
  7. C++中 * *的用法与区别----实操才能看明白
  8. JMS学习(三)ActiveMQ Message Persistence(转)
  9. 2018第17周总结
  10. Notepad++ 安装 Zen Coding / Emmet 插件
  11. iostream头文件简单理解
  12. DPDK Release 20.05
  13. 第五人格显示服务器维护中请稍后登录怎么办,《第五人格》未知异常 请稍后重试登不上去如何解决...
  14. shell基础知识及变量
  15. 最详细的Pycharm使用技巧 2020.06.06
  16. CV项目肢体动作识别(三)内附完整代码和详细讲解
  17. halcon C++编程 第22讲 图像镜像 tcy
  18. 黑马程序员————集合框架1(day14)
  19. 谈谈我对这个互联网时代的理解
  20. linux如何查看内存ddr几代,如何通过命令查看内存是ddr2还是ddr3的?

热门文章

  1. EXCEL——提取身份证中的出生年月日
  2. VUE输入 身份证 号,获取出生年月日
  3. C语言学习日记(yzy):socket(TCP)网络连接
  4. 面试总结 -记周六校招笔试
  5. 树莓派利用OpenCV的图像跟踪、人脸识别等
  6. 计算机专业考研英语二国家线多少分,考研英语二国家线多少,2019年考研英语二国家线?...
  7. 传奇人物____Anders Hejlsberg
  8. Oracle中insert into select和select into的用法(异常0RA-00905:missing keyword的解决)
  9. HTML选择器的学习
  10. 计算机加内存还是固态硬盘,电脑慢加内存还是固态硬盘好