训练AI识别缺口距离

需求描述

在网站登录的时候,出现拖动验证码,如我在Selenium进行登录的时候。要求截图后识别滑块和缺口之间的位置距离。你需要写个py的代码,然后训练一些数据,然后生成个模型。【测试网址:https://cas-q.juyoufuli.com/#/login
缺口图片如:

img

验收标准

1.提供你的py代码,写好注释,你可以少量的去训练数据,然后我拿到代码后,告知我怎么训练,我找人在标注一些数据
2.随机找验证图片,识别率在90%

参与要求

在悬赏页面提交申请,并注明您需要的时间,或相关项目!

参考:

import time
import cv2
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains

def get_slider_image(driver):
    # 获取整个页面截图
    driver.save_screenshot('screenshot.png')
    
    # 定位滑块元素并获取其位置和大小
    slider = driver.find_element_by_xpath('//div[@class="slider"]')
    location = slider.location
    size = slider.size
    
    # 根据滑块元素的位置和大小,裁剪出滑块图片
    image = cv2.imread('screenshot.png')
    x = location['x']
    y = location['y']
    width = size['width']
    height = size['height']
    
    slider_image = image[y:y+height, x:x+width]
    
    return slider_image

def get_gap_position(slider_image):
    # 在这里编写代码来训练模型并预测滑块与缺口之间的距离
    
    # 这里只是一个示例,直接返回一个固定值作为距离(需要根据实际情况修改)
    gap_position = 100
    
    return gap_position

def move_slider(driver, gap_position):
    # 获取滑块元素并计算需要移动的距离
    slider = driver.find_element_by_xpath('//div[@class="slider"]')
    
    distance_to_move = gap_position - 10  # 这里需要根据实际情况微调
    
    # 使用ActionChains类来模拟拖动操作
    action_chains = ActionChains(driver)
    
    # 按住滑块不放,并向右拖动指定距离,然后释放鼠标按钮完成拖动操作。
    # 这里需要根据实际情况微调移动速度和释放鼠标按钮的时间。
    # 可以尝试多次调整以达到最佳效果。
    
    # 示例中使用了一种简单的方式来模拟拖动操作,请根据实际情况进行修改。
    
    # 具体实现可能因为不同网站而有所差异,请根据具体网站的HTML结构和交互方式进行相应调整。
    
    action_chains.click_and_hold(slider).perform()
    action_chains.move_by_offset(distance_to_move, 0).perform()
    time.sleep(0.5)  # 等待一段时间以便验证通过(需要根据实际情况微调)
    action_chains.release().perform()

# 创建WebDriver对象并打开网页
driver_path = 'path/to/chromedriver'  # 替换为您下载的Chrome驱动程序路径
driver = webdriver.Chrome(executable_path=driver_path)
driver.get('https://example.com')  # 替换为目标网站URL

time.sleep(2)  # 等待页面加载完成(需要根据实际情况微调)

# 获取滑块图片并识别缺口位置距离
slider_image = get_slider_image(driver)
gap_position = get_gap_position(slider_image)

# 移动滑块完成验证过程
move_slider(driver, gap_position)

time.sleep(5)  # 等待验证结果显示(需要根据实际情况微调)

# 关闭浏览器窗口并退出WebDriver对象
driver.quit()

基于bing、GPT部分内容和本人思考总结:
这是一个比较复杂的任务,需要设计一个完整的流程才能实现。下面是一个大致的流程:
1、数据收集:需要从网站上收集拖动验证码的图片和对应的缺口距离数据。可以使用 Selenium 自动化测试工具进行模拟操作,收集大量的数据。
2、数据预处理:对收集到的数据进行预处理,包括图片的裁剪、缩放、灰度化等操作,以及对缺口距离进行标签化处理。
3、特征提取:将处理好的图片数据转换为可以输入模型的特征向量。可以使用深度学习中的卷积神经网络(CNN)进行特征提取,也可以使用传统的特征提取算法,例如 SIFT、HOG 等。
4、模型训练:将处理好的特征向量和标签数据输入到模型中进行训练。可以使用深度学习中的分类器,例如神经网络、支持向量机(SVM)等。
5、模型评估:使用测试数据对训练好的模型进行评估,计算准确率、召回率等指标,选择最佳的模型。
6、模型应用:将训练好的模型应用到实际的场景中进行测试,例如使用 Selenium 自动化测试工具进行拖动验证码的测试。
以下是一个简单的 Python 代码示例,用于读取数据、预处理图片和标签化处理:

