産業用ラズパイで試すAIカメラとAIアクセラレータHailo

Raspberry Pi公式のAIカメラモジュールは、これまでのカメラモジュール同様に接続できます。本体にCSIカメラポートが用意されおり基本は同じです。
AIカメラモジュールがこれまでと異なる点として、カメラ側に小さなAIアクセラレータ(RP2040)が搭載されている点です。
RP2040は、あのRaspberry Pi Picoと同じMCUです。

RP2040によりカメラ側でAIに必要になる処理を一部担えるため、Raspberry Pi本体の処理能力でも実現できる仕組みです。

産業用ラズパイのRaspberry PiはCompute Module 5 (CM5)で試しました。従来のPL-R4ではCM4搭載ですが、同じフォームファクタのCM5に載せ替えが可能です。今回はCM5を実装したモデルPL-R5-Mを使用しました。更にAIアクセラレータの1つであるHailoを接続しました。
基本的な動作は公式ドキュメントを参考に体験してみました。

AIカメラモジュールとHailoは市販されており、誰でも試すことができます。

従来のカメラモジュールとAIカメラモジュールの違い

公式ドキュメントに分かりやすい図がありました。左側が以前のカメラモジュールを表しています。オプションでAIアクセラレータの入出力が可能です。
右側がAIカメラモジュールです。IMX500内にAIアクセラレータが載っているのが分かります。
AI カメラモジュールに搭載されているチップ(MCU)はRP2040で、あのRaspberry Pi Picoでお馴染みです。
搭載されているチップが補助的に使われているため、オプションのAIアクセラレータを接続していない環境でも動作出来るわけです。

今回の環境

今回はAIカメラモジュールだけでなく、オプションとして本体のM.2スロットにHailo(AIアクセラレータ)も接続済みです。
本体はComputeModule 5を搭載したPL-R5-Mでセットアップしています。

  • Compute Module 5搭載 PL-R5-M USB IP20(産業用ラズパイ)
  • Raspberry Pi OS bookworm
  • AIカメラモジュール(IMX500)
  • Hailo(AIアクセラレータ)
PL-R5-M本体裏側:キャリーボード裏側のM.2スロットにマウントしたAI アクセラレータHailo

Hailoのセットアップはここでは省きます。やはり公式ドキュメントをご覧ください。

AIカメラモジュールは、専用のパッケージがあります。OSのアップデート後にaptでインストールしました。

sudo apt update && sudo apt full-upgrade
sudo apt install imx500-all

