はじめに
どのご家庭にも、あまっているRaspberry Piの一つや二つがあると思いますので、さくっと物体検出できるようにしてみます。
なお、手順はほとんどこちらの日本語訳になります。
(違いは、エラーに対応しただけ)
材料
- Raspberry Pi(今回は3B+を使用)
- Webカメラ
なお、OSはRaspbian GNU/Linux 10 (Buster)で確認しました。
また、結構容量を食いますので、SDカードのサイズは大き目がいいです。(今回は128GBで確認)
環境構築
ひたすら、Raspberry Piにライブラリ等をインストールしていきます。
なお、途中でうまくインストールできなかったときは、何はともあれ「sudo apt-get update」を試してみてください。
Raspberry Piのアップデート
updateとupgradeを行います。
$ sudo apt-get update
$ sudo apt-get dist-upgrade
なお、upgradeには時間がかかります。
TensorFlowのインストール
Deep LearningのフレームワークのひとつであるGoogleのTensorFlowをインストールします。
$ pip3 install tensorflow
次にTensorFlowが使用しているLibAtlasをインストールします。
$ sudo apt-get install libatlas-base-dev
さらにTensorFlowの物体検出の実行に必要なパッケージをインストールしていきます。
$ sudo pip3 install pillow lxml jupyter matplotlib cython
$ sudo apt-get install python-tk
OpenCVのインストール
TensorFlowの物体検出では通常matplotlibで画像の表示を行っているのですが、OpenCVを使ったほうが簡単でエラーも少ないので、ここではOpenCVを使用します。
まずOpenCVの実行に必要なパッケージをインストールします。
$ sudo apt-get install libjpeg-dev libtiff5-dev libjasper-dev libpng12-dev
$ sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev libv4l-dev
$ sudo apt-get install libxvidcore-dev libx264-dev
$ sudo apt-get install qt4-dev-tools libatlas-base-dev
次にOpenCV本体をインストールします。
$ sudo pip3 install opencv-python
Protocol Buffersのインストール
TensorFlowの物体検出ではGoogleのProtocol Buffersも使用していますので、こちらをインストールします。
(以前はコンパイルしないといけませんでしたが、今はパッケージがあります)
$ sudo apt-get install protobuf-compiler
TensorFlowのModel Gardenの取得
物体検出などいくつかのモデルを実装したTensorFlowのModel Gardenを取得します。
まずは、保存するディレクトリを用意します。
今回は「tensorflow1」という名前にしました。
$ mkdir tensorflow1
$ cd tensorflow1
カレントディレクトリを移動したら、そこにGitから取得します。
$ git clone --depth 1 https://github.com/tensorflow/models.git
次に、取得したソースコードにパスを通します。
まず、ファイル「.bashrc」をエディタで開きます。
$ sudo nano ~/.bashrc
ファイルの一番最後に、以下の1行を追加し、保存してファイルを閉じます。
export PYTHONPATH=$PYTHONPATH:/home/pi/tensorflow1/models/research:/home/pi/tensorflow1/models/research/slim
その後、変更を反映させるため、ターミナルを再起動します。
(「source ~/.bashrc」でもOK)
次に、取得したソースコードの中に.protoファイルがあるので、これをPythonのコードに変換します。
$ cd /home/pi/tensorflow1/models/research
$ protoc object_detection/protos/*.proto --python_out=.
カレントディレクトリを、物体検出のホームディレクトリに変更します。
以降実行時も、この場所で行います。
$ cd /home/pi/tensorflow1/models/research/object_detection
今回は、物体検出のモデルとして「SSD(SSD_Lite)」を使用します。
また、Raspberry Piで実行することから、軽めのネットワークである「MobileNet v2」を使用します。
これらを使ってMicrosoft COCOデータセットを事前に学習したモデルをダウンロードします。
$ wget http://download.tensorflow.org/models/object_detection/ssdlite_mobilenet_v2_coco_2018_05_09.tar.gz
$ tar -xzvf ssdlite_mobilenet_v2_coco_2018_05_09.tar.gz
これで準備は完了です。
物体検出の実行
まず、実行するためのソースコード(Pythonなので、実行モジュールではなく、スクリプトファイルになります)を取得します。
$ wget https://raw.githubusercontent.com/EdjeElectronics/TensorFlow-Object-Detection-on-the-Raspberry-Pi/master/Object_detection_picamera.py
取得したファイルを実行します。
$ python3 Object_detection_picamera.py --usbcam
※カメラ画像のウィンドウが表示されるまでに、ワーニング等のメッセージを出力しつつ、30秒ぐらいかかります
なお、WebカメラではなくRaspberry Pi専用の「Picamera」を使用して実行する場合は、引数の「--usbcam」を削除してください。
終了するときは、ターミナルのほうで「Ctrl-C」で止めます。
残念ながら、フレームレートが1fpsぐらいですので、もっと速くしたい場合はアクセラレータ等の使用をお勧めします。
エラー対応
私の環境では、実行時にエラーになってしまいました。
$ python3 Object_detection_picamera.py --usbcam
Traceback (most recent call last):
File "Object_detection_picamera.py", line 23, in <module>
import cv2
File "/usr/local/lib/python3.7/dist-packages/cv2/__init__.py", line 3, in <module>
from .cv2 import *
ImportError: /usr/local/lib/python3.7/dist-packages/cv2/cv2.cpython-37m-arm-linux-gnueabihf.so: undefined symbol: __atomic_fetch_add_8
対処方法として、事前にライブラリを読み込んでおくようにします。
ファイル「.bashrc」をエディタで開きます。
$ sudo nano ~/.bashrc
ファイルの最後の以下の1行を追加して、保存します。
export LD_PRELOAD=/usr/lib/arm-linux-gnueabihf/libatomic.so.1
最後のに変更を反映させます。
(ターミナルを再起動してもいいです)
$ source ~/.bashrc
これで正常に動作するようになります。
注意事項
長時間(5分以上)実行し続けると、CPUがとても熱くなってしまい、シャットダウンしてしまうことがあります。
その場合はCPUにヒートシンクを付ける等の対策をしてください。
まとめ
少々時間はかかりますが、手順通りにたどっていけば、ほぼ問題なく簡単にRaspberry Piで物体検出の環境が構築できます。
参考URL
https://github.com/EdjeElectronics/TensorFlow-Object-Detection-on-the-Raspberry-Pi
https://qiita.com/kobayuta/items/59c7b84caf8994071357
https://github.com/EdjeElectronics/TensorFlow-Object-Detection-on-the-Raspberry-Pi/issues/67
https://qiita.com/XM03/items/48463fd910470b226f22