Raspberry Pi AI cameraとPi Zero2 W でチュートリアルを試してみた

# はじめに
Raspberry Pi AI Cameraの国内販売が2024年9月から始まり、簡単にエッジAI処理をRaspberry Piを用いて試せる環境が揃ってきました。

本稿では、主にこれからRaspberry Pi AI Cameraを初めて使うユーザを対象にカメラのセットアップ方法とチュートリアルのサンプルアプリを動かす方法を紹介します。


<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3980579/6be66fb3-699e-6b1d-5a81-058d0e0e7fb0.jpeg" width="600">


<!--
# 機材リスト

### ✅ 必要なもの

| #  | Item              | メモ                                                                                      |
|----|-------------------|-------------------------------------------------------------------------------------------|
| 1  | Pi AI Camera      | [商品ページ](https://www.raspberrypi.com/products/ai-camera/)                              |
| 2  | Raspberry Pi      | Pi3 B+/Pi 4/PI5/PI Zero2w/Compute Module 4にて動作確認済み。本記事ではPI Zero2wを使用 |
| 3  | 電源ケーブル       |                                                                                           |
| 4  | SDカード           |                                                                                           |

### 💡 あれば便利なもの

| #  | Item              | メモ                                                                                         |
|----|-------------------|----------------------------------------------------------------------------------------------|
| 5  | マウス             | ディスプレイに接続する場合必要                                                               |
| 6  | モニター           | ディスプレイに接続する場合必要                                                               |
| 7  | Keyboard          | ディスプレイに接続する場合必要                                                               |
| 8  | HDMIケーブル       | Raspberry Pi 4,5の場合はMicroHDMI⇔HDMI、Zero2の場合はMiniHDMI⇔HDMIが必要                     |
| 9  | MicroUSBコネクタ  | PI Zero2wを使用する場合、USB Type-A機器を使うには変換ハブが必要                              |
| 10 | ケース&ヒートシンク | 必要に応じてご利用ください                                                                   |
-->

## 事前準備

### 1. SDカードにOSの書き込み
* Raspberry Pi OS Imager ([ダウンロード先](https://www.raspberrypi.com/software/))
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3980579/2edbe014-f1e6-043a-5eef-df8bb0b82b84.png)
こちらのツールを使うことで簡単にSDカードにOSイメージを書き込むことができます。
Windows, Mac, Linuxそれぞれに対応しています。
書き込み時に、ホスト名、SSH、Wifi、タイムゾーン、キーボードレイアウトの指定も可能です。

Raspberry Pi OS Imagerの公式ドキュメントは以下になります: 

https://www.raspberrypi.com/documentation/computers/getting-started.html




### 2.Raspberry PiにAI Cameraを接続

* Raspberry Pi AI Cameraを開封すると以下のようなものが入っています

![IMG_7205.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3980579/5c666d38-aecf-f500-f33a-236f985b0eda.jpeg)
* 同封物一覧
  1. AI Camera
  2. DSIケーブル ディスプレイ用FPC(Standard-Standard 20cm)
  3. DSIケーブル ディスプレイ用FPC(Standard-Mini 20cm)
    Raspberry Pi 5、Pi Zeroシリーズを使用する場合はこちらのケーブルを使用します。 
  4. 小型フォーカス調整工具(画像中央にある白い丸いもの)
      * 工具を反時計回りに回すと近距離にピントが合い、時計方向に回転させると遠距離にピントが合います。
      




* Raspberry Pi AI cameraとRaspberry Piを接続していきます。
    * フラットケーブルには裏表の向きがあるのでご注意ください
        * Raspberry Piとカメラのそれぞれの本体側接点（金属端子）が下向きになるように挿入してください。

:::note info 
### ケーブルを基盤に固定する手順
1. 基盤側のラッチを軽く引き上げて開きます。
2. ケーブルを正しい向き(画像のように黒いラッチがついてる側はケーブルの外側になるような向き)で挿入します。
3. ラッチを下ろしてケーブルを固定します。
:::

:::note warn
ケーブルの差し込みができていない場合、カメラが正しく認識できない場合があるので正しく刺さっているかを確認ください。
:::
![IMG_7207.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3980579/7c684b3a-fa0e-7d03-5999-4a3d5bd5a39d.jpeg)

正しく取り付けができると画像のようになります。




## チュートリアル手順

これからRaspberryPi財団の公開している[公式ドキュメント](https://www.raspberrypi.com/documentation/accessories/ai-camera.html#prerequisites)に沿って進めていきます。



まずデバイスを起動後、デスクトップからターミナルを起動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3980579/3aa6e195-ef19-f60a-c2b4-40c3f81c2c46.png)
 


1.  必要なライブラリのインストール


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

        * 上記のコマンドを実行することで、IMX500センサーを動かすのに必要なファームウェアや関連ソフトウェアをまとめてインストールを行うことができます。以下の1~3を実行しています。
            1. `/usr/share/imx500-models/` にサンプルのAIモデルファイルの配置
            2. `rpicam-apps`にIMX500カメラ用のファイルの追加
            3. AI Camera向けパッケージ化ツールのインストール

:::note info
Raspberry Pi Zero2 Wでライブラリの更新処理や、大きなライブラリをインストールする場合、メモリが不足することにより時間がかかる場合があります。
時間に余裕をもって実施していただくか、必要に応じてswap領域(仮想メモリ)の確保をしておくこともおすすめです。
:::

ちなみにこのライブラリをインストールされることで、自動的に配置されるAIモデルの一覧は以下になります。
こちらから直接DLしてきて利用することも可能です。

 https://github.com/raspberrypi/imx500-models





* ドライバを読み込むためにデバイスを再起動します
     * `sudo reboot`
     
*  起動時にI2Cバス上に接続されたIMX500カメラセンサーを検出し、正しく認識・初期化していることは以下で確認できます。
    * `sudo dmesg | grep imx500`
        * 正しく認識されていると以下のように`imx500`の表記が現れます。
        * もし表示されていない場合、ライブラリのインストールが正しくできなかった可能性があるのでログをご確認ください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3980579/86fc288b-d597-ba26-0eef-f579350365ce.png)


### サンプルスクリプトを試してみる🎮

#### 1. オブジェクト検知

##### 実行スクリプト
```
rpicam-hello -t 0s --post-process-file /usr/share/rpi-camera-assets/imx500_mobilenet_ssd.json --viewfinder-width 1920 --viewfinder-height 1080 --framerate 30
```

##### 実行結果
* 新しいAIモデルの書き込みの場合、AIモデルの書き込みに数分かかります。
* AI Cameraへのモデルの読み込み後、以下のように結果が可視化されます🍊

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3980579/21d5aaa9-3e0a-35fc-6602-726302e6c452.png)



