Raspberry Piを用いた疑似ドライブレコーダー（物体検出，記録，自動起動）に関するメモ

# きっかけ

Rasberry Pi 3Bをドローンに組み込み，行動監視や動体追跡，ベイズ最適化による行動最適化など遊んでいたところ，
ふと，持ち運びしやすいパソコンとしてRasberry Pi 3Bを購入したはずなのにドローンごと持ち運んでいては意味がないのでは，との高度に哲学的な疑問に行き着いた．

そこでRaspberry Pi 4B 8GBモデルを買い足した．
メモリが増えたことによりどこまでできるようになったか知りたかったため，深層学習系の物体検知モデル（TensorFlow-Lite-Object-Detection-on-Android-and-Raspberry-Pi）を動かし，ついでドライブレコーダっぽく使えるか試すために，自動起動（systemd）など試みてみたのであった．

# 参考・利用
**Raspberry Piで、オリジナルの学習モデルを使った物体検出（Raspberry Piの環境構築編）[3/4]**
https://dream-soft.mydns.jp/blog/developper/smarthome/2021/02/2881/

**EdjeElectronics/TensorFlow-Lite-Object-Detection-on-Android-and-Raspberry-Pi**
https://github.com/EdjeElectronics/TensorFlow-Lite-Object-Detection-on-Android-and-Raspberry-Pi

# 環境
・Raspberry Pi 4B 8GB
・Raspberry Pi OS Full（32bit）(10 buster)
・Raspberry Pi Camera Module 2

# Raspberry Pi 4Bの初期設定
ありふれた設定はおいておいて忘れやすいものを
### 日本語入力インストール

```python:
sudo apt update
sudo apt install ibus-mozc
```

### カメラテスト

```python:
sudo rpi-update
raspistill -o image.jpg
```

### フォルダ名を英語表記に

```python:
LANG=C xdg-user-dirs-update --force
```

### モニタ非接続用設定

```python:
sudo nano /boot/config.txt
```
hdmi_force_hotplug=1有効化

# 物体検知モデルのインストールから試運転
・TensorFlow-Lite-Object-Detection-on-Android-and-Raspberry-Pi

```python:
pip3 install tensorflow==1.14.0
sudo pip3 install opencv-python==4.1.0.25

git clone https://github.com/EdjeElectronics/TensorFlow-Lite-Object-Detection-on-Android-and-Raspberry-Pi.git
mv TensorFlow-Lite-Object-Detection-on-Android-and-Raspberry-Pi tflite
cd tflite/
sh get_pi_requirements.sh 

wget https://storage.googleapis.com/download.tensorflow.org/models/tflite/coco_ssd_mobilenet_v1_1.0_quant_2018_06_29.zip
unzip coco_ssd_mobilenet_v1_1.0_quant_2018_06_29.zip -d coco_ssd_mobilenet_v1_1.0_quant

cd tflite/
python3 TFLite_detection_webcam.py --modeldir=./coco_ssd_mobilenet_v1_1.0_quant
```

起動・動作確認．

# systemdによる自動起動の設定
・X server errorが起きる，tensorflowがimportできない，オプションが使えない，などいくらか悩んだ．試行錯誤した結果を下記記載する．最適解ではないであろうがとりま．
###1．shファイル作成
shファイルを介さない条件では動かすことができなかった．
X server errorを避けるため暫定の解決手段としてsleep 20を入れた．

```bash:
sudo nano /opt/object_detection.sh 
```

```bash:object_detection.sh  
#!/bin/sh
sleep 20;
cd /home/pi/tflite
/usr/bin/python3 TFLite_detection_webcam.py --modeldir=./coco_ssd_mobilenet_v1_1.0_quant
```

```bash:
sudo chmod a+x /opt/object_detection.sh
```

### 2．serviceファイル作成

```bash:
sudo nano /etc/systemd/system/object_detection.service
```

```bash:object_detection.service
[Unit]
Description=autoboot detection

[Service]
ExecStart=/opt/object_detection.sh
Restart=always                                           

[Install]
WantedBy=graphical.target
```

### 3．プログラム本体の改変
・TFLite_detection_webcam.py

・systemdでは次のパス（のみ）が通っていなかったため追加（shで対応しても良い）

```python:
import sys
sys.path.append("/home/pi/.local/lib/python3.7/site-packages")
```

・モニタなしのヘッドレスで動かすためコメントアウト

