OpenCV搞定腾讯滑块验证码的实现代码


Posted in Python onMay 18, 2019

前言

废话

滑块验证码破解是一直都想搞的项目,毕竟多数网站都会采用滑块验证码,于是最近在修改论文的闲暇之余把这事儿给解决了。要搞现在的滑块验证码绕不开图像处理,图像处理当然是首推OpenCV-Python啦!当然我的OpenCV非常菜(P.S.两天速成不敢保证代码质量),发现问题就直接指出嘛,不用走流程啦!

环境

首先需要一个python,然后安装opencv的python库,如下:

pip install opencv-python

然后测试一下是否可用,如下:

import cv2 as cv
import numpy as np

if __name__ == '__main__':
 img = np.ones((200, 200, 3), np.uint8) * 255
 cv.rectangle(img, (50, 50), (150, 150), (0, 0, 255), 2)
 cv.imshow('test', img)
 cv.waitKey(0)
 cv.destroyAllWindows()

正常的话就会如下显示:

OpenCV搞定腾讯滑块验证码的实现代码

OpenCV的使用

相关的API我也是边用边查的,用得也是相当生疏!具体的常用方法大家只好自行百度了,我就不献丑了!

实现原理及方法

腾讯滑块验证

这次搞得目标就是腾讯滑块验证码,调用腾讯滑块这个接口的网站还是挺多的,比如非常好用的在线画图网站ProcessOn,其中滑块验证部分类似这样子的:

OpenCV搞定腾讯滑块验证码的实现代码

抓个包发现只有滑块图和带缺口的图,如下:

OpenCV搞定腾讯滑块验证码的实现代码

破解滑块验证码最为关键的地方在于找到滑块缺口的位置,找到缺口位置后就可以利用Selenium模拟拖动滑块到指定位置实现破解,之前的老办法就是将完整图的像素点和带缺口图的像素点进行比较从而得到缺口位置,但是现在一般不会将完整图暴露给我们,所以只有在带有缺口的图上进行处理。我这里一共有两种方案进行缺口位置识别,一种是基于模板匹配的,另一种是基于轮廓检测的,下面会细讲两种方案的实现方法。

模板匹配识别缺口

具体是实现过程如下:

1.处理滑块的图片

  • 灰度化滑块图片
  • 处理一下滑块图中滑块的外圈
  • 使用inRange二值化滑块图
  • 使用开运算去除白色噪点

运行结果如下所示(左侧为原始滑块,右侧为处理后的滑块):

OpenCV搞定腾讯滑块验证码的实现代码

2.处理带缺口的图片

  • 先来个高斯滤波去噪
  • 灰度化带缺口图
  • 使用阈值二值化该图

运行结果如下所示(左侧为原始图,右侧为处理后的图):

OpenCV搞定腾讯滑块验证码的实现代码

3.进行模板匹配

调用模板匹配API并圈出匹配上的区域,结果如下所示:

OpenCV搞定腾讯滑块验证码的实现代码

警告警告警告

这种方法的缺口识别率在50%左右,很大一部分原因是滑块图的背景为纯白色,这在匹配时会产生很大的干扰,要是能将滑块图的背景变为透明,正确的匹配率可以达到90%以上

如果大家有任何将滑块图的背景变为透明的办法,可以留言到评论区,我真的万分感谢!!!下面是现阶段的实现代码:

# encoding:utf-8
import cv2 as cv
import numpy as np


# 对滑块进行二值化处理
def handle_img1(image):
  kernel = np.ones((8, 8), np.uint8) # 去滑块的前景噪声内核
  gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
  width, heigth = gray.shape
  for h in range(heigth):
    for w in range(width):
      if gray[w, h] == 0:
        gray[w, h] = 96
  # cv.imshow('gray', gray)
  binary = cv.inRange(gray, 96, 96)
  res = cv.morphologyEx(binary, cv.MORPH_OPEN, kernel) # 开运算去除白色噪点
  # cv.imshow('res', res)
  return res


# 模板匹配(用于寻找缺口有点误差)
def template_match(img_target, img_template):
  tpl = handle_img1(img_template) # 误差来源就在于滑块的背景图为白色
  blurred = cv.GaussianBlur(img_target, (3, 3), 0) # 目标图高斯滤波
  gray = cv.cvtColor(blurred, cv.COLOR_BGR2GRAY)
  ret, target = cv.threshold(gray, 127, 255, cv.THRESH_BINARY) # 目标图二值化
  # cv.imshow("template", tpl)
  # cv.imshow("target", target)
  method = cv.TM_CCOEFF_NORMED
  width, height = tpl.shape[:2]
  result = cv.matchTemplate(target, tpl, method)
  min_val, max_val, min_loc, max_loc = cv.minMaxLoc(result)
  left_up = max_loc
  right_down = (left_up[0] + height, left_up[1] + width)
  cv.rectangle(img_target, left_up, right_down, (0, 0, 255), 2)
  cv.imshow('res', img_target)


if __name__ == '__main__':
  img0 = cv.imread('./demo/3/hycdn_3.jpg')
  img1 = cv.imread('./demo/3/hycdn_3_2.png')
  template_match(img0, img1)
  cv.waitKey(0)
  cv.destroyAllWindows()

轮廓检测识别缺口

基于轮廓检测缺口的思路简单很多,加上合理的条件识别率在95%以上,实现过程如下:

带缺口图高斯模糊去噪用(200,400)的阈值做Canny边缘检测寻找轮廓对已有的轮廓做约束,比如轮廓的面积范围,轮廓的周长范围

多个匹配结果如下:

OpenCV搞定腾讯滑块验证码的实现代码

OpenCV搞定腾讯滑块验证码的实现代码

