Skip to content
 
 

Repository files navigation

⚠️ Please read our Legal Disclaimer before using!⚠️

⚠️ 使用前请阅读并了解法律免责声明: Legal Disclaimer⚠️

本项目仅限于学习神经网络相关技术使用。

Mouse Control

一种基于神经网络来模拟人手移动鼠标的方法

AI辅助开发

本项目在开发过程中使用了AI大语言模型辅助进行代码架构设计、函数实现建议及文档编写。所有AI生成内容均已由作者进行人工审核、验证和适配。AI生成的计划文档可在 ./documents/ 文件夹中找到。

简介

本项目源于轨迹检测需求,通过学习真实用户的鼠标移动轨迹,使用神经网络拟合人类移动模式。经过多次迭代优化,项目已具备完整的数据收集、预处理、训练、评估和推理能力。

核心特性:

  • 后台静默收集:运行程序在后台自动记录日常鼠标移动数据
  • 多任务学习:同时预测轨迹点、速度、加速度、曲率
  • 方向变化检测:轨迹分割时检测相邻向量夹角(大于60度强制分割),避免锐角拐弯
  • 自适应采样:在方向变化大(曲率大)的区域分配更多采样点
  • 参数配置化:通过 config.yaml 集中管理所有超参数,支持自定义关键点数量
  • 关键点数量可调:支持通过配置文件设置预测的轨迹点数量(默认40个),并配置上下限
  • 扩展输入特征:输入从 (dx, dy) 扩展为 (dx, dy, distance, direction, avg_curvature)
  • 完善评估指标:支持MSE、终点误差、Fréchet距离等多维度评估
  • 训练可视化:集成TensorBoard监控训练过程
  • GPU加速:支持CUDA训练加速
  • ONNX导出:训练完成后导出ONNX模型,支持跨平台推理
  • 高精度鼠标控制:使用Windows SendInput API实现高精度鼠标移动
  • 多种插值模式:支持B样条、Catmull-Rom样条、贝塞尔曲线三种插值方法
  • 最小加加速度模型:使用 10t³ - 15t⁴ + 6t⁵ 生成平滑的S形速度曲线
  • 生理震颤模拟:叠加±1.5像素的高斯噪声模拟手部微小颤动
  • 实时监控:输出最大速度、最大加速度、最大负加速度、最大曲率、速度均值、加速度均值、曲率均值、曲率方差、速度方差、加速度方差
  • 速度曲线绘制:绘制速度随时间变化曲线图
  • 轨迹可视化:测试完成后自动生成轨迹对比图,展示实际移动与预测轨迹

项目结构

mouse_control/
├── background_collector.py   # 后台数据收集程序
├── preprocess_data.py        # 数据预处理与特征工程
├── train.py                  # 多任务训练脚本(支持GPU)
├── show.py                   # 可视化工具
├── test.py                   # 轨迹平滑测试程序(支持三种插值模式)
├── test_windows.py           # 鼠标模拟测试(Windows API高精度移动)
├── test_mac.py               # 鼠标模拟测试(macOS Core Graphics API)
├── config.yaml               # 集中配置文件
├── requirements.txt          # 项目依赖
├── utils/
│   └── evaluation.py         # 评估指标计算模块
├── models/                   # 存放训练好的ONNX模型
│   ├── train/                # 训练指标与图表
│   └── test/                 # 测试指标与图表(含轨迹可视化图)
├── runs/                     # TensorBoard日志目录
└── data/                     # 存放数据
    ├── raw/                  # 原始后台数据
    └── processed/            # 处理后的训练/测试集

安装依赖

pip install -r requirements.txt

配置说明

所有参数通过 config.yaml 集中管理:

# 数据配置
data:
  raw_dir: "data/raw"              # 原始数据目录
  processed_dir: "data/processed"  # 处理后数据目录
  normalization_params_path: "data/processed/normalization_params.json"  # 归一化参数路径
  train_data_path: "data/processed/train_data.csv"  # 训练数据路径
  test_data_path: "data/processed/test_data.csv"    # 测试数据路径
  num_key_points: 40               # 轨迹采样点数(模型预测的关键点数量)
  min_key_points: 5                # 关键点数量下限
  max_key_points: 100              # 关键点数量上限
  train_test_split: 0.8            # 训练/测试集划分比例
  max_time_gap: 0.01              # 轨迹分割时间间隔(秒)
  max_direction_change: 1.047     # 轨迹分割方向变化阈值(弧度,60度)
  min_points_per_trajectory: 2     # 轨迹最小点数(自动调整为不小于num_key_points)

# 模型配置
model:
  type: "lstm"                    # 模型类型:"lstm" 或 "mlp"
  input_dim: 5                    # 输入维度:dx, dy, distance, direction, avg_curvature
  hidden_sizes: [128, 256, 128]   # MLP隐藏层大小
  dropout_rate: 0.25              # Dropout率
  loss_weights:                   # 多任务损失权重
    points: 0.45
    speeds: 0.20
    accelerations: 0.20
    curvatures: 0.15
  lstm_hidden_dim: 128            # LSTM隐藏层维度(仅lstm模式)
  lstm_num_layers: 2              # LSTM层数(仅lstm模式)

# 训练配置
training:
  epochs: 2000
  batch_size: 16
  learning_rate: 0.0005
  step_size: 100
  gamma: 0.85
  early_stopping_patience: 100    # 早停耐心值
  early_stopping_delta: 0.0001    # 早停改善阈值

# 输出配置
output:
  model_dir: "models"
  model_name: "mouse.onnx"
  log_dir: "runs"

使用流程

1. 收集鼠标轨迹(后台静默模式)

运行后台收集程序,自动记录日常使用中的鼠标移动:

python background_collector.py
  • 程序会在后台静默运行,记录时间戳、X坐标、Y坐标
  • 设置最小移动距离阈值(2像素)过滤抖动
  • 按天分割文件,文件保存在 data/raw/ 目录
  • 按 Ctrl+C 停止收集

2. 数据预处理

将原始数据处理为模型可用的训练样本:

python preprocess_data.py
  • 根据时间间隔(0.01秒)自动分割独立轨迹段
  • 方向变化检测:相邻向量夹角大于60度时强制分割轨迹,避免锐角拐弯
  • 自适应采样:在方向变化大的区域分配更多采样点
  • 计算速度加速度曲率特征
  • 扩展输入特征:dx, dy, distance, direction, avg_curvature
  • 使用Z-score归一化处理(分别计算dx、dy、x、y、speeds、acc、curvatures的归一化参数)
  • 按轨迹连续划分训练/测试集:前80%轨迹用于训练,后20%用于测试,确保轨迹连续性
  • 自动调整轨迹最小点数:确保轨迹点数不小于配置的关键点数量(num_key_points)
  • 保存归一化参数到 data/processed/normalization_params.json

3. 轨迹可视化测试

查看原始数据的轨迹信息和运动信息:

python test.py --mode B
python test.py --mode Catmull-Rom
python test.py --mode Bezier

支持的插值模式:

模式 插值方法 特点
B B样条插值 平滑且通过控制点附近
Catmull-Rom Catmull-Rom样条 平滑且严格通过所有控制点
Bezier 贝塞尔曲线 平滑但不通过中间控制点

输出信息:

  • 时间信息:开始时间戳、结束时间戳、总时长、平均时间间隔
  • 运动信息:最大速度、最大加速度、最大负加速度
  • 统计信息:速度均值、速度方差、加速度均值、加速度方差、曲率均值、曲率方差、最大曲率

1784869410897

4. 训练模型

运行训练脚本,支持GPU加速:

