Съемка видео с вебкамеры с помощью OpenCV в WSL2

Вопрос или проблема

Я пытаюсь получить доступ к своей веб-камере через OpenCV в WSL2 (Ubuntu). Я нашёл этот блог, где объясняется, как подключить USB-устройства к WSL2. Запуск usbipd wsl list в командной строке Windows показывает следующие устройства:

> usbipd wsl list
BUSID  VID:PID    УСТРОЙСТВО                                                       СОСТОЯНИЕ
1-1    0c45:6725  Интегрированная веб-камера                                        Не подключено
1-2    046d:c534  USB-устройство ввода                                             Не подключено
1-3    0cf3:e007  Bluetooth Qualcomm QCA61x4A                                      Не подключено
1-4    27c6:639c  Датчик отпечатков пальцев Goodix Moc                             Не подключено
2-2    8564:7000  USB-устройство массового хранения                                  Не подключено

Здесь интегрированная веб-камера моего устройства — это USB-устройство с BUSID 1-1. Я запустил usbipd wsl attach --busid 1-1, чтобы подключить свою интегрированную веб-камеру к WSL.

Теперь из WSL, введя lsusb, я вижу устройства следующим образом:

> lsusb
Шина 002 Устройство 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Шина 001 Устройство 003: ID 0c45:6725 Microdia Интегрированная_веб-камера_HD
Шина 001 Устройство 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

Похоже, что интегрированная веб-камера успешно подключена к WSL (в списке как Microdia Интегрированная_веб-камера_HD).

Вот код, используемый для доступа к веб-камере:

import cv2
import sys

source = cv2.VideoCapture(0)

win_name="Предпросмотр камеры"
cv2.namedWindow(win_name, cv2.WINDOW_NORMAL)

while cv2.waitKey(1) != 27:  # Escape
    has_frame, frame = source.read()
    if not has_frame:
        break
    cv2.imshow(win_name, frame)

source.release()
cv2.destroyWindow(win_name)

Здесь cv2.VideoCapture() принимает индекс в качестве аргумента. Документация OpenCV говорит:
doc

Если я запускаю приведенный выше код с 0 в качестве аргумента, я получаю следующий вывод:

[ WARN:[email protected]] global /io/opencv/modules/videoio/src/cap_v4l.cpp (889) open VIDEOIO(V4L2:/dev/video0): невозможно открыть камеру по индексу

Я подключил USB-устройства к WSL, но все еще не могу получить доступ к интегрированной веб-камере. Буду признателен за любые идеи, как обойти эту проблему!

Кратко: у меня была такая же проблема, этот GitHub, который кто-то упомянул в комментариях, сработал для меня:

https://github.com/PINTO0309/wsl2_linux_kernel_usbcam_enable_conf


Я потратил целый день, пробуя множество обходных путей, но это было единственное, что сработало для меня.

Я заранее знал, что это проблема, связанная с ядром WSL, потому что веб-камера прекрасно работала на виртуальной машине Ubuntu 22.04, запущенной на Virtual Box.

На странице GitHub не указано, но вам сначала потребуется:

1 – Установить usbipd-win

Вы можете следовать всем шагам здесь:
https://github.com/dorssel/usbipd-win/wiki/WSL-support

После того как вы сможете подключить устройство к WSL, И ОНО ПОКАЗЫВАЕТСЯ командой lsusb, вы можете следовать их руководству.

2 – Следуйте шагам, описанным в этом репозитории

https://github.com/PINTO0309/wsl2_linux_kernel_usbcam_enable_conf

Все, что они здесь описывают, вы можете сделать самостоятельно, следуя установке usbipd до конца, но большая разница в том, что они уже предварительно настроили файл .config для компиляции ядра, чтобы веб-камера заработала. (И это сработало для меня как по волшебству)


Я на Windows 11 Pro Build 22621, и моя веб-камера интегрированная, совместимая с uvcvideo, я опубликую полные характеристики здесь:

$ v4l2-ctl -d /dev/video0 --all

