python3使⽤OpenCV计算滑块拼图验证码缺⼝位置(场景
⽰例)
前⾔
滑块拼图验证码的失败难度在于每次图⽚上缺⼝位置不⼀样,需识别图⽚上拼图的缺⼝位置,使⽤python的OpenCV库来识别到环境准备
pip 安装 opencv-python
pip installl opencv-python
OpenCV(Open Source Computer Vision Library)是⼀个开源的计算机视觉库,提供了很多处理图⽚、视频的⽅法。OpenCV库提供了⼀个⽅法(matchTemplate()):从⼀张较⼤的图⽚中搜索⼀张较⼩图⽚,计算出这张⼤图上各个区域和⼩图相似度。
调⽤这个⽅法后返回⼀个⼆维数组(numpy库中ndarray对象),从中就能拿到最佳匹配区域的坐标。
这种使⽤场景就是滑块验证码上背景图⽚是⼤图,滑块是⼩图。
准备2张图⽚
场景⽰例
先抠出2张图⽚,分别为background.png 和 target.png
计算缺⼝位置
import cv2
# 作者-上海悠悠 QQ交流:717225969
# blog地址 wwwblogs/yoyoketang/
def show(name):
'''展⽰圈出来的位置'''
cv2.imshow('Show', name)
cv2.waitKey(0)
cv2.destroyAllWindows()
def _tran_canny(image):
"""消除噪声"""
image = cv2.GaussianBlur(image, (3, 3), 0)
return cv2.Canny(image, 50, 150)
def detect_displacement(img_slider_path, image_background_path):
"""detect displacement"""
# # 参数0是灰度模式
image = cv2.imread(img_slider_path, 0)
template = cv2.imread(image_background_path, 0)
# 寻最佳匹配
res = cv2.matchTemplate(_tran_canny(image), _tran_canny(template), cv2.TM_CCOEFF_NORMED)
pycharm安装教程和使用# 最⼩值,最⼤值,并得到最⼩值, 最⼤值的索引
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
top_left = max_loc[0] # 横坐标
# 展⽰圈出来的区域
x, y = max_loc # 获取x,y位置坐标
w, h = image.shape[::-1] # 宽⾼
show(template)
return top_left
if __name__ == '__main__':
top_left = detect_displacement("target.png", "background.png")
print(top_left)
运⾏效果看到⿊⾊圈出来的地⽅就说明到了缺⼝位置
调试完成后去掉 show 的这部分代码
# 展⽰圈出来的区域
# x, y = max_loc # 获取x,y位置坐标
# w, h = image.shape[::-1] # 宽⾼
# angle(template, (x, y), (x + w, y + h), (7, 249, 151), 2)
# show(template)
缺⼝的位置只需得到横坐标,距离左侧的位置top_left为184
ps:python opencv破解滑动验证码之获取缺⼝位置的⽰例代码
破解滑块验证码的思路主要有2种:
⼀张完整的背景图和⼀张有缺⼝的图⽚的场景,解决思路:两张图⽚同⼀个坐标位置进⾏像素上的⼀⼀对⽐,出不⼀样的坐标。
⼀张有缺⼝的图⽚和需要验证的⼩图,解决思路:1.两张图⽚进⾏⼆极化以及归⼀化,确定⼩图在图⽚中间的坐标。这种办法我没有验证通过,可以参考这⾥。2.通过opencv获得缺⼝位置
之后就要使⽤初中物理知识了,使⽤先加速后减速模仿⼈⼿动拖动
通过opencv获得图⽚的缺⼝位置
#coding=utf-8
import cv2
import numpy as np
from PIL import Image
def get_element_slide_distance():
otemp = 'captcha2.png'
oblk = 'captcha1.png'
target = cv2.imread(otemp, 0) # 读取进⾏⾊度图⽚,转换为numpy中的数组类型数据
template = cv2.imread(oblk, 0)
width, height = target.shape[::-1] # 获取缺⼝图数组的形状 -->缺⼝图的宽和⾼
temp = 'temp.jpg' # 将处理之后的图⽚另存
targ = 'targ.jpg'
cv2.imwrite(temp, template)
cv2.imwrite(targ, target)
target = cv2.imread(targ) # 读取另存的滑块图
target = cv2.cvtColor(target, cv2.COLOR_BGR2GRAY) # 进⾏⾊彩转换
# 去除⽩⾊部分获取滑块正常⼤⼩
target = target[target.any(1)]
target = abs(255 - target) # 获取⾊差的绝对值
cv2.imwrite(targ, target) # 保存图⽚
target = cv2.imread(targ) # 读取滑块
template = cv2.imread(temp) # 读取背景图
result = cv2.matchTemplate(target, template, cv2.TM_CCOEFF_NORMED) # ⽐较两张图的重叠区域
top, left = np.unravel_index(result.argmax(), result.shape) # 获取图⽚的缺⼝位置
#缺⼝位置
print((left, top, left + width, top + height)) # 背景图中的图⽚缺⼝坐标位置
#调⽤PIL Image 做测试
image = Image.open("captcha1.png")
rectangle = (left + 3, top + 3, left + width - 3, top + height - 3) #去掉⽩⾊块的影响(上⾯去掉⽩⾊部分的功能并没有真的起作⽤) #切割
imagecrop = p(rectangle)
#保存切割的缺⼝
imagecrop.save("new_image.jpg")
return left+3
distance = get_element_slide_distance()
# 滑动距离误差校正,滑动距离*图⽚在⽹页上显⽰的缩放⽐-滑块相对的初始位置
distance = distance*(280/680) - 22
拖动轨迹
def generate_tracks1(XCoordinates):
element = browser.find_element_by_xpath("//div[@class='secsdk-captcha-drag-icon sc-jKJlTe fsBatO']")
ActionChains(browser).click_and_hold(on_element = element).perform()
#
# ActionChains(browser).move_by_offset(xoffset=0, yoffset=y - 445).perform()
#
# time.sleep(0.15)
# print("第⼆步,拖动元素")
distance = XCoordinates - 60
# 初速度
v = 0
# 单位时间为0.2s来统计轨迹,轨迹即0.2内的位移,越低看起来越丝滑!!
t = 0.08
# 位移/轨迹列表,列表内的⼀个元素代表0.2s的位移
tracks = []
# 当前的位移
current = 0
# 到达mid值开始减速
mid = distance * 5 / 8
distance += 10 # 先滑过⼀点,最后再反着滑动回来
# a = random.randint(1,3)
while current < distance:
if current < mid:
# 加速度越⼩,单位时间的位移越⼩,模拟的轨迹就越多越详细
a = random.randint(100, 200) # 加速运动
else:
a = -random.randint(2, 10) # 减速运动
# 初速度
v0 = v
# 0.2秒时间内的位移
s = v0 * t + 0.5 * a * (t ** 2)
# 当前的位置
current += s
# 添加到轨迹列表
tracks.append(round(s))
# 速度已经达到v,该速度作为下次的初速度
v = v0 + a * t
if current > distance:
break
# 反着滑动到⼤概准确位置
# for i in range(4):
# tracks.append(-random.randint(1, 3))
# for i in range(4):
# tracks.append(-random.randint(1,3))
random.shuffle(tracks)
count = 0
for item in tracks:
print(item)
count += item
ActionChains(browser).move_by_offset(xoffset = item, yoffset = random.randint(-2, 2)).perform()
# ActionChains(browser).move_to_element_with_offset(to_element=element, xoffset=XCoordinates-18,yoffset=y - 445).perform()
# time.sleep(2)
# # 释放⿏标
print(count)
ActionChains(browser).release(on_element = element).perform()
到此这篇关于python3 使⽤OpenCV计算滑块拼图验证码缺⼝位置的⽂章就介绍到这了,更多相关python滑块拼图验证码内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论