#!/usr/bin/env python3 """ 创建测试视频 生成包含手部动作的测试视频用于系统测试 """ import cv2 import numpy as np import os import argparse def create_test_video(output_path, duration=10, fps=30): """ 创建测试视频 参数: output_path: 输出视频路径 duration: 视频时长(秒) fps: 帧率 """ # 视频参数 width, height = 640, 480 total_frames = duration * fps # 创建视频写入器 fourcc = cv2.VideoWriter_fourcc(*'mp4v') out = cv2.VideoWriter(output_path, fourcc, fps, (width, height)) print(f"正在创建测试视频: {output_path}") print(f"分辨率: {width}x{height}, 帧率: {fps}, 时长: {duration}秒") for frame_idx in range(total_frames): # 创建背景 frame = np.zeros((height, width, 3), dtype=np.uint8) frame[:] = (40, 40, 40) # 深灰色背景 # 计算进度 progress = frame_idx / total_frames # 绘制模拟手部(圆形) center_x = int(width * 0.3 + width * 0.4 * np.sin(progress * 4 * np.pi)) center_y = int(height * 0.3 + height * 0.4 * np.cos(progress * 2 * np.pi)) # 主手部圆形 cv2.circle(frame, (center_x, center_y), 30, (255, 200, 100), -1) # 绘制5个手指(小圆形) finger_positions = [ (center_x - 20, center_y - 35), # 拇指 (center_x - 10, center_y - 40), # 食指 (center_x, center_y - 42), # 中指 (center_x + 10, center_y - 40), # 无名指 (center_x + 20, center_y - 35) # 小指 ] for i, (fx, fy) in enumerate(finger_positions): # 手指颜色渐变 color = (200 + i * 10, 150 + i * 20, 100 + i * 15) cv2.circle(frame, (fx, fy), 8, color, -1) # 绘制手腕 wrist_x, wrist_y = center_x, center_y + 40 cv2.circle(frame, (wrist_x, wrist_y), 15, (180, 150, 120), -1) # 连接手掌和手腕 cv2.line(frame, (center_x, center_y), (wrist_x, wrist_y), (200, 180, 150), 8) # 添加文字信息 time_text = f"时间: {frame_idx/fps:.1f}s" position_text = f"位置: ({center_x}, {center_y})" cv2.putText(frame, time_text, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 255, 255), 2) cv2.putText(frame, position_text, (10, 60), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 255, 255), 2) cv2.putText(frame, "测试视频 - 模拟手部动作", (10, height - 20), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2) # 写入帧 out.write(frame) # 显示进度 if frame_idx % (fps * 2) == 0: # 每2秒显示一次进度 print(f"进度: {progress*100:.1f}%") # 释放资源 out.release() print(f"✅ 测试视频创建完成: {output_path}") def create_gesture_test_video(output_path, duration=15, fps=30): """ 创建手势测试视频 包含不同的手势动作 """ width, height = 640, 480 total_frames = duration * fps fourcc = cv2.VideoWriter_fourcc(*'mp4v') out = cv2.VideoWriter(output_path, fourcc, fps, (width, height)) print(f"正在创建手势测试视频: {output_path}") gestures = [ "张开手掌", "握拳", "OK手势", "指向手势", "抓取动作" ] frames_per_gesture = total_frames // len(gestures) for frame_idx in range(total_frames): frame = np.zeros((height, width, 3), dtype=np.uint8) frame[:] = (50, 50, 50) # 确定当前手势 gesture_idx = frame_idx // frames_per_gesture if gesture_idx >= len(gestures): gesture_idx = len(gestures) - 1 current_gesture = gestures[gesture_idx] # 手部基本位置 center_x = width // 2 center_y = height // 2 # 根据手势绘制不同形状 if current_gesture == "张开手掌": # 绘制张开的手掌 cv2.circle(frame, (center_x, center_y), 40, (255, 200, 100), -1) # 五个分开的手指 for i, angle in enumerate([-60, -30, 0, 30, 60]): finger_x = center_x + int(50 * np.cos(np.radians(angle))) finger_y = center_y - int(50 * np.sin(np.radians(angle))) cv2.circle(frame, (finger_x, finger_y), 12, (200, 180, 150), -1) elif current_gesture == "握拳": # 绘制握拳 cv2.circle(frame, (center_x, center_y), 35, (255, 200, 100), -1) # 手指弯曲(小圆圈) for i, angle in enumerate([-45, -22, 0, 22, 45]): finger_x = center_x + int(25 * np.cos(np.radians(angle))) finger_y = center_y - int(15 * np.sin(np.radians(angle))) cv2.circle(frame, (finger_x, finger_y), 8, (180, 150, 120), -1) elif current_gesture == "OK手势": # 绘制OK手势 cv2.circle(frame, (center_x, center_y), 35, (255, 200, 100), -1) # 拇指和食指形成圆圈 cv2.circle(frame, (center_x - 15, center_y - 20), 8, (200, 180, 150), -1) cv2.circle(frame, (center_x - 5, center_y - 25), 8, (200, 180, 150), -1) # 其他手指伸直 for i, angle in enumerate([15, 30, 45]): finger_x = center_x + int(40 * np.cos(np.radians(angle))) finger_y = center_y - int(40 * np.sin(np.radians(angle))) cv2.circle(frame, (finger_x, finger_y), 10, (200, 180, 150), -1) elif current_gesture == "指向手势": # 绘制指向手势 cv2.circle(frame, (center_x, center_y), 30, (255, 200, 100), -1) # 食指伸出 cv2.circle(frame, (center_x, center_y - 45), 10, (200, 180, 150), -1) # 其他手指弯曲 for i, angle in enumerate([-30, 15, 30]): finger_x = center_x + int(20 * np.cos(np.radians(angle))) finger_y = center_y - int(10 * np.sin(np.radians(angle))) cv2.circle(frame, (finger_x, finger_y), 8, (180, 150, 120), -1) elif current_gesture == "抓取动作": # 绘制抓取动作 cv2.circle(frame, (center_x, center_y), 32, (255, 200, 100), -1) # 拇指和食指靠近 thumb_x = center_x - 20 thumb_y = center_y - 20 index_x = center_x - 10 index_y = center_y - 30 cv2.circle(frame, (thumb_x, thumb_y), 9, (200, 180, 150), -1) cv2.circle(frame, (index_x, index_y), 9, (200, 180, 150), -1) # 连接线表示抓取 cv2.line(frame, (thumb_x, thumb_y), (index_x, index_y), (255, 255, 255), 2) # 添加文字信息 cv2.putText(frame, f"手势: {current_gesture}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 0), 2) cv2.putText(frame, f"时间: {frame_idx/fps:.1f}s", (10, 60), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (255, 255, 255), 2) cv2.putText(frame, "手势测试视频", (10, height - 20), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 255), 2) out.write(frame) if frame_idx % (fps * 2) == 0: print(f"进度: {frame_idx/total_frames*100:.1f}% - 当前手势: {current_gesture}") out.release() print(f"✅ 手势测试视频创建完成: {output_path}") def main(): parser = argparse.ArgumentParser(description='创建手部检测测试视频') parser.add_argument('--type', choices=['basic', 'gesture', 'both'], default='both', help='视频类型 (basic: 基础移动, gesture: 手势, both: 两种都创建)') parser.add_argument('--duration', type=int, default=10, help='视频时长(秒)') parser.add_argument('--fps', type=int, default=30, help='帧率') parser.add_argument('--output-dir', default='data/videos', help='输出目录') args = parser.parse_args() # 确保输出目录存在 os.makedirs(args.output_dir, exist_ok=True) if args.type in ['basic', 'both']: basic_path = os.path.join(args.output_dir, 'test_basic.mp4') create_test_video(basic_path, args.duration, args.fps) if args.type in ['gesture', 'both']: gesture_path = os.path.join(args.output_dir, 'test_gesture.mp4') create_gesture_test_video(gesture_path, args.duration + 5, args.fps) print("\n🎉 测试视频创建完成!") print("\n📁 创建的文件:") for file in os.listdir(args.output_dir): if file.endswith('.mp4'): file_path = os.path.join(args.output_dir, file) size = os.path.getsize(file_path) / (1024 * 1024) # MB print(f" {file} ({size:.1f} MB)") print("\n🚀 使用方法:") print(" ./start_service.sh --test-video data/videos/test_basic.mp4") print(" ./start_service.sh --test-video data/videos/test_gesture.mp4") if __name__ == '__main__': main()