えいあーるれいの技術日記

ROS2やM5 Stack、Ubuntuについて書いています

Raspi-Bullseyeでpicameraを検出するプログラムを作成する

ラズパイが接続されているかどうかを判定する方法については 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だけでなく、AndroidChrome OSでも使用でき、RaspberryPiもこれをサポートしています。


libcamera-appsを読む

RaspberryPi向けのlibcameraアプリケーションはraspberrypi/libcamera-appsで公開されています。

github.com

実は、探すコマンド自体はオプション --list-camerasがあります。

あったらデバイス詳細を流して終了コード0を返し、なかったら終了コード-1を返します。

当初は--list-camerasを見つけられず、単純に見つかったら0、見つからなかったら1の終了コードを返すプログラムを作成しました。


実装

ソースコードとビルドに使用したCMakeListsを以下に示します。

gist.github.com

カメラ自体は33行目で取得できますが、このリストにはUSB接続経由のカメラも含まれているようで、35行目で除いているようです。

ビルドは、同じディレクトリにソースコードとCMakeListsを配置してから次のコマンドでビルドするだけです。

mkdir build
cd build
cmake ..
make


以下、実行方法

./libcaemra-find

見つかれば終了コード0、それ以外は1が返ってきます。

ただし、複数台検出されても終了コードは0で同じです。(ログは異なります)

libcamera直ビルド&libcamera-appsのビルド面倒な人だったので、個人的には重宝しています。


補足:カメラコネクタの状態

csiコネクタは起動中の抜き差しを想定していないので、次の仕様があります。

  • 起動前にカメラを差す:終了コード0(正常)
  • 起動後にカメラを差す:終了コード1(カメラの接続状況に関わらず失敗)
  • 起動前はカメラを差して、その後に抜く:終了コード1(正常)
  • 起動前はカメラを差して、その後に抜いた後、また差す:終了コード0(正常)


参考資料