init
This commit is contained in:
140
run_live_demo.py
Normal file
140
run_live_demo.py
Normal file
@@ -0,0 +1,140 @@
|
||||
import os
|
||||
import cv2
|
||||
import re
|
||||
from surround_view import CaptureThread, CameraProcessingThread
|
||||
from surround_view import FisheyeCameraModel, BirdView
|
||||
from surround_view import MultiBufferManager, ProjectedImageBuffer
|
||||
import surround_view.param_settings as settings
|
||||
|
||||
|
||||
def is_rtsp_url(input_str):
|
||||
"""检查输入是否为RTSP URL"""
|
||||
return input_str.startswith('rtsp://')
|
||||
|
||||
|
||||
def main():
|
||||
# 配置四个RTSP摄像头地址(前、后、左、右)
|
||||
camera_ids = [
|
||||
"rtsp://admin:@192.168.112.153:554/video", # 前
|
||||
"rtsp://admin:@192.168.112.152:554/video", # 后
|
||||
"rtsp://admin:@192.168.112.150:554/video", # 左
|
||||
"rtsp://admin:@192.168.112.151:554/video" # 右
|
||||
]
|
||||
|
||||
# 摄像头ID映射(使用索引作为设备ID)
|
||||
camera_id_mapping = {i: cam_id for i, cam_id in enumerate(camera_ids)}
|
||||
|
||||
# 摄像头翻转参数(根据实际安装方向调整)
|
||||
flip_methods = [0, 0, 0, 0] # 0:不翻转, 1:水平翻转, 2:垂直翻转, 3:水平+垂直
|
||||
|
||||
# 加载相机内参模型
|
||||
yamls_dir = os.path.join(os.getcwd(), "yaml")
|
||||
camera_files = [os.path.join(yamls_dir, name + ".yaml") for name in settings.camera_names]
|
||||
camera_models = [FisheyeCameraModel(camera_file, name)
|
||||
for camera_file, name in zip(camera_files, settings.camera_names)]
|
||||
|
||||
# 初始化捕获线程(针对RTSP特殊处理)
|
||||
capture_tds = []
|
||||
for idx, (cam_id, flip) in enumerate(zip(camera_ids, flip_methods)):
|
||||
# 使用索引作为设备ID,解决KeyError问题
|
||||
if is_rtsp_url(cam_id):
|
||||
# RTSP流配置(使用FFmpeg后端)
|
||||
capture_tds.append(CaptureThread(
|
||||
device_id=idx, # 使用索引作为设备ID
|
||||
flip_method=flip,
|
||||
use_gst=False, # 关闭GStreamer,使用FFmpeg
|
||||
api_preference=cv2.CAP_FFMPEG, # 强制使用FFmpeg
|
||||
resolution=(960, 640)
|
||||
))
|
||||
# 手动打开RTSP流
|
||||
if not capture_tds[-1].cap.open(cam_id, cv2.CAP_FFMPEG):
|
||||
print(f"无法打开RTSP流: {cam_id}")
|
||||
return
|
||||
# 设置RTSP参数(兼容不同OpenCV版本)
|
||||
try:
|
||||
# 尝试通用参数设置方式
|
||||
capture_tds[-1].cap.set(cv2.CAP_PROP_BUFFERSIZE, 1) # 减少缓冲
|
||||
capture_tds[-1].cap.set(cv2.CAP_PROP_FRAME_WIDTH, 960)
|
||||
capture_tds[-1].cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 640)
|
||||
# 处理FFMPEG选项(兼容旧版本)
|
||||
if hasattr(cv2, 'CAP_PROP_FFMPEG_OPTION'):
|
||||
capture_tds[-1].cap.set(cv2.CAP_PROP_FFMPEG_OPTION, "rtsp_transport", "tcp")
|
||||
capture_tds[-1].cap.set(cv2.CAP_PROP_FFMPEG_OPTION, "stimeout", "5000000")
|
||||
else:
|
||||
print(f"RTSP流 {cam_id} 使用兼容模式,部分参数可能无法设置")
|
||||
except Exception as e:
|
||||
print(f"设置RTSP参数警告: {e}")
|
||||
else:
|
||||
# 普通USB/CSI相机配置
|
||||
capture_tds.append(CaptureThread(
|
||||
device_id=idx, # 使用索引作为设备ID
|
||||
flip_method=flip,
|
||||
use_gst=True,
|
||||
resolution=(960, 640)
|
||||
))
|
||||
if not capture_tds[-1].connect_camera():
|
||||
print(f"启动摄像头 {cam_id} 失败,退出程序")
|
||||
return
|
||||
|
||||
# 绑定捕获缓冲区管理器
|
||||
capture_buffer_manager = MultiBufferManager()
|
||||
for td in capture_tds:
|
||||
capture_buffer_manager.bind_thread(td, buffer_size=8)
|
||||
td.start()
|
||||
|
||||
# 初始化处理线程(使用索引作为device_id)
|
||||
proc_buffer_manager = ProjectedImageBuffer()
|
||||
process_tds = [
|
||||
CameraProcessingThread(
|
||||
capture_buffer_manager,
|
||||
device_id=idx, # 使用索引作为设备ID
|
||||
camera_model=model
|
||||
)
|
||||
for idx, model in enumerate(camera_models)
|
||||
]
|
||||
|
||||
# 启动处理线程
|
||||
for td in process_tds:
|
||||
proc_buffer_manager.bind_thread(td)
|
||||
td.start()
|
||||
|
||||
# 初始化环视拼接
|
||||
birdview = BirdView(proc_buffer_manager)
|
||||
birdview.load_weights_and_masks("./weights.png", "./masks.png")
|
||||
birdview.start()
|
||||
|
||||
# 主循环显示
|
||||
try:
|
||||
while True:
|
||||
birdview_img = birdview.get()
|
||||
if birdview_img is not None:
|
||||
display_img = cv2.resize(birdview_img, (800, 600))
|
||||
cv2.imshow("Surround View", display_img)
|
||||
|
||||
key = cv2.waitKey(1) & 0xFF
|
||||
if key == ord("q"):
|
||||
break
|
||||
|
||||
# 打印帧率信息
|
||||
status = []
|
||||
for td in capture_tds:
|
||||
cam_id = camera_id_mapping[td.device_id]
|
||||
status.append(f"捕获 {cam_id.split('@')[-1].split(':')[0]} FPS: {td.stat_data.average_fps:.1f}")
|
||||
for td in process_tds:
|
||||
cam_name = settings.camera_names[td.device_id]
|
||||
status.append(f"处理 {cam_name} FPS: {td.stat_data.average_fps:.1f}")
|
||||
status.append(f"全景 FPS: {birdview.stat_data.average_fps:.1f}")
|
||||
print(" | ".join(status), end="\r")
|
||||
|
||||
finally:
|
||||
for td in process_tds:
|
||||
td.stop()
|
||||
for td in capture_tds:
|
||||
td.stop()
|
||||
td.disconnect_camera()
|
||||
birdview.stop()
|
||||
cv2.destroyAllWindows()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user