15

我正在尝试在 Ubuntu 11.10 上使用 OpenCV 2.1 同时流式传输来自 3 个 Logitech Webcam Pro 900 设备的图像。为这些加载了 uvcvideo 驱动程序。

捕获两个设备工作正常,但是三个我遇到第三个空间不足错误:

libv4l2: error turning on stream: No space left on device

我似乎遇到了这个问题: http ://renoirsrants.blogspot.com.au/2011/07/multiple-webcams-on-zoneminder.html我试图做 quirks=128 (或几乎任何其他二次幂)技巧,但无济于事。我还尝试在另一台带有两个 USB 2.0 集线器的机器上将两个摄像头连接到一个,将第三个摄像头连接到第二个,这导致了同样的问题。我大致如下初始化(使用 N 个摄像头,因此结果实际上被放入 STL 向量中):

cv::VideoCapture cap0(0); //(0,1,2..)

并尝试将所有摄像机循环捕获为

cap0.retrieve(frame0);

这适用于 N=2 相机。当我设置 N=3 时,第三个窗口打开但没有图像出现,并且控制台充满了 V4L2 错误。同样,当我设置 N=2 并尝试在说 Cheese(简单的网络摄像头捕获应用程序)中打开第三个摄像头时,这也不起作用。

现在来了个大问题:通过启动三个实例尝试 guvcview 后,我能够一次查看三个摄像头(在帧速率或相关方面没有问题),所以这似乎不是硬件问题。我认为我应该设置一些属性,但我不确定那是什么。我已经研究了 MJPEG(这些相机似乎支持),但没有成功设置这个属性,或者如果我从 OpenCV 启动它们,它们在哪种模式下运行(yuyv?)。

想法?

4

7 回答 7

14

我也遇到了这个问题,并且有一个解决方案可以让我使用 mjpeg 压缩捕捉 2 个 640x480 的摄像机。我正在使用 Creative “Live Cam Sync HD VF0770”,它错误地报告了它的带宽要求。quirks=128 修复适用于 320x240 未压缩视频。但是对于压缩(mjpg)格式,quirks=128 不起作用(它对压缩格式没有任何作用)。

为了解决这个问题,我修改了 uvc 驱动程序如下:

下载内核源代码

mkdir -p ~/Software/kernel-git
cd ~/Software/kernel-git
git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
git checkout v3.2
# NOTE: `uname -r`  shows me my current kernel is 3.2.0-60-generic
# For a different kernel use a different tag

复制 uvc 目录:

mkdir -p ~/Software/uvcvideo_driver
cd ~/Software/uvcvideo_driver
#cp -a ~/Software/kernel-git/linux/drivers/media/usb/uvc .
cp ~/Software/kernel-git/linux/drivers/media/video/uvc .

修改 Makefile

cd ~/Software/uvcvideo_driver/uvc
vi Makefile

        obj-m += aauvcvideo.o
        aauvcvideo-objs  := uvc_driver.o uvc_queue.o uvc_v4l2.o uvc_video.o uvc_ctrl.o \
              uvc_status.o uvc_isight.o
        all:
          make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

        clean:
          make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

压缩时强制带宽为 0x400。

cd ~/Software/uvcvideo_driver/uvc
vw uvc_video.c
Find the uvc_fixup_video_ctrl() function.  At the end of the function add:
      if (format->flags & UVC_FMT_FLAG_COMPRESSED) {
        ctrl->dwMaxPayloadTransferSize = 0x400;
      }

构建 aauvcvideo 模块:

make

删除旧模块并插入新模块:

sudo rmmod uvcvideo
sudo insmod ./aauvcvideo.ko quirks=128

在 2 个不同的窗口中使用压缩运行 gucview 两次以进行测试

guvcview --device=/dev/video1 --format=mjpg --size=640x480
guvcview --device=/dev/video2 --format=mjpg --size=640x480

祝你好运!-橡子

于 2014-05-27T04:33:14.817 回答
10

我有这个确切的问题,使用三个罗技 quickcam pro 9000 相机(使用 ubuntu)。我可以读两个,但不是三个。就我而言,我没有使用 opencv,而是使用内存映射 IO 直接通过 V4L2 访问相机。简而言之,没有足够的 USB 带宽来分配三个缓冲区。

但是,我正在阅读未压缩的帧。一旦我将格式切换为 MJPEG,数据就足够小了,我可以从三个摄像头读取数据。我使用 libjpeg 来解码 MJPEG 流。

我还没有研究如何使用 OpenCV 更改图像格式,但我知道它需要 MJPEG 才能适应所有这些数据。

在切换到 MJPEG 之前,我花了很多时间尝试一次访问每个摄像机,在切换到下一帧之前流式传输单个帧。不建议!

于 2012-04-27T15:37:38.910 回答
8

