尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

Python+OpenCV舞蹈动作分析系统:从人体姿态检测到实时比对

发布时间:2026/9/3 7:11:44

资讯中心
01
ARTICLE

Python+OpenCV舞蹈动作分析系统:从人体姿态检测到实时比对

Python+OpenCV舞蹈动作分析系统:从人体姿态检测到实时比对
最近在舞蹈社团排练时经常需要快速学习和编排新舞蹈特别是像《RUN TO YOU》这样的热门曲目。传统的手写笔记和视频回放效率不高于是尝试用Python开发一个舞蹈动作分析工具没想到效果出奇的好。本文将分享如何用PythonOpenCV构建一个简易的舞蹈动作分析系统适合舞蹈爱好者、社团排练和教学使用。1. 舞蹈动作分析系统概述舞蹈动作分析系统是通过计算机视觉技术对舞蹈视频中的动作进行捕捉、分析和比对的技术方案。它可以帮助舞者更高效地学习舞蹈动作纠正姿势偏差特别适合团体舞蹈的整齐度训练。1.1 系统核心功能动作捕捉实时检测视频中的人体关键点动作比对将当前动作与标准动作进行相似度分析节奏分析结合音乐节奏标记动作时间点可视化反馈用不同颜色标注动作准确度1.2 技术实现原理系统基于OpenCV和MediaPipe库实现。MediaPipe提供预训练的人体姿态检测模型可以识别33个关键身体点坐标。通过计算关键点之间的角度和距离关系实现动作特征的量化分析。2. 环境准备与依赖配置2.1 系统要求操作系统Windows 10/11、macOS 10.14 或 Ubuntu 18.04Python版本3.7-3.10推荐3.8内存至少4GB建议8GB以上摄像头支持1080p分辨率的USB摄像头或网络摄像头2.2 安装必要的Python库创建新的Python虚拟环境后安装以下依赖包# 创建虚拟环境可选 python -m venv dance_analysis source dance_analysis/bin/activate # Linux/macOS dance_analysis\Scripts\activate # Windows # 安装核心依赖 pip install opencv-python4.5.5.64 pip install mediapipe0.8.9.1 pip install numpy1.21.6 pip install matplotlib3.5.2 pip install scipy1.7.32.3 验证安装创建简单的验证脚本检查环境是否正常# test_environment.py import cv2 import mediapipe as mp import numpy as np print(OpenCV版本:, cv2.__version__) print(MediaPipe版本:, mp.__version__) print(NumPy版本:, np.__version__) # 检查MediaPipe姿态检测模型是否能加载 mp_pose mp.solutions.pose pose mp_pose.Pose(static_image_modeTrue, min_detection_confidence0.5) print(姿态检测模型加载成功!) pose.close()3. 核心技术与算法原理3.1 人体关键点检测MediaPipe Pose模型可以检测人体的33个关键点包括面部、躯干、四肢等部位。每个关键点包含(x, y, z)三维坐标和可见度置信度。# 关键点索引定义 LANDMARK_INDICES { NOSE: 0, LEFT_SHOULDER: 11, RIGHT_SHOULDER: 12, LEFT_ELBOW: 13, RIGHT_ELBOW: 14, LEFT_WRIST: 15, RIGHT_WRIST: 16, LEFT_HIP: 23, RIGHT_HIP: 24, LEFT_KNEE: 25, RIGHT_KNEE: 26, LEFT_ANKLE: 27, RIGHT_ANKLE: 28 }3.2 动作特征提取通过计算关键点之间的角度和距离关系将舞蹈动作转化为数值特征向量import math def calculate_angle(point1, point2, point3): 计算三个关键点形成的角度 # 向量AB和BC vector_ab [point2.x - point1.x, point2.y - point1.y] vector_bc [point3.x - point2.x, point3.y - point2.y] # 计算夹角 dot_product vector_ab[0] * vector_bc[0] vector_ab[1] * vector_bc[1] magnitude_ab math.sqrt(vector_ab[0]**2 vector_ab[1]**2) magnitude_bc math.sqrt(vector_bc[0]**2 vector_bc[1]**2) # 避免除零错误 if magnitude_ab * magnitude_bc 0: return 0 cosine_angle dot_product / (magnitude_ab * magnitude_bc) cosine_angle max(-1, min(1, cosine_angle)) # 限制范围 angle math.degrees(math.acos(cosine_angle)) return angle def extract_pose_features(landmarks): 从关键点中提取特征向量 features [] # 计算主要关节角度 # 左臂角度肩-肘-腕 left_arm_angle calculate_angle( landmarks[LANDMARK_INDICES[LEFT_SHOULDER]], landmarks[LANDMARK_INDICES[LEFT_ELBOW]], landmarks[LANDMARK_INDICES[LEFT_WRIST]] ) features.append(left_arm_angle) # 右臂角度 right_arm_angle calculate_angle( landmarks[LANDMARK_INDICES[RIGHT_SHOULDER]], landmarks[LANDMARK_INDICES[RIGHT_ELBOW]], landmarks[LANDMARK_INDICES[RIGHT_WRIST]] ) features.append(right_arm_angle) # 左腿角度髋-膝-踝 left_leg_angle calculate_angle( landmarks[LANDMARK_INDICES[LEFT_HIP]], landmarks[LANDMARK_INDICES[LEFT_KNEE]], landmarks[LANDMARK_INDICES[LEFT_ANKLE]] ) features.append(left_leg_angle) # 右腿角度 right_leg_angle calculate_angle( landmarks[LANDMARK_INDICES[RIGHT_HIP]], landmarks[LANDMARK_INDICES[RIGHT_KNEE]], landmarks[LANDMARK_INDICES[RIGHT_ANKLE]] ) features.append(right_leg_angle) return np.array(features)3.3 动作相似度计算使用动态时间规整(DTW)算法比较两个动作序列的相似度from scipy.spatial.distance import euclidean from fastdtw import fastdtw def calculate_similarity(sequence1, sequence2): 计算两个动作序列的相似度 distance, path fastdtw(sequence1, sequence2, disteuclidean) # 将距离转换为相似度分数0-100 max_distance 1000 # 经验值可根据实际情况调整 similarity max(0, 100 - (distance / max_distance * 100)) return similarity4. 完整系统实现4.1 项目结构设计创建以下文件结构dance_analysis/ ├── main.py # 主程序入口 ├── pose_detector.py # 姿态检测模块 ├── motion_analyzer.py # 动作分析模块 ├── video_processor.py # 视频处理模块 ├── config.py # 配置文件 └── data/ # 数据目录 ├── reference/ # 参考动作视频 └── output/ # 分析结果输出4.2 核心模块实现4.2.1 姿态检测模块# pose_detector.py import cv2 import mediapipe as mp import numpy as np class PoseDetector: def __init__(self, static_image_modeFalse, model_complexity1, smooth_landmarksTrue, enable_segmentationFalse, smooth_segmentationTrue, min_detection_confidence0.5, min_tracking_confidence0.5): self.mp_pose mp.solutions.pose self.pose self.mp_pose.Pose( static_image_modestatic_image_mode, model_complexitymodel_complexity, smooth_landmarkssmooth_landmarks, enable_segmentationenable_segmentation, smooth_segmentationsmooth_segmentation, min_detection_confidencemin_detection_confidence, min_tracking_confidencemin_tracking_confidence ) self.mp_draw mp.solutions.drawing_utils def detect_pose(self, image, drawTrue): 检测图像中的姿态 rgb_image cv2.cvtColor(image, cv2.COLOR_BGR2RGB) results self.pose.process(rgb_image) if results.pose_landmarks and draw: self.mp_draw.draw_landmarks( image, results.pose_landmarks, self.mp_pose.POSE_CONNECTIONS, self.mp_draw.DrawingSpec(color(0, 255, 0), thickness2, circle_radius2), self.mp_draw.DrawingSpec(color(255, 0, 0), thickness2, circle_radius2) ) return results.pose_landmarks, image def get_landmark_coordinates(self, landmarks, image_shape): 获取关键点坐标 if not landmarks: return None coordinates [] height, width image_shape[:2] for landmark in landmarks.landmark: x int(landmark.x * width) y int(landmark.y * height) z landmark.z visibility landmark.visibility coordinates.append((x, y, z, visibility)) return coordinates def release(self): 释放资源 self.pose.close()4.2.2 动作分析模块# motion_analyzer.py import numpy as np from scipy.spatial.distance import euclidean from fastdtw import fastdtw import json import os class MotionAnalyzer: def __init__(self, reference_sequenceNone): self.reference_sequence reference_sequence self.current_sequence [] def set_reference(self, sequence): 设置参考动作序列 self.reference_sequence sequence def add_frame(self, features): 添加当前帧特征 if features is not None: self.current_sequence.append(features) def analyze_similarity(self): 分析当前序列与参考序列的相似度 if not self.reference_sequence or not self.current_sequence: return 0 # 使用DTW计算序列相似度 distance, _ fastdtw(self.reference_sequence, self.current_sequence, disteuclidean) # 归一化相似度分数 max_possible_distance len(self.reference_sequence) * 100 # 估计最大距离 similarity max(0, 100 - (distance / max_possible_distance * 100)) return similarity def save_sequence(self, sequence, filename): 保存动作序列到文件 os.makedirs(data, exist_okTrue) with open(fdata/{filename}.json, w) as f: json.dump([arr.tolist() for arr in sequence], f) def load_sequence(self, filename): 从文件加载动作序列 try: with open(fdata/{filename}.json, r) as f: sequence [np.array(arr) for arr in json.load(f)] return sequence except FileNotFoundError: print(f文件 {filename} 不存在) return None def reset_current(self): 重置当前序列 self.current_sequence []4.2.3 视频处理模块# video_processor.py import cv2 import numpy as np from pose_detector import PoseDetector from motion_analyzer import MotionAnalyzer class VideoProcessor: def __init__(self, video_source0): self.cap cv2.VideoCapture(video_source) self.pose_detector PoseDetector() self.analyzer MotionAnalyzer() self.is_analyzing False def process_frame(self, frame): 处理单帧图像 landmarks, annotated_frame self.pose_detector.detect_pose(frame) if landmarks and self.is_analyzing: # 提取特征并分析 coordinates self.pose_detector.get_landmark_coordinates(landmarks, frame.shape) features self.extract_features_from_coordinates(coordinates) self.analyzer.add_frame(features) # 计算相似度 similarity self.analyzer.analyze_similarity() # 在画面上显示相似度 cv2.putText(annotated_frame, fSimilarity: {similarity:.1f}%, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2) return annotated_frame def extract_features_from_coordinates(self, coordinates): 从坐标中提取特征 if not coordinates: return None # 简化特征提取只使用关键点的相对位置 features [] key_indices [11, 12, 13, 14, 15, 16, 23, 24, 25, 26, 27, 28] # 主要关节 for i in key_indices: if i len(coordinates): x, y, z, _ coordinates[i] features.extend([x, y]) return np.array(features) def start_analysis(self): 开始分析 self.is_analyzing True self.analyzer.reset_current() def stop_analysis(self): 停止分析 self.is_analyzing False def set_reference_from_file(self, filename): 从文件设置参考动作 sequence self.analyzer.load_sequence(filename) if sequence: self.analyzer.set_reference(sequence) return True return False def release(self): 释放资源 self.cap.release() self.pose_detector.release() cv2.destroyAllWindows()4.3 主程序实现# main.py import cv2 import sys from video_processor import VideoProcessor def main(): # 初始化视频处理器 processor VideoProcessor(0) # 0表示默认摄像头 print(舞蹈动作分析系统启动成功!) print(操作说明:) print(1. 按 r 键开始录制参考动作) print(2. 按 s 键停止录制并保存为参考) print(3. 按 a 键开始实时动作分析) print(4. 按 q 键退出程序) reference_recorded False while True: ret, frame processor.cap.read() if not ret: print(无法读取视频流) break # 处理帧 processed_frame processor.process_frame(frame) # 显示处理结果 cv2.imshow(Dance Motion Analysis, processed_frame) # 键盘控制 key cv2.waitKey(1) 0xFF if key ord(r): # 开始录制参考动作 processor.start_analysis() print(开始录制参考动作...) elif key ord(s): # 停止录制并保存参考动作 processor.stop_analysis() processor.analyzer.save_sequence(processor.analyzer.current_sequence, reference) reference_recorded True print(参考动作已保存!) elif key ord(a) and reference_recorded: # 开始实时分析 processor.set_reference_from_file(reference) processor.start_analysis() print(开始实时动作分析...) elif key ord(q): # 退出程序 break # 释放资源 processor.release() print(程序已退出) if __name__ __main__: main()4.4 系统运行演示运行程序后按照以下步骤操作录制参考动作面对摄像头按下r键开始录制标准舞蹈动作完成动作后按s键保存实时分析按下a键开始实时分析系统会显示当前动作与参考动作的相似度百分比优化调整根据相似度反馈调整动作直到达到满意的匹配度5. 常见问题与解决方案5.1 环境配置问题问题现象可能原因解决方案导入MediaPipe报错版本不兼容使用指定版本pip install mediapipe0.8.9.1摄像头无法打开权限问题或设备占用检查摄像头权限关闭其他使用摄像头的程序运行速度慢硬件性能不足降低摄像头分辨率使用model_complexity05.2 检测精度问题# 提高检测精度的配置 def create_high_accuracy_detector(): return PoseDetector( static_image_modeFalse, model_complexity2, # 使用更复杂的模型 min_detection_confidence0.7, # 提高检测置信度阈值 min_tracking_confidence0.7 # 提高跟踪置信度阈值 )5.3 光线和背景优化光线要求确保拍摄环境光线充足均匀避免逆光背景简洁使用单色背景避免复杂图案干扰检测服装对比穿着与背景颜色对比明显的服装6. 高级功能扩展6.1 多人舞蹈分析扩展系统支持多人同时分析class MultiPersonAnalyzer: def __init__(self): self.person_analyzers [] def add_person(self): 添加新的分析器实例 analyzer MotionAnalyzer() self.person_analyzers.append(analyzer) return len(self.person_analyzers) - 1 # 返回人员ID def analyze_group_synchronization(self): 分析团体同步度 if len(self.person_analyzers) 2: return 0 # 计算所有人之间的平均相似度 total_similarity 0 count 0 for i in range(len(self.person_analyzers)): for j in range(i 1, len(self.person_analyzers)): similarity self.calculate_pair_similarity( self.person_analyzers[i].current_sequence, self.person_analyzers[j].current_sequence ) total_similarity similarity count 1 return total_similarity / count if count 0 else 06.2 节奏分析集成结合音乐节奏进行更精确的动作时序分析import librosa class RhythmAnalyzer: def __init__(self, audio_file): self.audio_file audio_file self.tempo None self.beats None def analyze_rhythm(self): 分析音乐节奏 y, sr librosa.load(self.audio_file) # 检测节奏和节拍 self.tempo, beat_frames librosa.beat.beat_track(yy, srsr) self.beats librosa.frames_to_time(beat_frames, srsr) return self.tempo, self.beats def align_with_beats(self, motion_sequence, timestamps): 将动作序列与节拍对齐 aligned_sequence [] for beat_time in self.beats: # 找到最接近节拍时间点的动作帧 closest_idx np.argmin(np.abs(np.array(timestamps) - beat_time)) if closest_idx len(motion_sequence): aligned_sequence.append(motion_sequence[closest_idx]) return aligned_sequence6.3 数据持久化与报告生成import pandas as pd from datetime import datetime class ReportGenerator: def __init__(self): self.sessions [] def add_session(self, session_data): 添加训练会话数据 session_data[timestamp] datetime.now() self.sessions.append(session_data) def generate_progress_report(self): 生成进步报告 if not self.sessions: return None df pd.DataFrame(self.sessions) # 计算各项指标的进步情况 report { total_sessions: len(df), average_similarity: df[similarity].mean(), best_score: df[similarity].max(), improvement_trend: self.calculate_trend(df[similarity]) } return report def export_to_csv(self, filename): 导出数据到CSV文件 df pd.DataFrame(self.sessions) df.to_csv(filename, indexFalse)7. 实际应用建议7.1 舞蹈教学场景分解教学将复杂舞蹈分解为单个动作进行针对性训练实时反馈学员可以立即看到动作准确度加快学习进度团体协调帮助舞蹈团队提高动作整齐度7.2 排练优化策略分段练习将舞蹈分成小段逐段优化慢速练习先确保动作准确再提高速度镜像对比同时显示参考动作和当前动作进行对比数据追踪记录每次排练的进步情况7.3 技术优化方向模型优化使用更轻量化的模型提高运行效率移动端适配开发手机APP版本方便随时使用云端分析将视频上传到云端进行更复杂的分析AI教练集成AI建议系统提供具体的改进指导这个舞蹈动作分析系统虽然简单但已经具备了实用的核心功能。通过不断的迭代优化可以发展成为专业的舞蹈训练辅助工具。特别是在团体舞蹈排练中能够有效提高训练效率和动作质量。
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。