0%

opencv-破解滑动验证码

opencv 破解滑动验证码

最近在学习opencv,实现可以破解滑动验证码

原理

破解滑块验证码最为关键的地方在于找到滑块缺口的位置,找到缺口位置后就可以利用Selenium模拟拖动滑块到指定位置实现破解,之前的老办法就是将完整图的像素点和带缺口图的像素点进行比较从而得到缺口位置,但是现在一般不会将完整图暴露给我们,所以只有在带有缺口的图上进行处理

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




源码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#!/bin/bash python
#encoding:utf-8
import cv2 as cv


def get_pos(image):
blurred = cv.GaussianBlur(image, (5, 5), 0)
canny = cv.Canny(blurred, 200, 400)
binary, 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']
'''
笔者是根据打印日志 来算出自己验证码的周长和大小 方法是先把所有的轮廓画出来 然后根据实际坐标 反推
print("start")
print(x, y, w, h)
print(cx)
print(cv.contourArea(contour))
print(cv.arcLength(contour, True))
print("end")
'''
#对面积和周长进行限制
if (25 < cv.contourArea(contour) < 30 and 400 < cv.arcLength(contour, True) < 450):
if cx < 125:
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('slide.png')
get_pos(img0)
cv.waitKey(0)
cv.destroyAllWindows()

cv2.findContours 有遇到too many values to unpack这个报错
是因为opencv 老版本 返回两个参数 新版本返回3个参数更改返回参数个数

获取到移动的距离,使用selenium 模拟滑动就ok了