Ubuntu Weekly Recipe

第789回Python製のcamsetでWebカメラをGUIから設定する

リモートワークも定着し、何を映すかはともかくとして、Webカメラを常備している人も多いことでしょう。そもそもノートPCならほぼ標準搭載の機能ではあります。これらのWebカメラはUSB Video Class(UVC)に対応しており、Ubuntuでも特別なドライバーなしに使えます。しかしながら、その設定ツールについては、デバイス固有でありWindowsやmacOS向けのツールしか存在しないことが大半です。今回はUbuntuでも使えるGUIの設定ツールであるcamsetと、そのバックグラウンドで動いているVideo for Linux(V4L)用のCLIツールを紹介します。

図1 Jellyfishの上に乗ったMinotaurがNumbatに追いかけられる様子
図1

UVCのドライバーとツールを開発するVideo for Linux

Video for Linux(V4L)については、第230回のウェブカメラの映像をリアルタイムに補正するでも紹介しています。実は今回の話は、第230回で紹介した「v4l2ucp(Video4Linuxコントロールパネル⁠⁠」がリポジトリからインストールできなくなったことによる、代替案としての記事となります。

2012年当時はv4l2ucpは十分に機能していましたが、これはQt4を使っているツールであり、ほぼQt5に移行しきって、そろそろQt6対応が進み始めている今となっては古いアプリケーションになりました。実際Debianリポジトリ側では、Qt4の削除に伴いv4l2ucpパッケージもリポジトリから削除されています。たとえばUbuntu 22.04 LTSだとこのソフトウェアはリポジトリからインストールできない状態です。

一応、Qt5に対応したバージョンも存在する(した)ようですが、そこまで活発には開発されていないようです。そこで今回は代案として、よりインストールしやすいcamsetを紹介します。これはPythonとPycairoを用いたGUIツールで、pip/pipxコマンドでかんたんにインストールでき、1画面に設定項目をまとめたシンプルなUIであるため直感的に使える点が特徴です[1]

ちなみに他のツールとしては第303回で紹介した定番の「guvcview」や、V4L公式とも言える「qv4l2⁠⁠、snapからインストール可能なcameractrlsなども存在します。用途とフィーリングに合わせて使い分けましょう。

では、早速camsetインストールしてみましょう。手順としてはcamsetを動かすために必要なパッケージをインストールして、Pythonの流儀でパッケージをインストールするだけです。

$ sudo apt install v4l-utils pkg-config pipx
$ pipx install camset

pipxは~/.locah/pipx/以下にパッケージをインストールし、~/.local/bin/以下に実行スクリプトをインストールします。そのため~/.local/bin/に実行パスが通っていないと(環境変数$PATH~/.local/bin/が追加されていないと⁠⁠、camsetコマンドを実行できません。Ubuntuの場合、ログイン時に~/.local/bin/が存在すれば、自動的に$PATHにそのパスを追加してくれます。ただし初めてpipxを実行したときなど、~/.local/bin/が作られたタイミングでは$PATHは未更新です。そういう場合は、一度ログアウトしてログインし直すといいでしょう。

さらにcamsetには、アイコンファイルとdesktopファイルも用意されています。GNOME Shellのアプリケーション検索画面からcamsetを検索して表示するためには、これを次のように登録します。

アイコンファイルのサイズ確認
$ file ~/.local/pipx/venvs/camset/share/icons/camset.png
.local/pipx/venvs/camset/share/icons/camset.png: PNG image data, 256 x 256, 8-bit/color RGBA, non-interlaced

256x256なのでそれを指定してインストール
$ xdg-icon-resource install --novendor --size 256 ~/.local/pipx/venvs/camset/share/icons/camset.png

desktopファイルをインストール
$ desktop-file-install --dir=~/.local/share/applications/ ~/.local/pipx/venvs/camset/share/applications/camset.desktop

最後のコマンドでは"Desktop Entry" is an icon name with an extensionというエラーメッセージが出ます。これはdesktopファイルのIconフィールドで指定したアイコンファイル名に拡張子を指定しているからで、将来的にはこれは許可されなくなる予定です。今のところは付いていても動作するので、そのままで良いでしょう。

これでアプリケーション検索画面で「camset」を入力すると、camsetが起動できるようになりました。

図2 camsetを起動すると設定用のウィンドウとプレビュー画面のウィンドウが2個表示される
図2

プレビュー画面は設定ウィンドウの設定に合わせてリアルタイムで反映されます。ちなみにカメラの映像デバイスは、ひとつのアプリケーションでしか利用できません。よってたとえばZoomの映像の状態を確認したいのであれば、プレビュー画面だけ閉じてしまって、Zoomで適当なミーティングを開始し、そちらのカメラ映像を見ながら設定しましょう。ただし設定ウィンドウの左側は、他のアプリだと調整できないようです。

設定用ウィンドウは、原則としてデバイスがサポートのみ設定を変更できます。また、いくつかの項目は条件が満たされたときのみ操作可能です。代表的なものをいくつか説明していきましょう。

「Power Line Frequency」は電源の周波数設定です。いわゆる「映像のチラツキ」が発生した場合は、まずここの設定を変えてみると良いでしょう。

「Brightness」以降の設定は明るさやコントラスト、ホワイトバランス等を細かく設定できます。基本的にデフォルトの設定でも良いのですが、少しでも「きれいに」みせたいなら、うまく調節してみましょう。とりあえずいろいろいじって元に戻せなくなったら「Load defaults」ボタンを押すと、カメラの初期値に戻せます。

図3 例えば単純に「Saturation」を0にしたら、モノクロ映像になる
図3

「Backlight Compensation」「逆光補正」のことです。明るすぎる・暗すぎるをお手軽に調整できます。今回の機種(Logitech StreamCam)だと0か1しか設定できませんでした。

「Pan Absolute」⁠Tilt Absolute」は表示する画角を調整します。今回の機種(Logitech StreamCam)だと、まず「Zoom Absolute」を変更し画面をズームした上で、Pan/Tiltを変更することでカメラの画角のうち一部だけを表示させることが可能になります。

図4 Zoom/Pan/Tiltをいじって部分的な拡大映像に
図4

「Save settings」ボタンで設定内容が保存されます。設定先は~/.config/camset/カメラ名.camsetで、中身は単なるテキストファイルです。⁠Load settings」を押すと、設定ファイルから再度設定を反映できます。

CLIで操作する「v4l2-ctl」

camsetはバックエンドとしてv4l2-ctlコマンドを利用しています。V4L2はioctlなどからも操作できますが、v4l2-ctlコマンドでも一通りの操作が可能です。まずはその操作方法を見ていきましょう。まずV4L2に対応したカメラデバイスの一覧を表示します。

$ v4l2-ctl --list-devices
Logitech StreamCam (usb-0000:3d:00.0-2):
        /dev/video0
        /dev/video1
        /dev/media0

デバイスは1台だけなのですが、デバイスファイルは3種類あるようです。今回のケースだと、/dev/video0がカメラ本体の操作用で、/dev/video1がメタデータ用、/dev/media0が実際に映像データをやりとりするデバイスとなります。これは次のコマンドでも確認できます。

$ v4l2-ctl -d /dev/video0 --all
Driver Info:
        Driver name      : uvcvideo
        Card type        : Logitech StreamCam
(中略)
        Device Caps      : 0x04200001
                Video Capture
                Streaming
                Extended Pix Format
(中略)
Video input : 0 (Input 1: ok)
Format Video Capture:
        Width/Height      : 640/480
        Pixel Format      : 'YUYV' (YUYV 4:2:2)
(中略)
User Controls

                     brightness 0x00980900 (int)    : min=0 max=255 step=1 default=128 value=128
                       contrast 0x00980901 (int)    : min=0 max=255 step=1 default=128 value=128
                     saturation 0x00980902 (int)    : min=0 max=255 step=1 default=128 value=128
        white_balance_automatic 0x0098090c (bool)   : default=1 value=1
                           gain 0x00980913 (int)    : min=0 max=255 step=1 default=0 value=0
           power_line_frequency 0x00980918 (menu)   : min=0 max=2 default=2 value=2 (60 Hz)
                                0: Disabled
                                1: 50 Hz
                                2: 60 Hz
      white_balance_temperature 0x0098091a (int)    : min=2000 max=7500 step=1 default=4000 value=5142 flags=inactive
                      sharpness 0x0098091b (int)    : min=0 max=255 step=1 default=128 value=128
         backlight_compensation 0x0098091c (int)    : min=0 max=1 step=1 default=0 value=0

Camera Controls

                  auto_exposure 0x009a0901 (menu)   : min=0 max=3 default=3 value=3 (Aperture Priority Mode)
                                1: Manual Mode
                                3: Aperture Priority Mode
         exposure_time_absolute 0x009a0902 (int)    : min=3 max=2047 step=1 default=250 value=333 flags=inactive
     exposure_dynamic_framerate 0x009a0903 (bool)   : default=0 value=0
                   pan_absolute 0x009a0908 (int)    : min=-36000 max=36000 step=3600 default=0 value=0
                  tilt_absolute 0x009a0909 (int)    : min=-36000 max=36000 step=3600 default=0 value=0
                 focus_absolute 0x009a090a (int)    : min=0 max=255 step=1 default=0 value=30 flags=inactive
     focus_automatic_continuous 0x009a090c (bool)   : default=1 value=1
                  zoom_absolute 0x009a090d (int)    : min=100 max=400 step=1 default=100 value=100

最初の「Device Caps」「Video Capture」が表示されているものが、カメラ本体の操作用と考えておおよそ差し支えありません。

「User Controls」以降には、camsetで表示されていた項目がそのまま掲載されています。つまりcamsetはV4L2からこれらの値を取得・表示し、設定しているだけです。⁠User Controls」以降だけ表示したければv4l2-ctl -d /dev/video0 --list-ctrlsと実行してください。

設定は--set-ctrlオプションです。たとえば先程と同じように「saturation(彩度⁠⁠」を落としてモノクロ画像にするなら次のように設定します。

$ v4l2-ctl -d /dev/video0 --set-ctrl saturation=0

さて、camsetでは設定データを保存できることを紹介しました。具体的には次のようなフォーマットになっています。

brightness=128
contrast=128
saturation=0
white_balance_automatic=1
gain=0
power_line_frequency=2
sharpness=128
backlight_compensation=0
auto_exposure=3
exposure_dynamic_framerate=0
pan_absolute=0
tilt_absolute=0
focus_automatic_continuous=1
zoom_absolute=100
resolution_index=0

これはまさにv4l2-ctl --set-ctrlのオプションです。つまり起動時にこの設定を流し込めば、再起動のたびに設定しなおす必要がなくなります。試してみましょう。

まずは設定を反映するプログラムを作成します。これは上記を実行するシェルスクリプトとして作れば良いでしょう。たとえば~/.local/bin/cameraconfigみたいなファイルを次のような内容で作成します。

#!/bin/sh

if [ ! -c /dev/video0 ]; then
    # UVC is not found
    exit 0
fi

v4l2-ctl -d /dev/video0 --set-ctrl brightness=128
v4l2-ctl -d /dev/video0 --set-ctrl contrast=128
v4l2-ctl -d /dev/video0 --set-ctrl saturation=0
v4l2-ctl -d /dev/video0 --set-ctrl white_balance_automatic=1
v4l2-ctl -d /dev/video0 --set-ctrl gain=0
v4l2-ctl -d /dev/video0 --set-ctrl power_line_frequency=2
v4l2-ctl -d /dev/video0 --set-ctrl sharpness=128
v4l2-ctl -d /dev/video0 --set-ctrl backlight_compensation=0
v4l2-ctl -d /dev/video0 --set-ctrl auto_exposure=3
v4l2-ctl -d /dev/video0 --set-ctrl exposure_dynamic_framerate=0
v4l2-ctl -d /dev/video0 --set-ctrl pan_absolute=0
v4l2-ctl -d /dev/video0 --set-ctrl tilt_absolute=0
v4l2-ctl -d /dev/video0 --set-ctrl focus_automatic_continuous=1
v4l2-ctl -d /dev/video0 --set-ctrl zoom_absolute=100
v4l2-ctl -d /dev/video0 --set-ctrl resolution_index=0

あとはこれに実行権限を付けておきましょう。

$ chmod +x ~/.local/bin/cameraconfig

試しにcamsetか何かで設定を変更した上で、cameraconfigを実行してみてください。無事に設定が反映されればOKです。

次にログイン時に自動起動するようにします。.bashrcなどに記載しても良いのですが、今回はXDG AUtostartを利用しましょう。これはdesktopファイルを特定のディレクトリに置くことで、それを起動時に自動実行してくれる仕組みです。

たとえば次のようなファイルを~/.config/autostart/cameraconfig.desktopの名前で作ってみましょう。

[Desktop Entry]
Type=Application
Name=Update camera settings
Exec=cameraconfig
StartupNotify=false
NoDisplay=true
Hidden=true

desktopファイルが問題ないかは、次のコマンドで確認できます。

$ desktop-file-validate ~/.config/autostart/cameraconfig.desktop

これで次回ログイン時からは、好みの設定でカメラが起動するようになりました。今回はカメラデバイスが1台という前提で決め打ちしていますが、複数台運用しているのであればudevルールなどでシンボリックな名前を付けると区別がしやすくなります。

V4Lはその名前のとおり、映像に関するデバイスの設定です。今回はWebカメラに限定しましたが、V4Lがサポートするデバイスであれば他にも同様の対応が可能になります。ぜひ手持ちのデバイスが正しく操作できるか試してみてください。

おすすめ記事

記事・ニュース一覧