Информация о драйвере:
        Название драйвера : uvcvideo
        Тип карты        : Интегрированная_веб-камера_HD: Интеграция
        Информация о шине : usb-vhci_hcd.0-1
        Версия драйвера   : 5.15.90
        Возможности       : 0x84a00001
                Видео захват
                Захват метаданных
                Потоковая передача
                Расширенный пиксельный формат
                Возможности устройства
        Возможности устройства: 0x04200001
                Видео захват
                Потоковая передача
                Расширенный пиксельный формат
Приоритет: 2
Видеовход : 0 (Камера 1: ок)
Формат видео захвата:
        Ширина/Высота    : 640/480
        Пиксельный формат : 'MJPG' (Motion-JPEG)
        Поле             : Нет
        Байтов на строку  : 0
        Размер изображения  : 614989
        Цветовое пространство: По умолчанию
        Функция передачи  : По умолчанию (отображает на Rec. 709)
        YCbCr/HSV Кодирование: По умолчанию (отображает на ITU-R 601)
        Квантизация      : По умолчанию (отображает на полный диапазон)
        Флаги             :
Возможности обрезки видео захвата:
        Пределы      : Слева 0, Сверху 0, Ширина 640, Высота 480
        По умолчанию  : Слева 0, Сверху 0, Ширина 640, Высота 480
        Пиксельный аспект: 1/1
Выбор Видео захвата: crop_default, Слева 0, Сверху 0, Ширина 640, Высота 480, Флаги:
Выбор Видео захвата: crop_bounds, Слева 0, Сверху 0, Ширина 640, Высота 480, Флаги:
Параметры потоковой передачи видео захвата:
        Возможности     : времяперекрытие
        Кадры в секунду: 30.000 (30/1)
        Чтение буферов  : 0
                     яркость 0x00980900 (int)    : мин=-64 макс=64 шаг=1 по умолчанию=0 значение=0
                       контраст 0x00980901 (int)    : мин=0 макс=95 шаг=1 по умолчанию=0 значение=0
                     насыщенность 0x00980902 (int)    : мин=0 макс=100 шаг=1 по умолчанию=64 значение=64
                            оттенок 0x00980903 (int)    : мин=-2000 макс=2000 шаг=1 по умолчанию=0 значение=0
 автобаланс белого 0x0098090c (bool)   : по умолчанию=1 значение=1
                          гамма 0x00980910 (int)    : мин=100 макс=300 шаг=1 по умолчанию=100 значение=100
                           усиление 0x00980913 (int)    : мин=1 макс=8 шаг=1 по умолчанию=1 значение=1
           частота линии питания 0x00980918 (menu)   : мин=0 макс=2 по умолчанию=2 значение=1 (50 Гц)
                                0: Отключено
                                1: 50 Гц
                                2: 60 Гц
      температура авто баланса белого 0x0098091a (int)    : мин=2800 макс=6500 шаг=1 по умолчанию=4600 значение=4600 флаги=неактивно
                      резкость 0x0098091b (int)    : мин=1 макс=7 шаг=1 по умолчанию=2 значение=2
         компенсация обратного света 0x0098091c (int)    : мин=0 макс=3 шаг=1 по умолчанию=3 значение=3
                  автоэкспозиция 0x009a0901 (menu)   : мин=0 макс=3 по умолчанию=3 значение=3 (Режим приоритета диафрагмы)                                1: Ручной режим
                                3: Режим приоритета диафрагмы
              абсолютная экспозиция 0x009a0902 (int)    : мин=9 макс=625 шаг=1 по умолчанию=157 значение=157 флаги=неактивно
         приоритет автоэкспозиции 0x009a0903 (bool)   : по умолчанию=0 значение=0

И вот скриншот моей работающей камеры (я, конечно, положил палец перед ней, но изображение совершенно нормальное)
камера работает с учебным скриптом GitHub от PINTO0309

Ответ выше работает. Однако конфигурации в репозитории GitHub доступны только для нескольких версий WSL. Что если мы хотим скомпилировать другие версии WSL, такие как последнюю?

Здесь я даю общий метод для сборки ядра WSL с драйверами USB и интегрированной камеры. Версия, которую я протестировал, является последней версией – linux-msft-wsl-6.6.36.6, но она должна быть доступна для большинства версий с незначительными отличиями.

