add realsense camera

This commit is contained in:
game-loader 2025-06-16 15:41:00 +08:00
parent 636fda3598
commit c2c880a569

View File

@ -11,6 +11,7 @@ import pandas as pd
import numpy as np import numpy as np
from collections import deque from collections import deque
import math import math
import pyrealsense2 as rs
# 导入rtmlib # 导入rtmlib
@ -216,31 +217,130 @@ class MotionComparisonApp:
self.similarity_analyzer = PoseSimilarityAnalyzer() self.similarity_analyzer = PoseSimilarityAnalyzer()
self.frame_counter = 0 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): def preview_webcam(self):
"""显示摄像头预览,帮助用户调整位置""" """显示摄像头预览,帮助用户调整位置"""
# 打开摄像头 # 初始化RealSense摄像头
self.webcam_cap = cv2.VideoCapture(0) if not self.initialize_realsense():
if not self.webcam_cap.isOpened(): st.error("无法初始化摄像头")
st.error("无法打开摄像头")
return False return False
# 创建显示容器 # 创建显示容器
st.subheader("摄像头预览") st.subheader("摄像头预览")
preview_text = st.empty() 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() preview_placeholder = st.empty()
# 显示停止预览按钮 # 显示停止预览按钮
col1, col2, col3 = st.columns([1, 1, 1]) 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() ret, frame = self.read_webcam_frame()
if not ret: if not ret or frame is None:
st.error("无法获取摄像头画面") st.error("无法获取摄像头画面")
break break
@ -266,13 +366,13 @@ class MotionComparisonApp:
preview_placeholder.image(frame_rgb, caption="摄像头预览", use_column_width=True) 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 break
# 控制帧率 # 控制帧率
time.sleep(0.03) # 约30fps time.sleep(0.03) # 约30fps
# 返回预览是否成功
return True return True
def initialize_detector(self): def initialize_detector(self):
@ -324,11 +424,10 @@ class MotionComparisonApp:
st.error("无法打开标准视频文件") st.error("无法打开标准视频文件")
return return
# 如果摄像头未打开,则打开摄像头 # 确保RealSense摄像头正常工作
if self.webcam_cap is None or not self.webcam_cap.isOpened(): if not self.is_realsense_active and (self.webcam_cap is None or not self.webcam_cap.isOpened()):
self.webcam_cap = cv2.VideoCapture(0) if not self.initialize_realsense():
if not self.webcam_cap.isOpened(): st.error("无法初始化摄像头")
st.error("无法打开摄像头")
return return
# 获取视频信息 # 获取视频信息
@ -343,10 +442,11 @@ class MotionComparisonApp:
standard_placeholder = st.empty() standard_placeholder = st.empty()
with col2: with col2:
st.subheader("摄像头实时影像") camera_type = "RealSense摄像头" if self.is_realsense_active else "USB摄像头"
st.subheader(f"{camera_type}实时影像")
webcam_placeholder = st.empty() webcam_placeholder = st.empty()
# 添加相似度显区域 # 添加相似度显区域
similarity_col1, similarity_col2 = st.columns([1, 2]) similarity_col1, similarity_col2 = st.columns([1, 2])
with similarity_col1: with similarity_col1:
st.subheader("实时相似度") st.subheader("实时相似度")
@ -383,8 +483,8 @@ class MotionComparisonApp:
continue continue
# 读取摄像头帧 # 读取摄像头帧
ret_webcam, webcam_frame = self.webcam_cap.read() ret_webcam, webcam_frame = self.read_webcam_frame()
if not ret_webcam: if not ret_webcam or webcam_frame is None:
st.error("无法获取摄像头画面") st.error("无法获取摄像头画面")
break break
@ -399,8 +499,12 @@ class MotionComparisonApp:
webcam_frame = cv2.resize(webcam_frame, (target_width, target_height)) webcam_frame = cv2.resize(webcam_frame, (target_width, target_height))
# 处理关键点检测 # 处理关键点检测
try:
standard_keypoints, standard_scores = self.body_detector(standard_frame) standard_keypoints, standard_scores = self.body_detector(standard_frame)
webcam_keypoints, webcam_scores = self.body_detector(webcam_frame) webcam_keypoints, webcam_scores = self.body_detector(webcam_frame)
except Exception as e:
st.error(f"关键点检测错误: {str(e)}")
continue
# 每10帧计算一次相似度 # 每10帧计算一次相似度
if self.frame_counter % 10 == 0: if self.frame_counter % 10 == 0:
@ -503,11 +607,8 @@ class MotionComparisonApp:
with col3: with col3:
st.metric("最低相似度", f"{min_similarity:.1f}%") st.metric("最低相似度", f"{min_similarity:.1f}%")
# 清理资源 # 停止RealSense但不清理可能还要预览
if self.standard_cap: # self.stop_realsense() # 注释掉,让用户手动停止
self.standard_cap.release()
if self.webcam_cap:
self.webcam_cap.release()
def main(): def main():
os.makedirs("preset_videos", exist_ok=True) os.makedirs("preset_videos", exist_ok=True)
@ -599,6 +700,10 @@ def main():
if st.button("初始化关键点检测器"): if st.button("初始化关键点检测器"):
with st.spinner("正在初始化..."): with st.spinner("正在初始化..."):
app.initialize_detector() app.initialize_detector()
# 同时初始化RealSense摄像头
with st.spinner("正在初始化RealSense摄像头..."):
app.initialize_realsense()
# 显示系统信息 # 显示系统信息
st.subheader("系统信息") st.subheader("系统信息")