You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 15:15:03