🎄

Windows11 WSL2(kernel:5.10.74.3-microsoft-standard-WSL2)でUSBカメラを使う

2021/12/25に公開

※ usbipd-winのver.2.0.0リリースから下記の通りに実行してもUSBカメラが使えない可能性があります。ver1.3.0での実行記録です。

Microsoftから公式にWSL2でUSBデバイスに接続できるとの情報が出ておりました。
https://devblogs.microsoft.com/commandline/connecting-usb-devices-to-wsl/

記事通りに試してみると、WSL2からでもUSBカメラを認識することはできるものの接続できなかったので、その対処法をまとめます。

症状はWindowsからattachすると、WSL2でlsusbを実行するとデバイスは表示されるが、/dev/video*が生成されません。

結論としてはkernelビルドが必要でした。
デフォルトでV4L2関連のドライバが入っていないようです。

環境

  • Windows 11 Pro Insider Preview: 22523.rs_prerelease.211210-1418
  • WSL2 kernel: 5.10.74.3-microsoft-standard-WSL2
  • Ubuntu 20.04

usbipをインストール

こちらのソフトをインストール
https://github.com/dorssel/usbipd-win

Windowsのpowershellにて

winget install --exact dorssel.usbipd-win
# USBデバイスをリスト表示
usbipd list

WSL2でusbipを使えるようにする

WSL2にて

sudo apt install linux-tools-5.4.0-77-generic hwdata

/etc/sudoersを編集し、Defaults secure_path/usr/lib/linux-tools/5.4.0-77-genericを追加

sudo vim /etc/sudoers
# 下記のように追記する
# シャープもつけてください。
# Defaults secure_path="/usr/lib/linux-tools/5.4.0-77-generic:/usr/local/sbin:..."

もし編集に失敗してsudoが使えなくなった場合、WindowsのPowershellからrootユーザーでWSLにログインして、/etc/sudoresを再編集してください。

wsl -u root

usbipの動作確認

Windowsにて管理者権限でpowershellを起動して

usbipd list
usbipd wsl attach --busid={busid}

WSL2にて

lsusb

USBデバイスが表示されればOK。
このままでは、USBカメラをattachしても/dev/video*が生成されません。

カーネルのビルド

このあたりの記事を参考に行っていきます。
https://ktkr3d.github.io/2020/07/06/USB-support-to-WSL2/
https://zenn.dev/pinto0309/articles/0723ae46501beb

usbipは有効化されているので、カメラ関連の箇所を有効化します。

現在のカーネルバージョンを確認

uname -r -a
# 5.10.74.3-microsoft-standard-WSL2 #1 SMP ...

ビルドに必要なパッケージをインストール

sudo apt update
sudo apt upgrade
sudo apt install build-essential flex bison libssl-dev libelf-dev libncurses-dev autoconf libudev-dev libtool zip unzip v4l-utils libssl-dev \
python3-pip cmake git iputils-ping net-tools

カーネルのソースをダウンロード

cd /usr/src && \
TAGVERNUM=5.10.74.3 && \
TAGVER=linux-msft-wsl-${TAGVERNUM} && \
sudo git clone --depth 1 -b ${TAGVER} \
https://github.com/microsoft/WSL2-Linux-Kernel.git \
${TAGVERNUM}-microsoft-standard && \
cd ${TAGVERNUM}-microsoft-standard
sudo cp /proc/config.gz config.gz
sudo gunzip config.gz
sudo mv config .config

configをGUIで編集

sudo make menuconfig

実際にどれが必要な項目かわからなかったのでそれっぽいものを選択していく。

  • Device Drivers > Multimedia support > Media device typesからCameras and video grabbersを選択

  • Device Drivers > Multimedia support > Video4Linux optionsの中をすべて選択

  • Device Drivers > Multimedia support > Media USB AdaptersからUSB Video Class (UVC)を選択

  • 保存して終了

  • ビルド時にエラーがでたので.configファイルを直接編集。

    • 下記のようなエラー
    BTF: .tmp_vmlinux.btf: pahole (pahole) is not available
    Failed to generate BTF for vmlinux
    Try to disable CONFIG_DEBUG_INFO_BTF
    
    • Compile-time checks and compiler optionsのちょっと下、3994行目くらいのCONFIG_DEBUG_INFO_BTFynに書き換え
ビルド
sudo make -j$(nproc) && \
sudo make modules_install -j$(nproc) && \
sudo make install -j$(nproc)

生成されたカーネルファイルをWindows側にコピーする

sudo cp /usr/src/${TAGVERNUM}-microsoft-standard/vmlinux /mnt/c/Users/<windows username>/

WSL2の設定変更

ここからWindowsの操作。
WSL2の設定ファイルC:\\Users\\<windows username>\\.wslconfigでカーネルを指定する。
ファイルがなければ新規作成する。<windows username>は自身のユーザー名に置き換えてください。

[wsl2]
kernel=C:\\Users\\<windows username>\\vmlinux

WSL2を再起動

wsl --shutdown

WSL2のカーネルが変更されたか確認する。
WSL2にて。

uname -r -a
# 日付がビルド日時に更新されていればOK

動作確認

WSL2を再起動すると、usbipのattachも解除されるので再attach

Windowsの管理者権限Powershellにて

usbipd list
usbipd wsl attach --busid={busid}

WSL2にて

lsusb
# デバイスが出てくるはず

ls /dev/video*
# カメラデバイスをattachしていれば/dev/video*が表示されるはず

# 読み書き権限を与えます。
sudo chmod 777 /dev/video*

OpenCVとかでキャプチャできるか試してみましょう

import cv2

cap = cv2.VideoCapture(0)
while True:
	_, img = cap.read()
	cv2.imshow("", img)
	key = cv2.waitKey(1)
	if key == ord('q'):
		break
cap.release()
cv2.destroyAllWindows()

カメラのキャプチャ動画が表示されればOK。
カメラによっては映像が乱れることがあります。解像度が高く、データ転送量が多いと発生するのかもしれません。

Discussion