OpenCV搞定腾讯滑块验证码的实现代码

OpenCV搞定腾讯滑块验证码的实现代码

实现代码如下:

# encoding:utf-8
import cv2 as cv


def get_pos(image):
  blurred = cv.GaussianBlur(image, (5, 5), 0)
  canny = cv.Canny(blurred, 200, 400)
  contours, hierarchy = cv.findContours(canny, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
  for i, contour in enumerate(contours):
    M = cv.moments(contour)
    if M['m00'] == 0:
      cx = cy = 0
    else:
      cx, cy = M['m10'] / M['m00'], M['m01'] / M['m00']
    if 6000 < cv.contourArea(contour) < 8000 and 370 < cv.arcLength(contour, True) < 390:
      if cx < 400:
        continue
      x, y, w, h = cv.boundingRect(contour) # 外接矩形
      cv.rectangle(image, (x, y), (x + w, y + h), (0, 0, 255), 2)
      cv.imshow('image', image)
      return x
  return 0


if __name__ == '__main__':
  img0 = cv.imread('./demo/4/hycdn_4.jpg')
  get_pos(img0)
  cv.waitKey(0)
  cv.destroyAllWindows()

遗留问题

问题1

如何将滑块图的纯白背景变为透明背景?

问题2

使用Selenium和轨迹算法拖动滑块时将滑块拖出左侧的范围之外,轨迹算法是先加速后减速整体是向前移动的,按道理来说不可能往回走,但是模拟拖动的时候会出现滑块向后拖动且拖出范围的现象,这问题如何解决?

OpenCV搞定腾讯滑块验证码的实现代码

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python抓取最新博客内容并生成Rss
May 17 Python
分享一下Python 开发者节省时间的10个方法
Oct 02 Python
Python使用PyCrypto实现AES加密功能示例
May 22 Python
基于Python函数的作用域规则和闭包(详解)
Nov 29 Python
Python读写及备份oracle数据库操作示例
May 17 Python
Python3实现爬虫爬取赶集网列表功能【基于request和BeautifulSoup模块】
Dec 05 Python
基于Django框架的权限组件rbac实例讲解
Aug 31 Python
Django+python服务器部署与环境部署教程详解
Mar 30 Python
Eclipse配置python默认头过程图解
Apr 26 Python
python如何支持并发方法详解
Jul 25 Python
python+opencv3.4.0 实现HOG+SVM行人检测的示例代码
Jan 28 Python
分享提高 Python 代码的可读性的技巧
Mar 03 Python
Python3匿名函数lambda介绍与使用示例
May 18 #Python
python中数组和矩阵乘法及使用总结(推荐)
May 18 #Python
Python实现二叉树前序、中序、后序及层次遍历示例代码
May 18 #Python
python的内存管理和垃圾回收机制详解
May 18 #Python
Django处理多用户类型的方法介绍
May 18 #Python
Django 配置多站点多域名的实现步骤
May 17 #Python
将Python字符串生成PDF的实例代码详解
May 17 #Python
You might like
php字符串截取问题
2006/11/28 PHP
ZF等常用php框架中存在的问题
2008/01/10 PHP
php下检测字符串是否是utf8编码的代码
2008/06/28 PHP
php模拟js函数unescape的函数代码
2012/10/20 PHP
PHP简单获取视频预览图的方法
2015/03/12 PHP
简单谈谈php中的unicode和utf8编码
2015/06/10 PHP
PHP/ThinkPHP实现批量打包下载文件的方法示例
2017/07/31 PHP
jQuery html()等方法介绍
2009/11/18 Javascript
基于jquery实现的文字淡入淡出效果
2013/11/14 Javascript
JavaScript实现网页截图功能
2014/10/16 Javascript
javascript中的Function.prototye.bind
2015/06/25 Javascript
js简单实现标签云效果实例
2015/08/06 Javascript
jquery实现通用的内容渐显Tab选项卡效果
2015/09/07 Javascript
Jquery-1.9.1源码分析系列(十一)之DOM操作
2015/11/25 Javascript
Javascript技术栈中的四种依赖注入小结
2016/02/27 Javascript
jQuery利用sort对DOM元素进行排序操作
2016/11/07 Javascript
JS实现简单的天数计算器完整实例
2017/04/28 Javascript
angular.extend方法的具体使用
2017/09/14 Javascript
不使用 JS 匿名函数理由
2017/11/17 Javascript
详解Vue+axios+Node+express实现文件上传(用户头像上传)
2018/08/10 Javascript
vue遍历对象中的数组取值示例
2019/11/07 Javascript
Jquery如何使用animation动画效果改变背景色的代码
2020/07/20 jQuery
nodejs中的异步编程知识点详解
2021/01/17 NodeJs
[39:07]LGD vs VP 2018国际邀请赛淘汰赛BO3 第二场 8.21
2018/08/22 DOTA
简要讲解Python编程中线程的创建与锁的使用
2016/02/28 Python
pandas DataFrame实现几列数据合并成为新的一列方法
2018/06/08 Python
解决python -m pip install --upgrade pip 升级不成功问题
2020/03/05 Python
使用python批量转换文件编码为UTF-8的实现
2020/04/03 Python
python 弧度与角度互转实例
2020/04/15 Python
3个CCIE对一个工程师的面试题
2012/05/06 面试题
介绍一下Ruby的特点
2013/01/20 面试题
财务人员担保书
2014/05/13 职场文书
焦裕禄精神心得体会
2014/09/02 职场文书
中学生自我评价2015
2015/03/03 职场文书
公司搬迁通知
2015/04/20 职场文书
Spring Data JPA框架的核心概念和Repository接口
2022/04/28 Java/Android