#### 2.骨格推定

##### 実行スクリプト

```
rpicam-hello -t 0s --post-process-file /usr/share/rpi-camera-assets/imx500_posenet.json --viewfinder-width 1920 --viewfinder-height 1080 --framerate 30
```

##### 実行結果

* 以下のように可視化結果が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3980579/a9f1f0c1-b8ff-1414-a66e-b2136948e432.png)

* ちなみに実行するためのパラメータは`imx500_posenet.json` にて定義されています。
    * ここにAIモデルを実行するためのパラメータ、検出の閾値が設定されています。
    * デフォルトの値は以下のようになっています。
```
pi@raspberrypi:~ $ cat /usr/share/rpi-camera-assets/imx500_posenet.json
{
    "imx500_posenet":
    {
        "max_detections" : 5,
        "threshold" : 0.4,
        "offset_refinement_steps": 5,
        "nms_radius": 10.0,
        "network_file": "/usr/share/imx500-models/imx500_network_posenet.rpk",

        "save_input_tensor":
        {
            "filename": "/home/pi/posenet_input_tensor.raw",
            "num_tensors": 10
        },

        "temporal_filter":
        {
            "tolerance": 0.3,
            "factor": 0.3,
            "visible_frames": 8,
            "hidden_frames": 2
        }
    },

    "plot_pose_cv":
    {
        "confidence_threshold" : 0.2
    }
}

```