Я протестировал это решение с интегрированной камерой на моем ПК.

1 – Скомпилировать ядро WSL с любой версией

Шаг 1: Установите зависимости

# обновите источник пакетов
sudo apt update && sudo apt upgrade

# установите зависимости в соответствии с файлом README в исходном коде
sudo apt install build-essential flex bison dwarves libssl-dev libelf-dev cpio

# установите зависимости для конфигурации, согласно моему опыту
sudo apt install libncurses-dev

Шаг 2: Получите исходный код. Вы можете клонировать репозиторий или скачать его со страницы релиза

  • Не забудьте поместить его в систему Linux (я поместил его в WSL2)
# войдите в каталог
cd ~

# клонируйте репозиторий, например, тег "linux-msft-wsl-6.6.36.6" 
git clone --depth 1 -b linux-msft-wsl-6.6.36.6 https://github.com/microsoft/WSL2-Linux-Kernel.git

# войдите в исходный каталог
cd WSL2-Linux-Kernel

Шаг 3. Настройте ядро WSL командой: make menuconfig KCONFIG_CONFIG=Microsoft/config-wsl

Тогда мы увидим графический интерфейс терминала для конфигурации

  • Общие настройкиЛокальная версия: добавьте суффикс -usb-add для последующей проверки версии (вы можете добавить свой собственный суффикс)
  • Драйверы устройствПоддержка мультимедиа: измените его на * статус (нажмите пробел), а затем войдите в его конфигурацию (нажмите клавишу ввода)
    • измените Фильтры мультимедийных драйверов,Автоматический выбор вспомогательных драйверов (тюнеры, датчики, i2c, spi, фронтенды) на * статус
    • измените Типы мультимедийных устройствКамеры и видеозахватчики на * статус
    • измените Мультимедийные драйверыMультимедийные USB-адаптеры на * статус, а затем войдите в его конфигурацию
      • измените Веб-камеры на основе GSPCA и Класс USB Video (UVC) на статус “M”
      • войдите в Веб-камеры на основе GSPCA, измените все драйверы USB-камер на M, потому что мы не знаем тип нашей камеры
  • измените Драйверы устройствПоддержка USB на * статус, а затем войдите в его конфигурацию
    • измените Поддержка USB на хосте на * статус
    • измените Поддержка USB/IP на * статус, а затем измените все его подэлементы на * статус

Затем сохраните их и выйдите с помощью Сохранить и Выйти внизу

Шаг 4: Соберите ядро и установите модули

# скомпилируйте ядро
make KCONFIG_CONFIG=Microsoft/config-wsl -j$(nproc)
# скомпилируйте модули
sudo make KCONFIG_CONFIG=Microsoft/config-wsl modules -j$(nproc)
# установите модули в ядро
sudo make KCONFIG_CONFIG=Microsoft/config-wsl modules_install -j$(nproc)
# установите ядро
sudo make KCONFIG_CONFIG=Microsoft/config-wsl install -j$(nproc)

Теперь вы получите ядро WSL (./vmlinux)

2- Замените ядро на стандартное

Теперь вы можете скопировать ядро в ваш путь Windows и добавить путь в файл конфигурации WSL

  • Шаг 1: скопируйте ваше ядро в ваш путь Windows: sudo ./vmlinux /mnt/c/WSL/kernel/
  • Шаг 2: добавьте путь в C:/Users/{ваше имя пользователя}/.wslconfig (если этот файл не существует, создайте новый)
[wsl2]
kernel=C:\\WSL\\kernel\\vmlinux
  • Шаг 3: завершите работу WSL: wsl --shutdown
  • Шаг 4: войдите в WSL и проверьте версию: uname -a

Если вы увидите суффикс (-usb-add), это означает, что вы увенчались успехом. Ядро WSL теперь должно поддерживать USB и интегрированную камеру.

3 – Тест камеры

Если вы хотите использовать камеры, вам нужно совместно использовать камеру с WSL.

Во-первых, вам нужно установить usbipd-win

Во-вторых, выполните команды ниже в Windows с помощью Powershell.

