在Linux上使用OpenCV捕获多个网络摄像头(uvcvideo)

gee*_*eez 12 webcam opencv v4l2

我试图在Ubuntu 11.10上使用OpenCV 2.1同时从3台Logitech Webcam Pro 900设备流式传输图像.uvcvideo驱动程序会加载这些.

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

libv4l2: error turning on stream: No space left on device
Run Code Online (Sandbox Code Playgroud)

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

cv::VideoCapture cap0(0); //(0,1,2..)
Run Code Online (Sandbox Code Playgroud)

并尝试捕获循环中的所有摄像机

cap0.retrieve(frame0);
Run Code Online (Sandbox Code Playgroud)

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

现在变得很大但是:在通过启动三个实例尝试guvcview之后,我能够同时查看三个摄像头(在帧速率或相关方面没有问题),因此它似乎不是硬件问题.我认为我应该设置一些属性,但我不确定那是什么.我已经研究了MJPEG(这些相机似乎支持),但是没有成功设置这个属性,或者检测它们在运行时是从OpenCV启动它们的模式(yuyv?).

思考?

小智 10

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

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

我没有研究如何使用OpenCV更改图像格式,但我知道它需要MJPEG来适应所有数据.

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


Aco*_*orn 10

我也有这个问题并且有一个解决方案,让我可以使用mjpeg压缩捕获640x480的2个摄像头.我正在使用Creative"Live Cam Sync HD VF0770",它错误地报告了其带宽要求.quirks = 128 fix适用于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
Run Code Online (Sandbox Code Playgroud)

复制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 .
Run Code Online (Sandbox Code Playgroud)

修改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
Run Code Online (Sandbox Code Playgroud)

压缩时强制带宽为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;
      }
Run Code Online (Sandbox Code Playgroud)

构建aauvcvideo模块:

make
Run Code Online (Sandbox Code Playgroud)

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

sudo rmmod uvcvideo
sudo insmod ./aauvcvideo.ko quirks=128
Run Code Online (Sandbox Code Playgroud)

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

guvcview --device=/dev/video1 --format=mjpg --size=640x480
guvcview --device=/dev/video2 --format=mjpg --size=640x480
Run Code Online (Sandbox Code Playgroud)

祝好运!-Acorn

  • 解决相机问题的内核黑客应该得到一个upvote.:)我[阅读](http://www.ideasonboard.org/uvc/#footnote-13)FIX_BANDWIDTH怪癖只影响未压缩的格式,与您的答案相匹配.有趣的是,虽然`v4l2-ctl -d 0 -V`声称像素格式'MJPG',但是我使用基于OpenCV的代码时,这个怪癖[为我工作](http://stackoverflow.com/a/34778270/1628638)从多个摄像头捕获. (3认同)
  • 这次真是万分感谢。要添加更多信息,以下是我在基于 debian 的设备上执行此操作的方法: # apt-get source linux-image # tar xf <file> # cd linux-image # cp /lib/modules/<适当的 dir>/build/Module.symvers 。# make oldconfig # make prepare # make scripts # [EDIT AS ABOVE in drivers/media/usb/uvc] # make SUBDIRS=drivers/media/usb/uvc/modules (2认同)

sud*_*dar 7

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

v4l2-ctl -d /dev/video0 --list-formats
Run Code Online (Sandbox Code Playgroud)

输出将如下所示:

ioctl: VIDIOC_ENUM_FMT
    Index       : 0
    Type        : Video Capture
    Pixel Format: 'YUYV'
    Name        : 16bpp YUY2, 4:2:2, packed
Run Code Online (Sandbox Code Playgroud)

以下是可能的解决方案:

  1. 使用来自不同制造商的捕获设备,以便加载的驱动程序不同.通常,处理多个设备的相同驱动程序需要有效地处理带宽.
  2. 如果可用,请使用PCI USB扩展卡连接第二个USB视频捕获设备.当我尝试连接加载了驱动程序cx231xx的AVerMedia DVD EZMaker 7时,这种解决方法对我来说非常有效.