Захват нескольких веб-камер (uvcvideo) с OpenCV в Linux - PullRequest
11 голосов
/ 20 марта 2012

Я пытаюсь одновременно передавать изображения с 3 устройств Logitech Webcam Pro 900, используя OpenCV 2.1 в Ubuntu 11.10.Драйвер uvcvideo загружается для них.

Захват двух устройств работает нормально, однако с тремя я сталкиваюсь с ошибкой нехватки места для третьего:

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

Я, кажется, сталкиваюсь сэта проблема: 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..)

и пытаюсь захватить все камеры в цикле как

cap0.retrieve(frame0);

Это отлично работает для N = 2 камер.Когда я устанавливаю N = 3, открывается третье окно, но изображение не появляется, и на консоли появляется спам, полный ошибок V4L2.Точно так же, когда я устанавливаю N = 2 и пытаюсь открыть третью камеру, скажем, Cheese (простое приложение для захвата веб-камеры), это тоже не работает.

Теперь приходит большое но: После попытки guvcview, запустивВ трех случаях я мог просматривать три камеры одновременно (без проблем с точки зрения частоты кадров или связанных с ними), так что это не похоже на аппаратную проблему.Я полагаю, что есть какое-то свойство, которое я должен установить, но я не уверен, что это такое.Я изучил MJPEG (который эти камеры поддерживают), но мне не удалось установить это свойство или определить, в каком режиме (yuyv?) Они работают, если я запускаю их из OpenCV.

Мысли

Ответы [ 7 ]

9 голосов
/ 27 мая 2014

У меня тоже была эта проблема, и у меня есть решение, позволяющее мне снимать 2 камеры с разрешением 640x480 со сжатием mjpeg.Я использую Creative Live 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

copy uvc dir:

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;
      }

buildмодуль aauvcvideo:

make

удалить старый модуль и вставить новый:

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

дважды запустить gucview со сжатием в 2 разных окнах для проверки

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

Удачи!-Acorn

9 голосов
/ 27 апреля 2012

У меня была именно эта проблема, при использовании трех камер Logitech Quickcam Pro 9000 (с использованием Ubuntu).Я мог читать с двух, но не с трех.В моем случае я не использовал opencv, но обращался к камерам напрямую через V4L2, используя отображенный в памяти ввод-вывод.Проще говоря, пропускной способности USB было недостаточно для выделения трех буферов.

Однако я читал в несжатых кадрах.Как только я переключил формат на MJPEG, данные были достаточно малы, и я мог читать с трех камер.Я использовал libjpeg для декодирования потока MJPEG.

Я не изучал, как изменить формат изображения с помощью OpenCV, но я знаю, что это должен быть MJPEG, чтобы соответствовать всем этим данным.

Прежде чем перейти на MJPEG, я потратил много времени, пытаясь получить доступ к каждой камере по одному, передавая один кадр перед переключением на следующий.Не рекомендуется!

6 голосов
/ 31 мая 2013

Скорее всего, существует конфликт пропускной способности 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. Используйте карту расширения USB USB, если она доступна, для подключения второго устройства видеозахвата USB. Этот обходной путь отлично работал для меня, когда я пытался подключить AVerMedia DVD EZMaker 7, который загружал драйвер cx231xx.
4 голосов
/ 02 февраля 2016

OpenCV может быть построен для использования v4l или libv4l , и только версия v4l поддерживает сжатые форматы, в то время как версия libv4l поддерживает только один несжатый формат для OpenCV 2.4.11. (См. autosetup_capture_mode_v4l2 () для v4l и код, следующий за строкой 692 для libv4l.) OpenCV 3.0.0 здесь не намного улучшается по сравнению с 2.4.11; он все еще поддерживает только несжатые форматы для libv4l.

Поскольку в вашей ошибке упоминается libv4l2, у вас, похоже, версия libv4l и OpenCV записаны несжатыми в вашем случае. Чтобы создать версию OpenCV v4l, ваша команда cmake должна содержать

-D WITH_LIBV4L=OFF

(WITH_LIBV4L был включен по умолчанию для меня.)

Примечание о пропускной способности и USB. USB 2.0 (который используют практически все веб-камеры) имеет пропускную способность 480 Мбит / с. 640x480 при 30 кадрах в секунду и 24 бит / пиксель без сжатия составляет около 221 Мбит / с, поэтому можно быстро использовать пропускную способность USB 2.0 с несжатыми веб-камерами. Каждый получает 480 Мбит / с для каждого хост-контроллера USB , см. ответ о том, как их перечислить. (Концентраторы USB не добавляют хост-контроллеры, и несколько USB-портов на материнской плате обычно подключаются к одному хост-контроллеру. Все устройства и концентраторы, подключенные к хост-контроллеру, совместно используют пропускную способность.)

Для веб-камер, которые резервируют большую пропускную способность USB, чем им требуется, например, с сноской [13] на странице драйвера UVC , может FIX_BANDWIDTH quirk Помогите. Но эта хитрость работает только для несжатых форматов (если вы не сделаете взлом ядра в ответе Acorn здесь). В моем случае (Ubuntu 14.04, многие кинотеатры Microsoft LifeCam с разрешением 320x240) эта причуда сработала, когда я использовал версию OpenCV libv4l (четыре LifeCams на хост-контроллере ASMedia USB работали хорошо), но для версии v4l, которую я подтвердил использовать MJPEG - Я получил ошибку VIDIOC_STREAMON: No space left on device, как только я попытался захватить со второй LifeCam! (Для той же машины хост-контроллеры Intel и VIA работали лучше, и каждый работал с двумя LifeCam для v4l; LifeCam резервирует 48% пропускной способности USB 2.0.)

1 голос
/ 23 октября 2014

это работает как шарм для меня

sudo rmmod uvcvideo

sudo modprobe uvcvideo quirks = 128

Это будет сбрасываться при каждой перезагрузке. Если это работает, создайте следующий файл: sudo vi /etc/modprobe.d/uvcvideo.conf содержащий строку: Опции Uvcvideo Quirks = 128

проверьте эту ссылку http://renoirsrants.blogspot.in/2011/07/multiple-webcams-on-zoneminder.html

0 голосов
/ 28 сентября 2018

С ядром 4.15.0-34-generic в Ubuntu 18.04 и OpenCV 3.4, скомпилированным с поддержкой gstreamer / v4l, я могу транслировать 3x720p через один USB-порт, используя концентратор с питанием, используя сжатие MJPG с gstreamer в python (используя 2xC922 и Камеры 1xC920 - частота кадров 10 к / с не нужна для этого):

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)
0 голосов
/ 23 октября 2012

Одна из самых полезных вещей, которые я обнаружил, заключалась в том, что вы помещаете вызов Sleep (ms) между инициализацией захвата. Это позволило мне без проблем получить два снимка с веб-камеры одновременно.

...