# отобразить все USB-устройства
usbipd list

# поделитесь вашей камерой, предположим, что ее BUSID "1-6"
usbipd bind --busid 1-6 # для этого нужны права администратора

# прикрепите к WSL
usbipd attach --wsl --busid 1-6

В-третьих, войдите в WSL и выполните команды ниже

ls /dev/video*

Если вы видите какие-либо видео-устройства с помощью вышеуказанной команды, это означает, что вы увенчались успехом.

Ответ или решение

Захват видео с веб-камеры с использованием OpenCV в WSL2

Введение

Работа с веб-камерами через OpenCV в WSL2 (Windows Subsystem for Linux) может быть сложной задачей, особенно если речь идет о корректной настройке USB-устройств. В данной статье мы рассмотрим, как правильно захватывать видео с интегрированной веб-камеры в WSL2, используя OpenCV, а также предоставим пошаговые инструкции по устранению возможных проблем.

Зачем использовать WSL2 для работы с OpenCV?

WSL2 предоставляет возможность разрабатывать и тестировать приложения на Linux, не покидая Windows. Это упрощает рабочий процесс разработчиков и исследователей, работающих с инструментами, доступными только в Linux. Тем не менее, подключение и работа с USB-устройствами, такими как веб-камеры, требуют дополнительных шагов и конфигурации.

Шаг 1: Подключение веб-камеры к WSL2

Для начала убедитесь, что ваша веб-камера корректно подключена к Windows и распознается системой. Используя команду usbipd wsl list, вы можете просмотреть список доступных USB-устройств. Если ваша веб-камера отображается с состоянием "Не подключено", выполните команду:

usbipd wsl attach --busid 1-1

где 1-1 — это BUSID, соответствующий вашей веб-камере. После подключения проверьте, видна ли ваша камера в системе, выполнив команду lsusb. Если она отображается, значит, вы успешно подключили устройство.

Шаг 2: Установка необходимых библиотек

Убедитесь, что вы установили OpenCV и все необходимые зависимости. Это можно сделать с помощью следующих команд:

sudo apt update
sudo apt upgrade
sudo apt install python3-opencv

Шаг 3: Запуск скрипта для захвата видео

Используйте следующий код для доступа к веб-камере с помощью OpenCV:

import cv2
import sys

source = cv2.VideoCapture(0)

win_name = "Camera Preview"
cv2.namedWindow(win_name, cv2.WINDOW_NORMAL)

while cv2.waitKey(1) != 27:  # Escape
    has_frame, frame = source.read()
    if not has_frame:
        break
    cv2.imshow(win_name, frame)

source.release()
cv2.destroyWindow(win_name)

Шаг 4: Устранение проблем с доступом к камере

Если вы получаете сообщение об ошибке, например:

[ WARN:global /io/opencv/modules/videoio/src/cap_v4l.cpp (889) open VIDEOIO(V4L2:/dev/video0): can't open camera by index

это означает, что OpenCV не может получить доступ к устройству видео. В этом случае убедитесь, что USB-устройство поддерживается и правильно настроено. Возможно, придется скомпилировать собственный ядро Linux для WSL с поддержкой USB-устройств:

  1. Установите необходимые зависимости для компиляции ядра.
  2. Скачайте исходный код ядра WSL.
  3. Настройте конфигурацию для поддержки USB-устройств и видеокамер.
  4. Соберите и установите ядро, а затем обновите конфигурацию WSL.

Дополнительные рекомендации

Если вы столкнулись с трудностями, обратитесь к репозиториям GitHub, таким как wsl2_linux_kernel_usbcam_enable_conf и usbipd-win, которые содержат подробные инструкции по настройке и решению проблем с веб-камерами.

Заключение

Захват видео с веб-камеры через OpenCV в WSL2 может быть непростой задачей, но следуя указанным шагам и рекомендациям, вы сможете без проблем использовать свои устройства. Это открывает новые возможности для разработки, позволяя вам комбинировать мощные инструменты Linux и удобство Windows. Пробуйте, и пусть удача сопутствует вашим проектам!

Оцените материал
Добавить комментарий

Капча загружается...