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

OpenCV无法同时开启4台USB摄像头问题求助

USB四摄像头同时开启时第四台无画面的解决方案

问题重现

通过USB集线器连接/dev/video4、/dev/video6、/dev/video8、/dev/video10四台USB摄像头,单独或同时开启三台均正常工作,但同时开启四台时第四台无法捕获画面。使用的OpenCV代码如下:

#include <opencv2/opencv.hpp>
int main()
{
    cv::VideoCapture cap1(10, cv::CAP_V4L);
    cap1.set(cv::CAP_PROP_FRAME_WIDTH, 352);
    cap1.set(cv::CAP_PROP_FRAME_HEIGHT, 288);
    cap1.set(cv::CAP_PROP_FOURCC, cv::VideoWriter::fourcc('M', 'J', 'P', 'G'));

    cv::VideoCapture cap2(8, cv::CAP_V4L);
    cap2.set(cv::CAP_PROP_FRAME_WIDTH, 352);
    cap2.set(cv::CAP_PROP_FRAME_HEIGHT, 288);
    cap2.set(cv::CAP_PROP_FOURCC, cv::VideoWriter::fourcc('M', 'J', 'P', 'G'));

    cv::VideoCapture cap3(6, cv::CAP_V4L2);
    cap3.set(cv::CAP_PROP_FRAME_WIDTH, 352);
    cap3.set(cv::CAP_PROP_FRAME_HEIGHT, 288);
    cap3.set(cv::CAP_PROP_FOURCC, cv::VideoWriter::fourcc('M', 'J', 'P', 'G'));

    cv::VideoCapture cap4(4, cv::CAP_V4L2);
    cap4.set(cv::CAP_PROP_FRAME_WIDTH, 352);
    cap4.set(cv::CAP_PROP_FRAME_HEIGHT, 288);
    cap4.set(cv::CAP_PROP_FOURCC, cv::VideoWriter::fourcc('M', 'J', 'P', 'G'));
    while (true)
    {
        cv::Mat img1, img2, img3, img4;
        cap1.grab();
        cap1.retrieve(img1);
        cap2.grab();
        cap2.retrieve(img2);
        cap3.grab();
        cap3.retrieve(img3);
        cap4.grab();
        cap4.retrieve(img4);
        
        if (img1.cols > 0)
        {
            cv::imshow("1", img1);
            cv::waitKey(50);
        }
        if (img2.cols > 0)
        {
            cv::imshow("2", img2);
            cv::waitKey(50);
        }
        if (img3.cols > 0)
        {
            cv::imshow("3", img3);
            cv::waitKey(50);
        }
        if (img4.cols > 0)
        {
            cv::imshow("4", img4);
            cv::waitKey(50);
        }

    }

    return 1;
}

核心原因分析

  1. USB带宽瓶颈:USB集线器带宽共享,即使使用MJPEG压缩,四台摄像头同时传输的总带宽可能超过USB总线实际可用上限(尤其是USB 2.0总线)。
  2. 代码阻塞问题:循环中每个imshow后调用waitKey(50)导致程序频繁阻塞,摄像头帧捕获线程无法及时获取数据,最终引发第四台摄像头超时无输出。
  3. 后端API混用:代码中混用CAP_V4L和CAP_V4L2后端,存在兼容性冲突风险。
  4. 供电不足:无外接电源的USB集线器可能无法为四台摄像头提供足够电力,导致第四台无法正常启动。

解决方案

1. 优化USB带宽占用

  • 降低帧率:为每个摄像头设置更低帧率,减少数据传输量:
    cap1.set(cv::CAP_PROP_FPS, 10);
    cap2.set(cv::CAP_PROP_FPS, 10);
    cap3.set(cv::CAP_PROP_FPS, 10);
    cap4.set(cv::CAP_PROP_FPS, 10);
    
  • 进一步降低分辨率:尝试320x240或更低分辨率,减少单帧数据大小。
  • 确认MJPEG格式生效:部分摄像头可能不支持强制设置MJPEG,会 fallback 到YUYV等未压缩格式,可通过以下命令查看摄像头支持的格式:
    v4l2-ctl --list-formats-ext /dev/video4
    
    也可在代码中通过cap.get(cv::CAP_PROP_FOURCC)验证格式是否设置成功。

2. 修复代码阻塞问题

将waitKey移到循环末尾,仅调用一次,避免频繁阻塞:

while (true)
{
    cv::Mat img1, img2, img3, img4;
    bool success1 = cap1.grab() && cap1.retrieve(img1);
    bool success2 = cap2.grab() && cap2.retrieve(img2);
    bool success3 = cap3.grab() && cap3.retrieve(img3);
    bool success4 = cap4.grab() && cap4.retrieve(img4);
    
    if (success1) cv::imshow("1", img1);
    if (success2) cv::imshow("2", img2);
    if (success3) cv::imshow("3", img3);
    if (success4) cv::imshow("4", img4);

    // 仅在循环末尾处理窗口事件,按ESC退出
    if (cv::waitKey(1) == 27) break;
}

3. 统一使用V4L2后端

将所有VideoCapture的后端统一改为cv::CAP_V4L2,避免API混用的兼容性问题:

cv::VideoCapture cap1(10, cv::CAP_V4L2);
cv::VideoCapture cap2(8, cv::CAP_V4L2);
cv::VideoCapture cap3(6, cv::CAP_V4L2);
cv::VideoCapture cap4(4, cv::CAP_V4L2);

4. 检查集线器供电与带宽

  • 使用带外接电源的USB 3.0集线器:USB 3.0提供更高带宽(5Gbps)和更稳定的供电,能更好支持多摄像头同时工作。
  • 若使用USB 2.0集线器,确保总带宽不超总线限制:USB 2.0理论带宽480Mbps,实际可用约300-400Mbps,MJPEG格式下352x288@10fps单摄像头约3-5Mbps,四台总带宽远低于限制,但集线器质量差可能导致实际可用带宽不足。

5. 添加错误检查

在代码中添加摄像头初始化和帧捕获的错误检查,便于排查问题:

if (!cap1.isOpened()) {
    std::cerr << "Failed to open /dev/video10" << std::endl;
    return -1;
}
if (!cap2.isOpened()) {
    std::cerr << "Failed to open /dev/video8" << std::endl;
    return -1;
}
if (!cap3.isOpened()) {
    std::cerr << "Failed to open /dev/video6" << std::endl;
    return -1;
}
if (!cap4.isOpened()) {
    std::cerr << "Failed to open /dev/video4" << std::endl;
    return -1;
}

6. 调整摄像头初始化顺序

尝试改变摄像头初始化顺序,比如先初始化/dev/video4,避免总线冲突:

cv::VideoCapture cap4(4, cv::CAP_V4L2);
cv::VideoCapture cap3(6, cv::CAP_V4L2);
cv::VideoCapture cap2(8, cv::CAP_V4L2);
cv::VideoCapture cap1(10, cv::CAP_V4L2);

内容的提问来源于stack exchange,提问作者HC S

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 08:14:51