From c2c880a5698444d2915955270971007031422992 Mon Sep 17 00:00:00 2001 From: game-loader Date: Mon, 16 Jun 2025 15:41:00 +0800 Subject: [PATCH] add realsense camera --- motion_comparison_app.py | 159 ++++++++++++++++++++++++++++++++------- 1 file changed, 132 insertions(+), 27 deletions(-) diff --git a/motion_comparison_app.py b/motion_comparison_app.py index 8d87e37..b827ff6 100644 --- a/motion_comparison_app.py +++ b/motion_comparison_app.py @@ -11,6 +11,7 @@ import pandas as pd import numpy as np from collections import deque import math +import pyrealsense2 as rs # 导入rtmlib @@ -216,31 +217,130 @@ class MotionComparisonApp: self.similarity_analyzer = PoseSimilarityAnalyzer() self.frame_counter = 0 + # RealSense相关 + self.realsense_pipeline = None + self.realsense_config = None + self.is_realsense_active = False + + def initialize_realsense(self): + """初始化RealSense摄像头""" + try: + # 创建pipeline和config + self.realsense_pipeline = rs.pipeline() + self.realsense_config = rs.config() + + # 配置RGB流 - 640x480 @ 30fps + self.realsense_config.enable_stream(rs.stream.color, 640, 480, rs.format.bgr8, 30) + + # 可选:启用深度流(如果需要) + # self.realsense_config.enable_stream(rs.stream.depth, 640, 480, rs.format.z16, 30) + + # 启动pipeline + profile = self.realsense_pipeline.start(self.realsense_config) + + # 获取设备信息 + device = profile.get_device() + device_info = f"RealSense {device.get_info(rs.camera_info.name)}" + + self.is_realsense_active = True + st.success(f"✅ RealSense摄像头初始化成功: {device_info}") + return True + + except Exception as e: + st.error(f"❌ RealSense摄像头初始化失败: {str(e)}") + st.info("尝试使用普通USB摄像头...") + + # 回退到普通摄像头 + self.webcam_cap = cv2.VideoCapture(0) + if self.webcam_cap.isOpened(): + st.info("✅ 使用普通USB摄像头") + return True + else: + st.error("❌ 无法打开任何摄像头") + return False + + def read_realsense_frame(self): + """从RealSense读取一帧图像""" + if not self.is_realsense_active or self.realsense_pipeline is None: + return False, None + + try: + # 等待新的帧 + frames = self.realsense_pipeline.wait_for_frames(timeout_ms=5000) + + # 获取RGB帧 + color_frame = frames.get_color_frame() + if not color_frame: + return False, None + + # 转换为numpy数组 + color_image = np.asanyarray(color_frame.get_data()) + + return True, color_image + + except Exception as e: + st.error(f"读取RealSense帧失败: {str(e)}") + return False, None + + def read_webcam_frame(self): + """统一的摄像头读取接口""" + if self.is_realsense_active: + return self.read_realsense_frame() + elif self.webcam_cap is not None and self.webcam_cap.isOpened(): + ret, frame = self.webcam_cap.read() + return ret, frame + else: + return False, None + + def stop_realsense(self): + """停止RealSense摄像头""" + if self.is_realsense_active and self.realsense_pipeline is not None: + try: + self.realsense_pipeline.stop() + self.is_realsense_active = False + st.info("RealSense摄像头已停止") + except Exception as e: + st.error(f"停止RealSense时出错: {str(e)}") + + def cleanup(self): + """清理所有资源""" + if self.standard_cap is not None and self.standard_cap.isOpened(): + self.standard_cap.release() + self.standard_cap = None + + if self.webcam_cap is not None and self.webcam_cap.isOpened(): + self.webcam_cap.release() + self.webcam_cap = None + + self.stop_realsense() + self.is_running = False def preview_webcam(self): """显示摄像头预览,帮助用户调整位置""" - # 打开摄像头 - self.webcam_cap = cv2.VideoCapture(0) - if not self.webcam_cap.isOpened(): - st.error("无法打开摄像头") + # 初始化RealSense摄像头 + if not self.initialize_realsense(): + st.error("无法初始化摄像头") return False # 创建显示容器 st.subheader("摄像头预览") preview_text = st.empty() - preview_text.info("请调整您的位置,确保全身在画面中清晰可见") + + # 显示摄像头信息 + camera_info = "RealSense摄像头" if self.is_realsense_active else "普通USB摄像头" + preview_text.info(f"正在使用: {camera_info} - 请调整您的位置,确保全身在画面中清晰可见") preview_placeholder = st.empty() # 显示停止预览按钮 col1, col2, col3 = st.columns([1, 1, 1]) - stop_preview = col2.button("停止预览", key="stop_preview_btn") # 预览循环 - while not stop_preview: + preview_active = True + while preview_active: # 读取摄像头帧 - ret, frame = self.webcam_cap.read() - if not ret: + ret, frame = self.read_webcam_frame() + if not ret or frame is None: st.error("无法获取摄像头画面") break @@ -266,13 +366,13 @@ class MotionComparisonApp: preview_placeholder.image(frame_rgb, caption="摄像头预览", use_column_width=True) # 检查停止按钮状态 - if col2.button("停止预览", key=f"stop_preview_btn_{time.time()}", replace=True): + if col2.button("停止预览", key="stop_preview_btn"): + preview_active = False break # 控制帧率 time.sleep(0.03) # 约30fps - # 返回预览是否成功 return True def initialize_detector(self): @@ -324,11 +424,10 @@ class MotionComparisonApp: st.error("无法打开标准视频文件") return - # 如果摄像头未打开,则打开摄像头 - if self.webcam_cap is None or not self.webcam_cap.isOpened(): - self.webcam_cap = cv2.VideoCapture(0) - if not self.webcam_cap.isOpened(): - st.error("无法打开摄像头") + # 确保RealSense摄像头正常工作 + if not self.is_realsense_active and (self.webcam_cap is None or not self.webcam_cap.isOpened()): + if not self.initialize_realsense(): + st.error("无法初始化摄像头") return # 获取视频信息 @@ -343,10 +442,11 @@ class MotionComparisonApp: standard_placeholder = st.empty() with col2: - st.subheader("摄像头实时影像") + camera_type = "RealSense摄像头" if self.is_realsense_active else "USB摄像头" + st.subheader(f"{camera_type}实时影像") webcam_placeholder = st.empty() - # 添加相似度显区域 + # 添加相似度显示区域 similarity_col1, similarity_col2 = st.columns([1, 2]) with similarity_col1: st.subheader("实时相似度") @@ -383,8 +483,8 @@ class MotionComparisonApp: continue # 读取摄像头帧 - ret_webcam, webcam_frame = self.webcam_cap.read() - if not ret_webcam: + ret_webcam, webcam_frame = self.read_webcam_frame() + if not ret_webcam or webcam_frame is None: st.error("无法获取摄像头画面") break @@ -399,8 +499,12 @@ class MotionComparisonApp: webcam_frame = cv2.resize(webcam_frame, (target_width, target_height)) # 处理关键点检测 - standard_keypoints, standard_scores = self.body_detector(standard_frame) - webcam_keypoints, webcam_scores = self.body_detector(webcam_frame) + try: + standard_keypoints, standard_scores = self.body_detector(standard_frame) + webcam_keypoints, webcam_scores = self.body_detector(webcam_frame) + except Exception as e: + st.error(f"关键点检测错误: {str(e)}") + continue # 每10帧计算一次相似度 if self.frame_counter % 10 == 0: @@ -503,11 +607,8 @@ class MotionComparisonApp: with col3: st.metric("最低相似度", f"{min_similarity:.1f}%") - # 清理资源 - if self.standard_cap: - self.standard_cap.release() - if self.webcam_cap: - self.webcam_cap.release() + # 停止RealSense但不清理,可能还要预览 + # self.stop_realsense() # 注释掉,让用户手动停止 def main(): os.makedirs("preset_videos", exist_ok=True) @@ -599,6 +700,10 @@ def main(): if st.button("初始化关键点检测器"): with st.spinner("正在初始化..."): app.initialize_detector() + # 同时初始化RealSense摄像头 + with st.spinner("正在初始化RealSense摄像头..."): + app.initialize_realsense() + # 显示系统信息 st.subheader("系统信息")