<details>
<summary>各パラメータの詳細はこちら</summary>

<br>

| パラメータ                               | 説明                                                                                                                                                                                                | デフォルト値                                                         |
|-----------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------|
| **max_detections**                      | 検出するポーズ（人物）の最大数。                                                                                       | `5`                               |
| **threshold**                           | ポーズを検出する際のスコア（信頼度）のしきい値。これよりも低いスコアは無視されます                                                                                                                 | `0.4`               |
| **offset_refinement_steps**             | 関節座標を微調整（補正）するステップ数。値を増やすと精度が上がる一方、処理負荷が高まる。                                                                                               | `5`                                                         |
| **nms_radius**                          | （NMS: Non-Maximum Suppression）で使用する半径。近い位置に重複して検出されたポーズをまとめたり除外したりするときに使用する。                                                               | `10.0`                                                      |
| **network_file**                        | PoseNet の学習済みモデルファイル（IMX500 用 `.rpk`）のパス。                                                                                                                                       | `/usr/share/imx500-models/imx500_network_posenet.rpk`     |
| **save_input_tensor.filename**          | 推論入力のテンソル（raw データ）を保存する先のファイルパス。デバッグや可視化に使用します。                                                                                                           | `/home/pi/posenet_input_tensor.raw`                       |
| **save_input_tensor.num_tensors**       | 何フレーム分の入力テンソルを連続して保存するか。指定回数分保存したら停止します。                                                                                                                     | `10`                                                        |
| **temporal_filter.tolerance**           | ポーズが大きく変化した際、どの程度まで過去情報を維持するかを制御する許容誤差のしきい値。                                                                                                             | `0.3`                                                       |
| **temporal_filter.factor**              | 時系列フィルタの係数。値が大きいほど過去情報を強く反映し、出力が滑らかになりますが、動きの速い動作への追従が遅くなる場合があります。                                                                  | `0.3`                                                       |
| **temporal_filter.visible_frames**      | 連続してポーズが検出されているとき、過去何フレーム分の情報を利用するかを設定。                                                                                                                       | `8`                                                         |
| **temporal_filter.hidden_frames**       | 一時的に検出が途切れた場合でも、直近の情報を維持してポーズを補完するためのフレーム数。                                                                                                               | `2`                                                         |
| **confidence_threshold** (plot_pose_cv) | OpenCV などで結果を可視化するときに、可視化対象とする最低スコア。値が低い関節は表示対象外にして誤検出を減らします。                                                                                  | `0.2`                                                       |

</details>







### Picamera2のサンプルスクリプト💻

次に、Picamera2 を使用したサンプルアプリを試してみましょう。
Picamera2 は、Raspberry Pi 向けの Python ライブラリで、カメラモジュール（特に Raspberry Pi AI Camera や純正カメラ）を簡単に制御・利用できるようにするツールです。


Picamera2 の公式ドキュメントは、以下のリンクから参照できます。

https://www.raspberrypi.com/documentation/accessories/ai-camera.html#picamera2



#### 環境構築

* 多くのサンプルアプリはOpenCVを使用します。そのため以下をインストールします。
```
sudo apt install python3-opencv python3-munkres
```

次にサンプルスクリプトを準備します。


```
git clone https://github.com/raspberrypi/picamera2.git
cd picamera2/examples/imx500
```
上記のフォルダにはそれぞれAIモデルのタスクに応じたサンプルスクリプトが格納されています。
* imx500_classification_demo.py
    * Classification用
* imx500_object_detection_demo.py
    * Object Detection用
* imx500_pose_estimation_higherhrnet_demo.py
    * Pose Estimation用