import os
import cv2
import numpy as np

# 读取数据
def load_data(data_path):
    data = []
    labels = []
    for file_name in os.listdir(data_path):
        if file_name.endswith('.jpg'):
            img = cv2.imread(os.path.join(data_path, file_name), cv2.IMREAD_GRAYSCALE)
            label = int(file_name.split('_')[1])
            data.append(img)
            labels.append(label)
    return np.array(data), np.array(labels)

# 图像预处理
def preprocess(img):
    # 裁剪图片
    img = img[10:58, 10:310]
    # 缩放图片
    img = cv2.resize(img, (200, 40))
    # 二值化处理
    _, img = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
    return img

# 标签化处理
def labelize(labels, num_classes):
    return np.eye(num_classes)[labels]

# 加载数据
data, labels = load_data('captcha_data')
# 图像预处理
data = np.array([preprocess(img) for img in data])
# 标签化处理
labels = labelize(labels, num_classes=10)

当然,这只是一个简单的示例,实际实现中还需要考虑很多细节问题,例如数据增强、模型优化等。

您好,感谢您的项目机会。针对您提出的验证码滑块识别需求,我可以提供以下方案:

  1. 使用Python和OpenCV来获取验证码图片,并提取滑块和缺口图片区域。
  2. 对滑块和缺口图片进行预处理,包括灰度化、去噪等,以提高特征提取的效果。
  3. 利用模板匹配等算法提取滑块和缺口的特征,计算二者之间的距离。
  4. 构建一个小型卷积神经网络模型,使用滑块和缺口图片作为输入,训练输出它们之间的距离。
  5. 收集一些验证码样本进行训练和测试,调整模型达到较好的识别效果。
  6. 将模型封装成函数,可针对新验证码进行识别预测。
  7. 提供详细注释的代码,以及如何使用的说明文档。

一般来说计算offset有两个方法:1. 通过背景图和带有缺口图之间比对像素来确定,但是这种由于背景底色的原因我们不能保证offset计算很准确。但是通过手动调整,我这里登陆浦发银行时准确率可以在75%以上。 2. 通过下载图片然后去训练,由于这方面我不擅长,故而这里只介绍一下第一种方法。

我们需要用到的库有:BytesIO、Image。

import time
import random
 
from io import BytesIO
from PIL import Image
from selenium.webdriver.common.action_chains import ActionChains
 
from fund_transactions.sliding_track import drag_and_drop
 
 
class SliderVerification(object):
    def __init__(self, driver):
        self.driver = driver
 
    def get_screenshot(self):
        """
            获取屏幕截图
        """
        screenshot = self.driver.get_screenshot_as_png()
        screenshot = Image.open(BytesIO(screenshot))
 
        return screenshot
 
    def update_style(self):
        """
            修改图片的style属性,显示无缺口的图片
        """
        # js = 'document.querySelectorAll("canvas")[3].style="display:block"'
        # 这里使用js去缺口,获得背景图
        js = 'document.getElementsByClassName("geetest_canvas_fullbg geetest_fade geetest_absolute")[0].setAttribute("style","display:block")'
        self.driver.execute_script(js)
        time.sleep(2)
 
    def get_position(self):
        """
            获取截取验证码时的四条边
        """
        # 获取验证码图片对象
        code_img = self.driver.find_element_by_xpath("//canvas[@class='geetest_canvas_slice geetest_absolute']")
        time.sleep(2)
 
        location = code_img.location
        size = code_img.size
 
        # 计算图片截取区域(左,上,右,下,的坐标值)
        left, top, right, buttom = location['x'], location['y'], location['x'] + size['width'], \
                                   location['y'] + size['height']
        return left, top, right, buttom
 
    def get_image(self):
        """
            截取验证码图片
        """
        # 获取验证码位置
        position = self.get_position()
        print("postion_1:", position)
        # 从屏幕截图中抠出有缺口的验证码图片
        captcha1 = self.get_screenshot().crop(position)
        # 修改style属性,显示无缺口的验证码图片
        self.update_style()
        print("position_2:", position)
        # 从屏幕截图中抠出无缺口的验证码图片
        captcha2 = self.get_screenshot().crop(position)
 
        with open('captcha1.png', 'wb') as f1, open('captcha2.png', 'wb') as f2:
            captcha1.save(f1)
            captcha2.save(f2)
 
        # 这里将调整为原来带有缺口的图片显示出来
        js = 'document.getElementsByClassName("geetest_canvas_fullbg geetest_fade geetest_absolute")[0].setAttribute("style","display:none")'
        self.driver.execute_script(js)
        time.sleep(2)
 
        return captcha1, captcha2
 
    @staticmethod
    def is_pixel_equal(img1, img2, x, y):
        """
        判断两张图片的同一像素点的RGB值是否相等
        """
        pixel1, pixel2 = img1.load()[x, y], img2.load()[x, y]
        # print(pixel1,pixel2)
        # 设定一个比较基准
        sub_index = 60
 
        # 比较
        if abs(pixel1[0] - pixel2[0]) < sub_index and abs(pixel1[1] - pixel2[1]) < sub_index and abs(
                pixel1[2] - pixel2[2]) < sub_index:
            return True
        else:
            return False
 
    def get_gap_offset(self, img1, img2):
        """
            获取缺口的偏移量
        """
        x = int(img1.size[0] / 4.2)
        for i in range(x, img1.size[0]):
            for j in range(img1.size[1]):
                # 两张图片对比,(i,j)像素点的RGB差距,过大则该x为偏移值
                if not self.is_pixel_equal(img1, img2, i, j):
                    x = i
                    return x
        return x

