add realsense camera
This commit is contained in:
parent
636fda3598
commit
c2c880a569
@ -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("系统信息")
|
||||
|
Loading…
Reference in New Issue
Block a user