Raspberry Pi, Nano Piを使った3Dカメラ ネットワーク サーバーの構築方法

# はじめに
以前に、cam2webをaeroTAP 3D USBカメラに接続して、Raspi/Nano Piをネットワーク３Dカメラ化する手順について説明しました。

今回は、cam2webに -image[?]起動パラメータを追加して、より実践で使えるように拡張したので、その使用方法について解説します。

Pasberry Pi3/4やNano Piの環境作成の方法については、前回の記事を参照してください。

https://qiita.com/nextEDGE-aeroTAP/items/5d33ee028969f219ea48

https://qiita.com/nextEDGE-aeroTAP/items/7d2d986637d16756553b

# 結果
各SBCにaeroTAP 3Dカメラを接続して、ブラウザから各種のフォーマットでリアルタイム ストリーミングが可能になります。

深度マップ+グレースケール画像を取得することで、JPGからRGBへの変換後の各画素データ(RGB 24Bit)には、
16Bit距離情報と8bitのグレースケール画像が得られることになります。
これを利用して、クライアントPCで複数の3Dカメラからの画像をリアルタイムで3D表示が可能になると思います。

|カラー画像 | グレースケール画像 | カラー深度マップ | 深度マップ+グレースケール画像|
|:-:|:-:|:-:|:-:|
| cam2web -image:0 |cam2web -image:1|cam2web -image:2|cam2web -image:3|
| ![color.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/568972/87d868f0-b3e4-91df-ee64-598bd0e13ad6.jpeg) |  ![gray.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/568972/8f51682c-bf08-acf1-3cb1-21c76944206e.jpeg) | ![depth,jpg.jfif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/568972/3a116c35-7582-510b-adc8-5a088e84cc19.jpeg)  | ![Depth+G.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/568972/5e78416b-ee07-eaba-bb90-004767ad2daf.jpeg)|

:::note info
クライアント側ソフトもこちらに公開しました。
:::
https://qiita.com/nextEDGE-aeroTAP/items/3a3cb7b21ccc5fdf43b0


# 準備するもの
- Raspberry Pi4 ( またはPi3 )、またはNano Pi NEO3
- aeroTAP 3D USBカメラ
- PC ( Putty,ブラウザ)
- cam2web for aeroTAPキット

Githubから最新の最新のcam2web for aeroTAPキットをダウンロードします。

https://github.com/Taisuke-S/cam2web-aeroTAP

# ビルド
キットをgitコマンドで入手します。
```
git clone https://github.com/Taisuke-S/cam2web-aeroTAP.git
```

## Raspberry Pi3環境の場合の修正箇所
Raspberry Pi3環境でビルドする場合、~/cam2web-aeroTAP/src/app/linux/Makefile(96行目)の修正が必要です。

```perl:
Makefile
	$(COMPILER) -o $@ $(OBJ) $(LDFLAGS) -L/home/pi/cam2web-aeroTAP/src/core/cameras/aeroCAM/lib/linux_arm.pi3
```


## cam2web のビルド
cam2web をGitHubからダウンロードして、いくつかのaeroTAP 3Dカメラを使うためにカメラ部分のコードを変更します。

1. ~/cam2web-aeroTAP/src/core/cameras/aeroTAPフォルダーのファイルを　~/cam2web-aeroTAP/src/core/cameras/V4L2フォルダーに上書きします。

```perl:
tar -vxzf cam2web.tar.gz
cp ~/cam2web-aeeoTAP/src/care/cameras/aeroTAP ~/cam2web-aeroTAP/src/core/cameras/V4L2
cd ~/cam2web-aeeoTAP/src/tools/web2h/make/gcc
make
cd ~/cam2web-aeroTAP/src/apps/linux
make
```

# 実行の準備
## aeroTAP SDK ライブラリを共有ライブラリパス LD_LIBRAY_PATHに追加
Raspberry Pi4の場合:
```perl:
export LD_LIBRARY_PATH=/home/pi/cam2web-master/src/core/cameras/aeroTAP/lib/linux_arm:$LD_LIBRARY_PATH
```
Raspberry Pi3の場合:
```perl:
export LD_LIBRARY_PATH=/home/pi/cam2web-master/src/core/cameras/aeroTAP/lib/linux_arm.pi3:$LD_LIBRARY_PATH
```