然后调用get_gap_offset方法就可以获得偏移量,而参数img1/img2使用get_img方法可以获取。

拿到了偏移量,下面就需要获取滑动的轨迹。

import numpy as np
from selenium.webdriver.common.action_chains import ActionChains
 
 
def ease_out_quad(x):
    return 1 - (1 - x) * (1 - x)
 
 
def ease_out_quart(x):
    return 1 - pow(1 - x, 4)
 
 
def ease_out_expo(x):
    if x == 1:
        return 1
    else:
        return 1 - pow(2, -10 * x)
 
 
def get_tracks(distance, seconds):
    """
    :param distance: offset
    :param seconds: 拉动时间
    :return: 
    """
    tracks = [0]
    offsets = [0]
    # print("np_value:", np.arange(0.0, seconds, 0.1))
    for t in np.arange(0.0, seconds, 0.1):
        offset = round(ease_out_quart(t / seconds) * distance)
        tracks.append(offset - offsets[-1])
        offsets.append(offset)
    return offsets, tracks
 
 
def drag_and_drop(browser, offset, knob):
    """
    拖拽
    :param browser: 浏览器对象
    :param offset: 滑块到缺口的距离
    :param knob: 滑块的位置
    """
    offsets, tracks = get_tracks(offset, 12)
    # print("offsets:", offsets)
    # print("tracks:", tracks)
    ActionChains(browser).click_and_hold(knob).perform()
    for x in tracks:
        ActionChains(browser).move_by_offset(x, 0).perform()
    ActionChains(browser).pause(0.5).release().perform()

然后万事具备,就开始拉动滑块吧。下面这段代码应该放在第一段代码下面,第二段代码再第一段中有引入,所以这里直接调用。

    def do_captcha(self):
        """
            实现处理验证码
        """
        # 有缺口,无缺口图片
        time.sleep(3)
        img1, img2 = self.get_image()
        # 比较两个验证码图片获取验证码滑块的偏移量
        offset = self.get_gap_offset(img1, img2)
        offset = offset - 10
        print("offset:", offset)
 
        # todo 这使用加速度拖动,被极限识别,无法通过验证
        # 使用偏移值计算移动操作
        # track = self.get_track(offset)
        # 操作滑块按钮,模拟拖动滑块做验证登录
        # self.operate_slider(track)
 
        # todo 使用jquery自定义的移动轨迹拖动,通过验证
        slider_bt = self.driver.find_element_by_xpath("//div[@class='geetest_slider_button']")
        drag_and_drop(self.driver, offset + 40, slider_bt)
        time.sleep(8)