* imx500_segmentation_demo.py
    * Segmentation用

### サンプルスクリプトの実行

#### 1. クラス分類

##### 実行スクリプト

```
python imx500_classification_demo.py --model /usr/share/imx500-models/imx500_network_efficientnet_bo.rpk
```

##### 実行結果
* 左上に推論結果が表示されます。今回は正しくオレンジと判定されていることがわかります。
* COCOデータセット[^1]に含まれている画像を画面越しに撮影してみて挙動を確認しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3980579/2baa1984-e21e-96e8-c884-74624312d02c.png)



#### 2. ObjectDetection

##### 実行スクリプト

```
python imx500_object_detection_demo.py --model /usr/share/imx500-models/imx500_network_efficientdet_lite0_pp.rpk
```
##### 実行結果

* 検出したオブジェクトのバウンディングボックスが表示されています。
* 正しくOrangeと認識できています

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3980579/25317f3e-cdea-b461-89c8-6746de474984.png)

#### 3. 骨格推定

##### 実行スクリプト

```
python imx500_pose_estimation_higherhrnet_demo.py --model /usr/share/imx500-models/imx500_network_higherhrnet_coco.rpk
```

##### 実行結果

* 実行すると検出したキーポイントが可視化されます。
<!--
* 3人のキーポイントを検出できていることがわかります

* こちらもCOCOデータセット[^1]に含まれている画像を画面越しに撮影してみて挙動を確認しています。

 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3980579/d2418d25-fc85-5147-b754-163715933fba.png)
-->



#### 4. セグメンテーション

##### 実行スクリプト

```
python imx500_segmentation_demo.py  --model /usr/share/imx500-models/imx500_network_deeplabv3plus.rpk
```

##### 実行結果

* セグメンテーションした結果がマスクで可視化されます。
* 今回はオレンジ色なのでわかりにくいですが、物体に対して正しくマスク抽出が行えていることがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3980579/cfc0b11e-9a57-06b8-538a-2c1566792bb7.png)

### Q&A 🔍
最後に、よくあるエラーについてもまとめます。何かあればご参考にしてください。


- `imx500-all` パッケージをインストールしようとした際、「パッケージが見つからない」と表示されることがあります。これは **Bookworm OS 以降が対象**になっているためで、対応バージョン以外では利用できません。  
  Bookwormを使用している場合は、以下のコマンドでパッケージ情報を更新することで、インストールできるようになります。

  ```bash
  sudo apt update && sudo apt full-upgrade
  ```

- また、サンプルスクリプトの実行中に次のようなエラーが発生することがあります：

  ```
  ValueError: tensor info length 260 does not match expected size 708
  ```

  このエラーは、一部のライブラリが古いことが原因です。下記のようにアップデートすることで解消できます。

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


## まとめ

Raspberry Pi AI カメラでチュートリアルを一通り試してみました。
ラズパイにAIカメラを接続しサンプルスクリプトでAIを動かしてみるまで短時間でセットアップすることができます。


設置スペースが限られている場所でも活用できるのでますますエッジAIの利用がしやすくなってきたなと思います。

私も以下のような簡易的な治具を自作して、開発や検証に活用しています。ちょっとした固定や持ち運びが便利になるので、作業効率も上がります。

もしこの記事が参考になったり、「やってみたい」と思っていただけたら、ぜひ LGTM を押してもらえると嬉しいです！😊
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3980579/77ceea46-a9f9-470c-a8dc-1ee661c1f93d.png" width="400">




####  困った時は

もし、記事の途中でうまくいかなかった場合は、気軽にこの記事にコメントいただければと思います。

もしRaspberryPiに関連する疑問がある場合は下記フォーラムもご確認、ご活用ください。
- [Raspberry Pi Forums](https://forums.raspberrypi.com/)


[^1]: Microsoft COCO: Common Objects in Context[2014] https://arxiv.org/abs/1405.0312