Nano Piの場合:
```perl:
export LD_LIBRARY_PATH=/home/pi/cam2web-master/src/core/cameras/aeroTAP/lib/linux_aarch64:$LD_LIBRARY_PATH
```

cam2webを実行する前に、コマンドライン パラメータを確認してください。

```perl:
./cam2web -?
```
- size パラメータで解像度を選択
- image パラメータで出力フォーマットを選択

深度マップ+グレースケール画像
```perl:
./cam2web -image:3
```

# ブラウザからのアクセス
cam2webが実行できたら、PCのブラウザからアクセスしてみます。
例えば、PiのIPアドレスが192.168.1.131の場合、以下のURLを開きます。

`http://192.168.1.131:8000`

単に、ストリーミングする場合:
`http://192.168.1.131:8000/camera/mjpeg`

単に、1枚の画像としてダウンロードする場合:
`http://192.168.1.131:8000/camera/jpeg`

# aeroTAP 3D USBカメラの接続時の注意
使用するaeroTAP 3D USBカメラの種類により、利用可能な解像度、またRaspi/Nano PiのUSB3.0ポートに接続できません。以下の表を参照してください。

:::note warn
USB3が利用できないカメラをUSB3.0ポートに接続する場合、USB2.0ハブを介して接続してください。
:::

|aeroTAP 3D G2 | aeroTAP 3D | aeroTAP 3D GS |
|:-:|:-:|:-:|
| USB2/3が利用可能 |  USB2のみ | USB2のみ  |
| 320x240  |  320x240 | -  |
| 640x480  | 640x480  | 640x480  |
|  -   | 640x400  | -  |
|  1280x720   | -  | 1280x720   | 


![USB20HUB.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/568972/95b74741-9eca-b785-91d7-286a3e679378.jpeg)


## 別の方法として、ソースを編集して強制的にUSB2.0モードで接続している状態にします。
~/cam2web-master/src/core/cameraa/V4L2/XV4L2Camera.cpp ファイルの編集
443行目をコメントアウトして、再ビルドしてください。

```perl:
//		bUSB20 = camera.getUSB20();
```

# 機能拡張
WebApiの機能拡張を行いました。クライアントアプリから3Dデータを取得して3D処理するために必要な拡張です。
- Image Typeを https://ip:port/camera/info で取得できるようにしました。
```json:
{"status":"OK","config":{"device":"Video for aeroTAP 3D Camera","height":"480","title":"Video for aeroTAP 3D Camera","width":"640"}}
```
- FocalLengthの値を https://ip:port/camera/config で取得できるようにしました。値は1000倍した値です。利用するには、float FocalLengthW/1000 として使います。
```json:
{"status":"OK","config":{"AutoExposure":"3","AutoWhiteBalance":"1","FocalLengthH":"414426","FocalLengthW":"414426"}}
```
1台のPCから複数の3Dカメラサーバーを3Dモデルで表示するためのアプリを作っています。
必要なWebAPIを今後も追加していきます。

# 追記 2022.08.24
## AngleX 値の追加
これは、カメラを下向きに傾けて設置する際の角度を表します。3D再構築する際に、カメラの傾きが分かると、上下位置を正しく構築できます。
また、"ImageType"も /configに移動しました。

https://ip:port/camera/config で取得できます。

```json:
{"status":"OK","config":{"AngleX":"0","device":"Video for aeroTAP 3D Camera","height":"480","title":"Video for aeroTAP 3D Camera","width":"640"}}
```
## ImageType値の変更
https://ip:port/camera/config へJSONフォーマットでPOSTすることでで設定を変更できるようにしました。
例えば、{"ImageType":"0"} をPOSTすると、カラー画像に切り替わります。
クライアント側から制御できるのがいいです。

## BMPのサポートの追加
知らずに、画像がJPEGでストリーミングするためImageType=3で深度マップRAW値とグレースケール画像を同時にストリーミングした場合、クライアント側で100%再生できない(JPEG圧縮のため)ことが分かりました。JPEG圧縮を100%としてもあまり改善されませんでした。
そのため、クライアント側で、正確に3D再構築するために、BMP形式で受信する方法にしました。
以下の方法でファイルを取得できるようにしました。

```
http://IP:PORT/camera/bmp 
```


# 関連情報

https://qiita.com/nextEDGE-aeroTAP/items/b97282bb856fad4ad6cf

https://qiita.com/nextEDGE-aeroTAP/items/3a3cb7b21ccc5fdf43b0