很可能存在由视频捕获设备的驱动程序报告的 USB 带宽争用。检查像素格式是否为YUYV,恰好是未压缩的。相反,如果像素格式为 MJPG(压缩),则可能有多个设备在同一个 USB 通道上。

v4l2-ctl -d /dev/video0 --list-formats

输出将如下所示:

ioctl: VIDIOC_ENUM_FMT
    Index       : 0
    Type        : Video Capture
    Pixel Format: 'YUYV'
    Name        : 16bpp YUY2, 4:2:2, packed

以下是可能的解决方案:

  1. 使用来自不同制造商的捕获设备,以便加载的驱动程序不同。通常,处理多个设备的同一个驱动程序需要有效地处理带宽。
  2. 如果可用,请使用 PCI USB 扩展卡连接第二个 USB 视频捕获设备。当我尝试连接加载驱动程序 cx231xx 的 AVerMedia DVD EZMaker 7 时,此解决方法对我非常有效。
于 2013-05-31T06:53:38.893 回答
4

OpenCV 可以构建为使用v4llibv4l,并且只有 v4l 版本支持压缩格式,而 libv4l 版本仅支持 OpenCV 2.4.11 的一种未压缩格式。(对于 v4l,请参见autosetup_capture_mode_v4l2(),对于 libv4l,请参见第 692 行之后的代码。)OpenCV 3.0.0 在这里并没有比 2.4.11 改进太多;它仍然只支持 libv4l 的未压缩格式。

由于您的错误提到libv4l2,您的情况似乎有 libv4l 版本和 OpenCV 未压缩捕获。要构建 v4l 版本的 OpenCV,您的 cmake 命令应包含

-D WITH_LIBV4L=OFF

WITH_LIBV4L默认为我启用。)

关于带宽和 USB 的说明。USB 2.0(几乎所有网络摄像头都使用)的带宽为 480 Mbit/s。30 fps 和 24 位/像素未压缩的 640x480 约为 221 Mbit/s,因此使用未压缩的网络摄像头可以快速耗尽 USB 2.0 带宽。每个 USB主机控制器可获得 480 Mbit/s ,请参阅此答案以了解如何列出它们。(USB集线器不添加主机控制器,主板上的多个 USB 端口通常连接到同一个主机控制器。连接到主机控制器的所有设备和集线器共享带宽。)

对于预留比所需更多 USB 带宽的网络摄像头,例如,在UVC 驱动程序页面上有脚注 [13]的网络摄像头, FIX_BANDWIDTH怪癖可以提供帮助。但是这个怪癖仅适用于未压缩的格式(除非您在 Acorn 的答案中进行内核破解)。在我的情况下(Ubuntu 14.04,许多 Microsoft LifeCam Cinemas at 320x240),当我使用 OpenCV 的 libv4l 版本(ASMedia USB 主机控制器上的四个 LifeCam 运行良好)但对于 v4l 版本时,这个怪癖起作用了——我确认使用MJPEG——当我尝试从第二个 LifeCam 捕捉时出现错误!(对于同一台机器,Intel 和 VIA 主机控制器表现更好,每个都与两个 LifeCam 配合使用 v4l;LifeCam 保留了 48% 的 USB 2.0 带宽。)VIDIOC_STREAMON: No space left on device

于 2016-02-02T19:00:44.423 回答
1

这对我很有魅力

sudo rmmod uvcvideo

sudo modprobe uvcvideo 怪癖=128

这将在每次重新启动时重置。如果可行,请创建以下文件:sudo vi /etc/modprobe.d/uvcvideo.conf 包含以下行:options uvcvideo quirks=128

检查此链接 http://renoirsrants.blogspot.in/2011/07/multiple-webcams-on-zoneminder.html

于 2014-10-23T07:37:04.510 回答
1

使用 Ubuntu 18.04 上的内核 4.15.0-34-generic 和使用 gstreamer/v4l 支持编译的 OpenCV 3.4,我能够使用供电集线器在单个 USB 端口上流式传输 3x720p,并在 python 中使用带有 gstreamer 的 MJPG 压缩(使用 2xC922 和 1xC920 相机 -不需要 10fps 的帧率来工作):

def open_cam_usb(dev, width, height):
    gst_str = (
        "v4l2src device=/dev/video{} ! "
        "image/jpeg,widh=(int){},height=(int){},framerate=10/1,"
        "format=(string)RGB ! "
        "jpegdec ! videoconvert ! appsink"
    ).format(dev, width, height)
    return cv2.VideoCapture(gst_str, cv2.CAP_GSTREAMER)
于 2018-09-28T08:38:08.973 回答
0

我发现的最有用的事情之一是,如果您在捕获初始化之间放置一个 Sleep(ms) 调用。这使我可以毫无问题地同时检索两个网络摄像头捕获。

于 2012-10-23T18:58:28.677 回答