当然还有输入密码过程中会检测鼠标的按下和弹起,但是用了好多模拟方法都行不通,这里强烈建议使用DD模拟鼠键的电信号来解决的,有需要用到可以参考我的上一篇文章,有DD详细的使用步骤。附链接如下:

https://blog.csdn.net/weixin_39823751/article/details/114690638

参考资料:https://www.jianshu.com/p/84e1fdbe7e23?utm_campaign=haruki

http://www.51testing.com/html/41/n-3725241-2.html

https://blog.csdn.net/weixin_43977603/article/details/105768270

给你一个参考的算距离的函数代码

# 定义一个函数,用来找到滑块和缺口之间的位置距离
def get_distance(slider_url, gap_url):
    # 获取滑块图片和缺口图片
    slider = get_image(slider_url)
    gap = get_image(gap_url)

    # 获取滑块图片的宽度和高度
    slider_width, slider_height = slider.shape[::-1]

    # 初始化最大的相似度和最佳的位置距离
    max_similarity = -1
    best_distance = 0

    # 遍历缺口图片的每个像素点,从左到右,从上到下
    for x in range(gap.shape[1]):
        for y in range(gap.shape[0]):
            # 如果滑块图片超出了缺口图片的边界,就跳过这个像素点
            if x + slider_width > gap.shape[1] or y + slider_height > gap.shape[0]:
                continue

            # 截取缺口图片中与滑块图片大小相同的区域
            region = gap[y:y + slider_height, x:x + slider_width]

            # 计算滑块图片和截取区域之间的相似度
            similarity = get_similarity(slider, region)

            # 如果相似度大于最大相似度,就更新最大相似度和最佳位置距离
            if similarity > max_similarity:
                max_similarity = similarity
                best_distance = x

    # 返回最佳位置距离
    return best_distance

AI中测出两个物件之间准确的距离
可以参考下
https://zhidao.baidu.com/question/198900034558040765.html

AI: 机器学习的模型是如何训练的?(在试错中学习)_ai训练模型原理_HowieXue的博客-CSDN博客 一句话理解机器学习一般训练过程 :通过有标签样本来调整(学习)并确定所有权重Weights和偏差Bias的理想值。训练的目标:最小化损失函数(损失函数下面马上会介绍)机器学习算法在训练过程中,做的就是:检查多个样本并尝试找出可最大限度地减少损失的模型;目标就是将损失(Loss)最小化在这里插入图片描述上图就是一般模型训练的一般过程(试错过程),其中模型: 将一个或多个特征作为输入,然后返回一个预测 (y’) 作为输出。为了进行简化,不妨考虑一种采用一个特征并返回一个预测的模型,如下公式_ai训练模型原理 https://blog.csdn.net/HowieXue/article/details/104270306

滑块验证,我记得之前是有人做过的,有个叫极验滑动验证码的,你可以找找资料。不需要模型训练,只需要比较图片的像素点,从而计算缺口的问题。具体可以参考:
极验滑动验证码的识别:https://www.kancloud.cn/tokimeki/python3-spider-notebook/775530

可以通过比较像素点,来计算缺口

对比像素点的RGB值可以实现,缺口处的像素点明显不同

数据收集:你需要收集一组带有滑块和缺口的图片。你可以使用Selenium或其他Web自动化工具来模拟登录并进行截图。确保收集到的图片涵盖不同的场景和角度。
数据标注:对于每张收集到的图片,你需要标注缺口的位置(通常是滑块左侧的位置)。你可以使用标注工具(如LabelImg)来标注这些位置,并将标注结果保存为标注文件。
数据预处理:为了提高模型的训练效果,你可能需要对收集到的图片进行预处理,如裁剪、缩放、灰度化等。这些操作可以使用OpenCV等图像处理库完成。
模型训练:使用标注的数据集来训练模型。在这个问题中,你可以选择使用卷积神经网络(CNN)来进行训练。你可以使用深度学习框架,如TensorFlow或PyTorch,从头开始构建模型,并使用标注的数据集进行训练。
模型评估和调优:训练完成后,你需要使用测试集来评估模型的性能。如果模型的表现不理想,你可以尝试调整模型的参数、增加训练数据量或进行其他优化措施。
模型应用:使用训练好的模型来预测新的图片中滑块和缺口之间的距离。你可以将模型集成到你的Selenium代码中,通过识别距离来自动完成滑动验证码的验证过程。