add realsense camera
This commit is contained in:
parent
636fda3598
commit
c2c880a569
@ -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))
|
||||||
|
|
||||||
# 处理关键点检测
|
# 处理关键点检测
|
||||||
standard_keypoints, standard_scores = self.body_detector(standard_frame)
|
try:
|
||||||
webcam_keypoints, webcam_scores = self.body_detector(webcam_frame)
|
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帧计算一次相似度
|
# 每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("系统信息")
|
||||||
|
Loading…
Reference in New Issue
Block a user