如何使用OpenCV在同一窗口中显示多路摄像头实时画面
OpenCV多路摄像头实时画面同窗口拼接方案
核心实现逻辑
- 预先设定所有摄像头输出的统一分辨率,避免逐帧调整尺寸带来的性能损耗
- 每次循环同步读取所有摄像头的帧数据,做尺寸归一化处理
- 按照预设的网格排列规则,将多帧画面拼接为单张大图
- 输出拼接后的大图到单个窗口,保证实时帧率稳定
可运行示例代码
import cv2 import numpy as np def main(): # 配置参数:按实际摄像头数量调整 CAMERA_COUNT = 3 # 摄像头总路数 TARGET_SIZE = (320, 240) # 每个摄像头画面的统一尺寸(宽,高) # 自动计算拼接网格的行列数 cols = int(np.ceil(np.sqrt(CAMERA_COUNT))) rows = int(np.ceil(CAMERA_COUNT / cols)) # 初始化所有摄像头 caps = [] for i in range(CAMERA_COUNT): cap = cv2.VideoCapture(i) # 预先设置摄像头输出分辨率,减少后续resize开销 cap.set(cv2.CAP_PROP_FRAME_WIDTH, TARGET_SIZE[0]) cap.set(cv2.CAP_PROP_FRAME_HEIGHT, TARGET_SIZE[1]) if not cap.isOpened(): print(f"摄像头{i}打开失败,跳过该设备") continue caps.append(cap) # 更新实际可用的摄像头数量 valid_cam_count = len(caps) if valid_cam_count == 0: print("无可用摄像头") return while True: frames = [] # 读取所有摄像头的帧 for cap in caps: ret, frame = cap.read() if not ret: # 读取失败的话用黑帧占位 frame = np.zeros((TARGET_SIZE[1], TARGET_SIZE[0], 3), dtype=np.uint8) else: # 保证尺寸统一 frame = cv2.resize(frame, TARGET_SIZE) frames.append(frame) # 补全空白帧填满网格 for _ in range(rows * cols - valid_cam_count): frames.append(np.zeros((TARGET_SIZE[1], TARGET_SIZE[0], 3), dtype=np.uint8)) # 按行拼接 row_frames = [] for r in range(rows): start = r * cols end = start + cols row = np.hstack(frames[start:end]) row_frames.append(row) # 按列拼接所有行得到最终画面 final_frame = np.vstack(row_frames) # 展示拼接后的画面 cv2.imshow("多路摄像头拼接画面", final_frame) # 按q键退出 if cv2.waitKey(1) & 0xFF == ord('q'): break # 释放资源 for cap in caps: cap.release() cv2.destroyAllWindows() if __name__ == "__main__": main()
注意事项
- 部分USB摄像头对连续设置分辨率参数的兼容性较差,如果出现摄像头打开失败的情况,可以注释掉
cap.set相关代码,仅靠后续cv2.resize做尺寸统一即可 - 摄像头数量较多时建议降低单路画面的
TARGET_SIZE,可以有效提升实时帧率 - 如果需要自定义排列规则,直接修改
cols和rows参数即可,比如设置cols=CAMERA_COUNT就可以实现所有画面横向排列
内容的提问来源于stack exchange,提问作者zhizha
相关产品推荐
相关产品推荐