```python:
#cv2.imshow('Object detector', frame)
```

・frameをjpg形式でUSBに保存してゆく．条件は適当に

```python:
while True:
    ～省略
    cv2.imwrite('/media/pi/RASP4DATA/save_traffic_jpg/'+str(jpgfiles_max)+'.jpg', frame)
    jpgfiles_max += 1
    if jpgfiles_max>5000:
        jpgfiles_max = 0
    など
```

### 4．service起動とテスト

```python:
sudo systemctl daemon-reload
sudo systemctl enable object_detection.service
sudo systemctl start object_detection.service
sudo systemctl status object_detection.service
```
● object_detection.service - autoboot detection
   Loaded: loaded (/etc/systemd/system/object_detection.service; enabled; vendor pre
   Active: active (running) since Thu 2021-12-30 10:48:08 JST; 5s ago
 Main PID: 4234 (object_detection.sh)
    Tasks: 3 (limit: 4915)
   CGroup: /system.slice/object_detection.service
           ├─4234 /bin/sh /opt/object_detection.sh
           └─4235 /usr/bin/python3 TFLite_detection_webcam.py --modeldir=./coco_
12月 30 10:48:08 raspberrypi systemd[1]: Started autoboot detection.
12月 30 10:48:09 raspberrypi object_detection.sh[4234]: 2021-12-30 10:48:09.876082: 
lines 1-11/11 (END)

・以降，Raspberry Piを起動するたびにTFLite_detection_webcam.pyが自動起動し，物体検出した画像をjpg形式でUSBに保存し続ける．

# 自動車に設置
・Raspberry Pi 4Bは3Aほど要求する．電源問題は地味に厄介．

#要事，USBからjpgを吸い出し動画に加工

```python:
import sys
import os
import cv2

fourcc = cv2.VideoWriter_fourcc('m', 'p', '4', 'v')
video = cv2.VideoWriter('save_traffic_jpg.mp4',fourcc, 20.0, (1280, 720))

PATH = '/media/pi/RASP4DATA/save_traffic_jpg/'
jpgfiles = os.listdir(PATH)
jpgfiles_num = [int(w[:-4]) for w in jpgfiles if '.jpg' in w]
jpgfiles_num.sort()
print(jpgfiles_num)

for jpgfile_num in jpgfiles_num:
    img = cv2.imread(PATH+str(jpgfile_num)+'.jpg')
    video.write(img)
video.release()
```

・こんな感じとなるはずです．
![video100.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284074/60a4e2ff-aa17-d9e4-1232-eef76bc99e22.gif)


# 今後やりたいこと
・CLIPを用いたより重い物体認識・解釈．
　8GBもメモリがあればできるかも・・・
　CLIPを用いた画像のテキストによる説明と、その発展可能性に関する試行
　https://qiita.com/kzuzuo/items/e35e0c0535f0d32b135e
　＊とりま，pytorchインストールまで

```python:
sudo apt install libopenblas-dev libblas-dev m4 cmake cython python3-dev python3-yaml python3-setuptools
sudo apt-get install libavutil-dev libavcodec-dev libavformat-dev libswscale-dev
#https://github.com/sungjuGit/PyTorch-and-Vision-for-Raspberry-Pi-4B
cd /home/pi/Downloads
sudo pip3 install torch-1.8.0a0+56b43f4-cp37-cp37m-linux_armv7l.whl
sudo pip3 install torchvision-0.9.0a0+8fb5838-cp37-cp37m-linux_armv7l.whl
```

Googleが2022にViLD発表
Open-vocabulary Object Detection via Vision and Language Knowledge Distillation
https://arxiv.org/abs/2104.13921

・センサーをつけて野生動物撮影用トレイルカメラ代わりとし，物体検出を利用して検出動物の記録csv自動作成・送信．
　面白いかもしれない．
・未知データ含め実用とするには・・・分類が限定されやすい画像分類モデルでなく，深層距離学習が必要かな・・・ArcFaceなど現在の技術はどうなっているのだっけか．

・・・

#その後
Raspberry Pi 4BはドライブレコーダーとしてND5RCに固定され，
持ち運びしやすいパソコンは，やはり無いままなのであった．

年末年始は普段乗り慣れていない方々が運転するためか予想できない危険な目に遭う機会が通常より多くなるでしょう．
ドライブレコーダーで身を守りつつお気をつけて！