-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathstereo_stream.py
More file actions
87 lines (74 loc) · 2.48 KB
/
Copy pathstereo_stream.py
File metadata and controls
87 lines (74 loc) · 2.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import cv2
import numpy as np
from picamera2 import Picamera2
import subprocess
import time
import sys
# --- 1. 硬件与推流配置 ---
WIDTH, HEIGHT = 640, 480
FPS = 20
LISTEN_PORT = "8888"
print("正在启动双目相机...")
# --- 2. 初始化相机 ---
# 初始化两个相机实例 (0 是 CAM0, 1 是 CAM1)
cam0 = Picamera2(0)
cam1 = Picamera2(1)
# 配置基础参数
config = cam0.create_preview_configuration(main={"format": "RGB888", "size": (WIDTH, HEIGHT)})
# 如果你发现左右反了,可以在这里调整 cam0 和 cam1 的编号
cam0.configure(config)
cam1.configure(config)
# 启动相机
cam0.start()
cam1.start()
# --- 3. 设置 FFmpeg 推流管道 ---
# 拼接后的总宽度是单张图的两倍 (1280x480)
# 我们使用 libx264 编码,并开启 zerolatency 模式以降低延迟
command = [
'ffmpeg',
'-y',
'-f', 'rawvideo',
'-vcodec', 'rawvideo',
'-pix_fmt', 'bgr24',
'-s', f"{WIDTH*2}x{HEIGHT}",
'-r', str(FPS),
'-i', '-', # 从管道读取输入
'-c:v', 'libx264',
'-preset', 'ultrafast',
'-tune', 'zerolatency',
'-f', 'mpegts',
f'tcp://0.0.0.0:{LISTEN_PORT}?listen' # 监听模式,等待 Mac 连接
]
# 启动 FFmpeg 子进程
try:
pipe = subprocess.Popen(command, stdin=subprocess.PIPE)
print(f"\n🚀 推流已就绪!")
print(f"请在 Mac 播放器 (IINA/VLC) 中打开 URL:")
print(f"👉 tcp://你的树莓派IP:{LISTEN_PORT}")
print("\n按 Ctrl+C 停止运行")
while True:
# 4. 抓取并转换图像
frame0 = cam0.capture_array()
frame1 = cam1.capture_array()
# Picamera2 出来的是 RGB,OpenCV 习惯 BGR
img0 = cv2.cvtColor(frame0, cv2.COLOR_RGB2BGR)
img1 = cv2.cvtColor(frame1, cv2.COLOR_RGB2BGR)
# 5. 横向拼接
combined = cv2.hconcat([img0, img1])
# 可选:在画面上加个简单的 OSD 文字(方便确认左右)
# cv2.putText(combined, "CAM0", (20, 40), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
# cv2.putText(combined, "CAM1", (WIDTH + 20, 40), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
# 6. 将处理好的帧塞进 FFmpeg 管道
pipe.stdin.write(combined.tobytes())
except KeyboardInterrupt:
print("\n用户中断,正在安全退出...")
except Exception as e:
print(f"\n发生错误: {e}")
finally:
# 7. 释放资源
if 'pipe' in locals():
pipe.stdin.close()
pipe.wait()
cam0.stop()
cam1.stop()
print("相机已关闭。")