python train.py
  • 自动检测CUDA设备
  • 支持MLP和LSTM两种模型架构(通过config.yaml配置)
  • 多任务学习模型:输入 (dx, dy, distance, direction, avg_curvature),输出 (N个轨迹点 + N个速度 + N-1个加速度 + N个曲率),其中N为配置的关键点数量
  • 加权MSE损失:轨迹(0.45)、速度(0.20)、加速度(0.20)、曲率(0.15)
  • 评估指标:计算并输出终点误差、Fréchet距离
  • 指标输出:训练指标保存到 models/train/training_metrics.csv,测试指标保存到 models/test/test_metrics.csv
  • 图表生成:自动生成训练指标组合图(损失曲线 + 误差指标曲线)和测试指标条形图
  • TensorBoard:训练过程记录到 runs/ 目录
  • 训练完成后导出ONNX模型到 models/ 目录

train结果:

1784869191410

test结果:

1784869201804

5. 训练可视化

启动TensorBoard查看训练过程:

tensorboard --logdir=runs

查看内容:

  • 训练损失曲线(总损失、轨迹损失、速度损失、加速度损失、曲率损失)
  • 训练误差指标曲线(终点误差、Fréchet距离)
  • 测试损失曲线
  • 测试误差指标曲线(终点误差、Fréchet距离)

6. 验证与可视化

查看训练数据或模型预测结果:

python show.py

支持三种可视化:

  • 轨迹散点图(支持预测轨迹与真实轨迹叠加对比)
  • 速度-时间曲线图
  • 加速度-时间曲线图

1784869234520

7. 模拟鼠标运动(Windows)

运行测试程序,随机生成坐标并模拟人类鼠标移动:

python test_windows.py --mode Catmull-Rom

支持的命令行参数:

--mode B           # B样条插值(默认)
--mode Catmull-Rom # Catmull-Rom样条插值
--mode Bezier      # 贝塞尔曲线插值

核心特性:

  • 随机生成起始点和终点坐标(长距离移动:30%-70%屏幕对角线)
  • 调用ONNX模型预测轨迹
  • Windows API高精度控制:使用SendInput API发送相对位移,实现高精度鼠标移动
  • 多种插值模式:支持B样条、Catmull-Rom样条、贝塞尔曲线三种插值方法
  • 最小加加速度模型:使用 10t³ - 15t⁴ + 6t⁵ 生成平滑的S形速度曲线,符合人类"加速-匀速-减速"运动模式
  • 生理震颤模拟:叠加±1.5像素的高斯噪声模拟手部微小颤动,使用移动平均滤波确保连续性
  • 速度自适应:基于预测速度动态调整每段移动时间
  • 实时监控输出:每次运动后输出最大速度、最大加速度、最大负加速度、最大曲率、速度均值、加速度均值、曲率均值、曲率方差、速度方差、加速度方差
  • 速度曲线绘制:绘制速度随时间变化曲线图
  • 轨迹可视化:测试完成后自动生成轨迹图(models/test/trajectories_plot.png),10次移动使用不同颜色区分,圆圈表示起点,叉号表示终点,实线为实际移动轨迹,虚线为模型预测轨迹
  • 按 Ctrl+C 停止测试(中断后仍会生成已完成移动的轨迹图)

1784874528646

8. 模拟鼠标运动(macOS)

python test_mac.py --mode Catmull-Rom

注意:需要在 系统设置 > 隐私与安全性 > 辅助功能 中授权此应用

自定义关键点数量

通过修改 config.yaml 中的 num_key_points 可以调整模型预测的轨迹点数量:

data:
  num_key_points: 40    # 修改为你想要的点数(5-100之间)

修改后需要重新运行数据预处理和训练:

python preprocess_data.py
python train.py

模型会自动适应新的关键点数量,无需修改代码。

Python推理

import onnxruntime as ort
import numpy as np
import json

session = ort.InferenceSession("models/mouse.onnx")

with open("data/processed/normalization_params.json", 'r') as f:
    params = json.load(f)

dx, dy = 100, 150
distance = np.sqrt(dx ** 2 + dy ** 2)
direction = np.arctan2(dy, dx)
avg_curvature = 0.0