以前にもお伝えしたように、カメラモジュールの動作に際し、config.txtのパラメーターを変更しないとなりません。
(参考:産業用ラズパイでも簡単にカメラを繋げられる

Pi 5(bookworm)だとconfig.txtはfirmware以下にあります。

sudo nano /boot/firmware/config.txt

config.txtの変更箇所は、カメラの自動認識を明示的にオフ、AIカメラモジュールであるIMX500を指定します。

camera_auto_detect=0

[all]

dtoverlay=imx500,cam0

※試用したPL-R5-MはCompute Module 5を搭載した独自のデバイスのため、他にも追記・変更する箇所があります。

再起動後にAIカメラが自動認識できたか、コマンドを使って確かめます。
imx500が見つかりました。これで準備はOKです。

libcamera-hello --list-cameras

Available cameras
-----------------
0 : imx500 [4056x3040 10-bit RGGB] (/base/axi/pcie@120000/rp1/i2c@88000/imx500@1a)
    Modes: 'SRGGB10_CSI2P' : 2028x1520 [30.02 fps - (0, 0)/4056x3040 crop]
                             4056x3040 [10.00 fps - (0, 0)/4056x3040 crop]

物体検出してみる

AIカメラも認識したところで、早速サンプルを実行してみました。
/usr/share/rpi-camera-assetsにrpicam-appで使えるファイルがインストールされています。json形式です。
同じく、/usr/share/imx500-modelsにAI Modelがインストールされています。
これはPythonコマンドで指定できるようですね。拡張子はrpkです。

ドキュメント通り、rpicam-helloコマンドでimx500_mobilenet_ssd.jsonを実行すると、物体にボックス状の境界線を描画できました。

rpicam-hello -t 0s --post-process-file /usr/share/rpi-camera-assets/imx500_mobilenet_ssd.json
【AIカメラ】検出パーセンテージ 62%

今回はHailoをセットアップしているため、Hailoと書かれているjsonファイルも実行してみました。
結果としては同じように枠線が表示されます。

rpicam-hello -t 0s --post-process-file /usr/share/rpi-camera-assets/Hailo_yolov6_inference.json
【Hailo_yolov6_inference.json】検出パーセンテージ 91%

2つを比べると、検知のパーセンテージが異なりました。
先程だと62%だったのに対し、Hailo_yolov6_inference.jsonだと91%でした。

実行後にターミナル画面に進捗バー(Network Firmware Update)が表示されますが、これがHailo搭載だと速く数秒でした。

ちなみに、コマンドのオプションとして--viewfinder-width 1920 --viewfinder-height 1080 --framerate 30とすると画像の縦横、フレームレートなど指定できます。
Hailo_yolov6〜の「YOLO」は物体検出のアルゴリズムのことです。バージョン6、バージョン8などありますね。

先程のimx500_mobilenet_ssd.jsonファイルの中を覗いてみると、/usr/share/imx500-modelsにあるAIモデルを使っていることが分かります。(rpkファイル)

{
    "imx500_object_detection":
    {
        "max_detections" : 5,
        "threshold" : 0.6,
        "network_file": "/usr/share/imx500-models/imx500_network_ssd_mobilenetv2_fpnlite_320x320_pp.rpk",
...(以下、略)

他のアセットファイル

インストールされた他のjsonファイルも試してみました。
jsonファイル内でそれぞれパラメーターを指定できます。

そのまま実行した結果をいくつかご紹介します。

./usr/share/rpi-camera-assets
├── annotate_cv.json
├── face_detect_cv.json
├── Hailo_classifier.json
├── Hailo_pose_inf_fl.json
├── Hailo_scrfd.json
├── Hailo_yolov5_personface.json
├── Hailo_yolov5_segmentation.json
├── Hailo_yolov6_inference.json
├── Hailo_yolov8_inference.json
├── Hailo_yolov8_pose.json
├── Hailo_yolox_inference.json
├── hdr.json
├── imx500_mobilenet_ssd.json
├── imx500_posenet.json
├── motion_detect.json
├── negate.json
└── sobel_cv.json

annotate_cv.json
フレーム数など処理内容(注釈)が表示されました。

Hailo_classifier.json
カメラの向きを変えると左上に単語が変わるのが分かります。

Hailo_scrfd.json
別のウィンドウが立ち上がり、ズームアップやクリップボードへのコピーなど操作できました。

negate.json
ネガ表示になりました。

sobel_cv.json
エッジを強調するソベルフィルターです。

ここまではrpicamコマンドでの実行でした。
次は、Picamera2を使いPythonファイルのデモを動かしてみます。

Picamera2のインストール

Pythonコードでカメラモジュールを制御するのに、コード内でPicamera2のインポートが必要になります。

Picamera2は現行のOSでプリインストールされています。Raspberry Pi OS Bullseyeより前のOSイメージファイルか、OS liteイメージでは別にインストールする必要があります。
(参考:https://github.com/raspberrypi/picamera2

ほとんどの例でOpenCV を使用しています。依存関係をインストールしておきましょう。

sudo apt install python3-opencv python3-munkres

Picamera2をgit cloneして、デモが入ったexamplesの中に、AIカメラモジュール(IMX500)用ディレクトリがありました。

git clone https://github.com/raspberrypi/picamera2.git
cd picamera2/examples/imx500

Pythonで書かれた5つのデモファイル。

./picamera2/examples/imx500
├── imx500_classification_demo.py
├── imx500_object_detection_demo_mp.py
├── imx500_object_detection_demo.py
├── imx500_pose_estimation_higherhrnet_demo.py
└── imx500_segmentation_demo.py

Hailoディレクトリにも3つありました。

./picamera2/examples/Hailo
├── coco.txt
├── detect.py
├── pose.py
└── pose_utils.py

Pythonのデモプログラムを試してみる

公式ドキュメント通り、imx500_object_detection_demo.pyで、imx500_network_ssd_mobilenetv2_fpnlite_320x320_pp.rpkというAI modelを指定して実行してみます。

python imx500_object_detection_demo.py --model /usr/share/imx500-models/imx500_network_ssd_mobilenetv2_fpnlite_320x320_pp.rpk

ちゃんとテディベアと出ましたね。

このぬいぐるみはRaspberry Pi公式マスコットです。バベッジベア(Babbage Bear)という名称ですが、流石にそれは学習させないと無理ですね。テディベアはぬいぐるみとして予めデータセットされていますし、実際にテディベアなので問題はありません。

「ssd_mobilenetv2」はmobileとあるようにモバイル端末などのリソースがあまりない環境で物体検知を判別させるモデルのことです。
MobileNET v3までリリースされています。

続いて、ポーズ(骨格)の検出デモも試してみました。
こちらはデモをそのまま実行するだけで済みました。

python imx500_pose_estimation_higherhrnet_demo.py

カメラモジュールとの距離の問題があって腕だけですみません。
何もせずとも3点?が認識され骨格として繋がれました。骨格の数は最大数なども指定して調整できるとありました。
あまり距離が近いと駄目でしたが、60cmも離れていれば骨格の線が自動的に表示されます。

AI Modelであるrpkのファイルは、全部で24個ありました。
深層学習やAI、Python言語についてご存じの方なら、各AI Modelを指定してPythonプログラムを書いてみてはいかがでしょうか。

./usr/share/imx500-models
├── imx500_network_deeplabv3plus.rpk
├── imx500_network_efficientdet_lite0_pp.rpk
├── imx500_network_efficientnet_bo.rpk
├── imx500_network_efficientnet_lite0.rpk
├── imx500_network_efficientnetv2_b0.rpk
├── imx500_network_efficientnetv2_b1.rpk
├── imx500_network_efficientnetv2_b2.rpk
├── imx500_network_higherhrnet_coco.rpk
├── imx500_network_inputtensoronly.rpk
├── imx500_network_levit_128s.rpk
├── imx500_network_mnasnet1.0.rpk
├── imx500_network_mobilenet_v2.rpk
├── imx500_network_mobilevit_xs.rpk
├── imx500_network_mobilevit_xxs.rpk
├── imx500_network_nanodet_plus_416x416_pp.rpk
├── imx500_network_nanodet_plus_416x416.rpk
├── imx500_network_posenet.rpk
├── imx500_network_regnetx_002.rpk
├── imx500_network_regnety_002.rpk
├── imx500_network_regnety_004.rpk
├── imx500_network_resnet18.rpk
├── imx500_network_shufflenet_v2_x1_5.rpk
├── imx500_network_squeezenet1.0.rpk
└── imx500_network_ssd_mobilenetv2_fpnlite_320x320_pp.rpk

AIカメラを試してみて

サンプルの動作とはいえ、コマンドを実行してカメラ前に何かをかざせば、何のストレスもなく判別しているように見受けられます。
AIカメラモジュールとAIアクセラレータのどちらも使ったため処理はとてもスムーズでした。
AIカメラモジュールだけだと、コマンド実行後のNetwork Firmware Updateに少し時間がかかります。動作してしまえば後は同じです。

YOLO、TensorFlow、HailoといったAIで使われる言葉や仕組みが多く、前知識がない状態だと複雑に感じます。カメラですから、画像や映像の知識もあると良いでしょう。
逆に慣れている人なら、Raspberry Pi で実現できていることに驚くかもしれません。

公開されているドキュメントはかなり細かいものの、サンプル例からAIカメラモジュールで何ができるのか理解が深まると思います。

参考:AIカメラモジュール公式ドキュメント


記事寄稿:ラズパイダ

非エンジニアでも楽しく扱えるRaspberry Pi 情報サイト raspida.com を運営。ラズベリーパイに長年触れた経験をもとに、ラズベリーパイを知る人にも、これから始めたいと興味を持つ人にも参考になる情報・トピックを数多く発信。PiLinkのサイトへは産業用ラズベリーパイについて技術ブログ記事を寄稿。