ラズパイが接続されているかどうかを判定する方法については vcgencmd get_camera
というコマンドを使用することで確認できることは有名だと思います。
How Do I Know if My Raspberry Pi Camera is Working? – RaspberryTips
しかし、少なくとも私の環境ではカメラが接続されているのにも関わらず以下のような出力になってしまいます。
$ vcgencmd get_camera supported=0 detected=0
一方で、libcamera-helloでは先ほどの出力にも関わらず映像が映ってしまいます。
Raspi4 + Bullseyeでは接続方法が変わったのでしょうか?
また、vcgencmdは検出の有無に関わらず終了コードが同じなので「カメラ検出の結果によって分岐…」も行いにくいという欠点もあります。
ということでlibcameraに従った新しいカメラ検出プログラムを作成することにしました。
libcameraとは?
libcameraとは、組込みシステム向けのカメラ用高レベルなオープンソースAPIです。
カメラにはさまざまな高度な処理が必要で、専用のICがカメラに付属していることがほとんどです。
ウェブカメラはその代表例でしょう。
USBを差すだけで映像が取得できますが、カメラ内でICが生データの取得から圧縮などの画像処理を行って転送を行います。
その一方で、組込み分野ではCPUの劇的な性能向上に着目しその専用ICを除くことで低コスト化を進めるようになります。
例えば、RaspberryPi向けのpicameraやタブレット端末内のカメラには画像処理ICがない場合があります。
抜き差しが行われないデバイスにとって画像処理&転送ICは設置面積やコストの面で取り除いた方が良いからです。
しかしながら、カメラのICがなくなると、これまで画像処理ICが担っていた処理をアプリケーション開発者側が行わなければなりません。
(私は業界のことを詳しく知っているわけではないですが)また、ベンダー側から提供されるドライバは非オープンソースで公開にも制限があるため、v4l2ドライバのような加速的な開発が期待できません。
libcameraはOSSとして、組込みカメラの高レベルAPIを提供することを目標としています。
Linuxだけでなく、AndroidやChrome OSでも使用でき、RaspberryPiもこれをサポートしています。
libcamera-appsを読む
RaspberryPi向けのlibcameraアプリケーションはraspberrypi/libcamera-appsで公開されています。
実は、探すコマンド自体はオプション --list-cameras
があります。
あったらデバイス詳細を流して終了コード0を返し、なかったら終了コード-1を返します。
当初は--list-cameras
を見つけられず、単純に見つかったら0、見つからなかったら1の終了コードを返すプログラムを作成しました。
実装
ソースコードとビルドに使用したCMakeListsを以下に示します。
カメラ自体は33行目で取得できますが、このリストにはUSB接続経由のカメラも含まれているようで、35行目で除いているようです。
ビルドは、同じディレクトリにソースコードとCMakeListsを配置してから次のコマンドでビルドするだけです。
mkdir build cd build cmake .. make
以下、実行方法
./libcaemra-find
見つかれば終了コード0、それ以外は1が返ってきます。
ただし、複数台検出されても終了コードは0で同じです。(ログは異なります)
libcamera直ビルド&libcamera-appsのビルド面倒な人だったので、個人的には重宝しています。
補足:カメラコネクタの状態
csiコネクタは起動中の抜き差しを想定していないので、次の仕様があります。
- 起動前にカメラを差す:終了コード0(正常)
- 起動後にカメラを差す:終了コード1(カメラの接続状況に関わらず失敗)
- 起動前はカメラを差して、その後に抜く:終了コード1(正常)
- 起動前はカメラを差して、その後に抜いた後、また差す:終了コード0(正常)