# 使用训练时的归一化参数进行归一化
dx_norm = (dx - params["dx_mean"]) / params["dx_std"]
dy_norm = (dy - params["dy_mean"]) / params["dy_std"]
distance_norm = (distance - params["distance_mean"]) / params["distance_std"]
direction_norm = (direction - params["direction_mean"]) / params["direction_std"]
avg_curvature_norm = (avg_curvature - params.get("avg_curvature_mean", 0)) / params.get("avg_curvature_std", 1)

input_data = np.array([[[dx_norm, dy_norm, distance_norm, direction_norm, avg_curvature_norm]]], dtype=np.float32)
outputs = session.run(None, {"input": input_data})

points = outputs[0][0]      # N个轨迹点
speeds = outputs[1][0]      # N个速度值
accelerations = outputs[2][0] # N-1个加速度值
curvatures = outputs[3][0]  # N个曲率值

# 反归一化
points[:, 0] = points[:, 0] * params['x_std'] + params['x_mean']
points[:, 1] = points[:, 1] * params['y_std'] + params['y_mean']
speeds = speeds * params['speeds_std'] + params['speeds_mean']
accelerations = accelerations * params['acc_std'] + params['acc_mean']
curvatures = curvatures * params['curvatures_std'] + params['curvatures_mean']

C++推理

cv::dnn::Net net;
net = cv::dnn::readNetFromONNX("mouse.onnx");
if (!net.empty())
{
  cv::Mat blob(1, 5, CV_32F, cv::Scalar(dx_norm, dy_norm, dist_norm, dir_norm, curvature_norm));
  int sizes[] = { 1, 10, 2 };
  cv::Mat mat(3, sizes, CV_32F);
  net.setInput(blob,"input");
  cv::Mat output = net.forward("output");
  std::cout << output.at<float>(0,8,0) << std::endl;
}

评估指标

指标 说明 计算公式
MSE 均方误差 预测值与真实值差的平方均值
终点误差 轨迹终点偏差 预测终点与真实终点的欧氏距离
Fréchet距离 曲线相似度 考虑曲线顺序的最短距离匹配

注意事项

  1. 数据收集:后台收集的数据量较大,请确保硬盘空间充足
  2. 隐私合规:仅在个人设备上使用,注意相关法律法规,不涉及任何个人隐私信息,仅用于研究和学习目的。任何个人数据都不会被存储或分享。
  3. 模型训练:建议在GPU服务器上训练以获得更好的性能
  4. 流畅性:使用最小加加速度模型 + 缓动函数模拟人类加速-匀速-减速行为,保证动作自然
  5. 生理震颤:噪声幅度控制在±1.5像素内,使用移动平均滤波确保连续性
  6. 数据划分:训练/测试集按轨迹连续划分,确保同一轨迹的样本不被拆分
  7. 归一化:推理时必须使用训练时保存的归一化参数进行输入归一化和输出反归一化
  8. 关键点数量:修改num_key_points后必须重新运行数据预处理和训练
  9. 轨迹可视化:测试程序需要matplotlib库生成轨迹图
  10. 方向变化检测:相邻向量夹角大于60度时强制分割轨迹,避免锐角拐弯学习到一条轨迹中

优化历史

  • v1.0:二开基础版本,输入(dx, dy),单任务预测轨迹点
  • v2.0:多任务学习,同时预测轨迹点、速度、加速度
  • v3.0:参数配置化、输入特征扩展、完善评估指标、TensorBoard可视化
  • v3.1:训练集添加终点误差和Fréchet距离计算,更新图表为双子图布局
  • v4.0:支持自定义关键点数量、Windows API高精度鼠标控制、轨迹可视化
  • v4.1:方向变化检测、自适应采样、曲率作为训练维度、多种插值模式
  • v4.2:最小加加速度模型、生理震颤模拟、实时监控、速度曲线绘制

License

MIT License

About

一种基于神经网络来模拟人手移动鼠标的方法-fork from sunxin1424

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages