video-motion-direction-skill — 视频运动方向分析测试
基于 Farneback 密集光流法分析视频帧间运动,自动将视频按方向变化切分为连续时间段,输出「向左3.5秒 → 静止1.2秒 → 向右5.0秒」的时间轴。
测试流程
- 前置条件1: 从
test_config.json读取配置(应用名称、设备名称、功能项、数据资源) - 前置条件2: ADB端口策略 — 命令行优先 > 配置文件
基础信息.安卓模拟器> 默认值5555。模拟器类型映射: 雷电→5555, MuMu→16384 - 前置条件3: 调用
ydkj_camera_position_init执行PTZ预置位初始化 - 主流程:
- 连接设备 → 进入直播页
- 播放测试视频(PotPlayer),触发移动追踪告警
- 获取告警事件 → 下载事件关联视频
- 用 Farneback 密集光流法分析视频运动方向
- 验证主要方向是否为期望值(默认期望向右) - 输出: JSON 结果文件(含
result.passed)
参数
| 参数 | 说明 | 默认值 |
|---|---|---|
--adb-port |
ADB端口 | 从配置文件读/5555 |
--device-name |
设备名称 | 从配置文件读 |
--video |
测试视频路径 | 从配置文件读/D:\video\运动跟踪_背景不动_从左向右_.mp4 |
--play-duration |
播放时长(秒) | 配置文件测试标准/15 |
--min-segment |
最小分析片段(秒) | 0.6 |
--no-ptz |
跳过PTZ初始化 | 无 |
--skip-app |
纯分析模式(跳过APP操作) | 无 |
--prompt |
提示词文件路径 | 无 |
使用方式
全流程测试(含APP操作)
python motion_direction_test.py
全流程测试(指定参数)
python motion_direction_test.py --adb-port 5555 --device-name ydkj123
纯视频分析模式(跳过APP+PTZ)
python motion_direction_test.py --skip-app --video D:\video\test.mp4 --min-segment 0.6
直接用核心分析模块
python scripts/analyze_motion.py D:\video\test.mp4 --min-segment 0.6
配置项(test_config.json)
基础信息
{
"基础信息": {
"应用名称": "移动爱家",
"产品名称": "V71S",
"设备名称": "ydkj123",
"安卓模拟器": "雷电"
},
"功能项": {
"PTZ云台": "支持",
"移动追踪": "支持"
},
"数据资源": {
"运行跟踪视频": "运动跟踪_背景不动_从左向右_.mp4"
}
}
输出
测试/执行结果输出到:workspace/test_output/video-motion-direction-skill/motion_direction_test_YYYYMMDD_HHMMSS.json
JSON 输出格式(含 result.passed)
{
"device": "ydkj123",
"test_time": "2026-06-12T12:30:00",
"steps": [
{"step": 0, "action": "connect_device", "status": "passed"},
{"step": 1, "action": "ptz_position_init", "status": "passed"},
{"step": 2, "action": "play_video", "status": "passed"},
{"step": 3, "action": "fetch_event_video", "status": "passed"},
{"step": 4, "action": "analyze_direction", "status": "passed", "direction": "right"},
{"step": 5, "action": "verify_direction", "status": "passed", "expected": "right", "actual": "right"}
],
"result": {
"passed": true,
"messages": "success"
},
"main_direction": "right",
"video_analyzed": "D:\\video\\downloaded_20260612_123000.mp4",
"direction_analysis": {
"video": "motion_track_downloaded_20260612_123000.mp4",
"fps": 15.0,
"duration_sec": 19.87,
"main_direction": "right",
"main_direction_percent": 63.6,
"timeline": [
{"direction": "right", "start_sec": 0.13, "end_sec": 2.47, "duration_sec": 2.34, "frames": 18, "avg_magnitude": 3.7},
{"direction": "still", "start_sec": 3.47, "end_sec": 4.47, "duration_sec": 1.0, "frames": 8, "avg_magnitude": 0.0}
]
},
"verification": {
"result": {"passed": true, "messages": "PASS: direction=right (expected=right)"},
"expected_direction": "right",
"actual_direction": "right"
}
}
result 字段说明
| 字段 | 类型 | 说明 |
|---|---|---|
result.passed |
bool | 全部步骤通过为 true,否则 false |
result.messages |
string | "success" 或 "failed" |
核心分析模块(analyze_motion.py)
analyze_motion.py 是底层视频分析模块,保持独立可调用:
python skills/video-motion-direction-skill/scripts/analyze_motion.py <input_video> [options]
| 参数 | 说明 | 默认值 |
|---|---|---|
input_video |
输入视频路径(必填) | - |
-o, --output |
JSON 结果输出路径 | 控制台输出 |
--skip-frames |
跳帧数 | 1 |
--min-segment |
最小片段时长(秒) | 0.6 |
--still-threshold |
静止判定幅度阈值 | 0.8 |
--max-frames |
最大分析帧数(0=全部) | 0 |
--fps |
手动指定fps | auto |
算法说明
- Farneback密集光流:计算相邻帧每个像素的运动向量
- 方向判定:按0°/90°/180°/270°分为右/下/左/上四个方向
- 滑动窗口平滑:3帧窗口消除单帧毛刺
- 短片段合并:小于
min-segment的片段合并到相邻最长的片段 - 静止判定:整体运动幅度低于
still-threshold时标记为静止
依赖
- Python: opencv-python, numpy, uiautomator2
- 系统: adb, PotPlayer(播放测试视频时)
- 技能: ydkj_camera_position_init, ydkj_camera_fetch_events_test, potplayer-video-player-skill, emulator-app-launcher