I wrote it in English in the comment section.
#◆ はじめに
Raspberry Pi 3 model B+ へ、タイトル記載のディープラーニング(DeepLearning)環境をインストール・構築する。
OSを導入するところからのクリーンな状態での作業を前提とし、初期状態から着手すれば、ほぼコピー&ペーストだけでつまづくことなく完了するはず。
ごちゃごちゃするのは好きではないため、pyenv, virtualenv は使用しない。
パーミッションの設定は適当とし、セキュリティは特に考慮しない。
同じパッケージを何度も導入しようとしているところ、無駄なパッケージをインストールしようとしているところはご愛敬で。
ノーミス・ノンストップで走っても半日以上かかるのでかなりの覚悟が必要。
ちなみに、Intel が公開しているNCS導入スクリプトはそのままではopenCVがまともに入らないので注意。
Stretchは初回起動時にSDのパーティション拡張を自動で実行してくれるため、Jessieより若干手順が楽。
SSHで作業している場合は、時間の掛かるスクリプト部分でターミナルがタイムアウトしてしまうことが多いため、Raspberry Pi→HDMI→ディスプレイ、の直接接続構成での作業をお勧めする。
次回は、Neural Compute Stickの3本挿し(Multi Stick構成)を試そうと思う。
結果だけ言うと1本でも次回の実装のほうが遥かに動作が速い。
https://qiita.com/PINTO/items/7f13fcb7c894c27691b2
次次回の実装は次回の実装より更に2倍速く動作する。
https://qiita.com/PINTO/items/db3ab44a3e2bcd87f2d8
そして更に上記のどれよりも速く高精度なMobileNet-SSDによる実装。
HW構成次第ではRaspberryPiで10FPS以上を達成。
https://qiita.com/PINTO/items/b97b3334ed452cb555e2
Raspbian JessieにてNCS無しの類似構成でSingle Shot MultiBox Detector環境を構築した前回の記事はこちら。
https://qiita.com/PINTO/items/bbf5ff907966f213fbdf
#◆ 環境 [2017.12.11時点]
・Windows 10 Pro [作業用PC] + TeraTerm
・Raspberry Pi 3 model B+
・Intel Movidius Neural Compute Stick https://developer.movidius.com/
・Raspbian Stretch 2017-11-29
・NCS SDK v1.11.00.04 → [2018.01.10 VerUp] v1.12.00
・ROS kinetic 1.12.11
・samba 4.2.14
・Python 2.7.13、3.5.3(OS標準導入済)
・Tensorflow 1.4.0
・Keras 2.1.2(今回は使わないのでお好みで)
・OpenCV 3.3.1 → [2018.01.12 VerUp] 3.4.0
・Jupyter notebook(今回は使わないのでお好みで)
・MicroSD Card class10 SDHC 32GB
・USBキーボード、USBマウス、液晶テレビ、HDMIケーブル
・インターネット接続可能な有線LAN 又は Wi-Fi環境
#◆ Raspbian stretch のインストール
1.下記をダウンロード
http://ftp.jaist.ac.jp/pub/raspberrypi/raspbian/images/raspbian-2017-12-01/2017-11-29-raspbian-stretch.zip
2.ダウンロードされたzipを解凍
3.Win32DiskImagerをダウンロードしてインストール https://ja.osdn.net/projects/sfnet_win32diskimager/downloads/Archive/win32diskimager-1.0.0-install.exe/
4.SDカードをホストPCに挿入/接続
5.Win32DiskImagerを起動し、2017-11-29-raspbian-stretch.imgを指定して書き込み
6.Raspberry Pi 3 へSDカードを挿入して電源ON
7.スタートメニュー→設定→RaspberryPiの設定→インタフェース→必要なオプションを「有効」にする
8.スタートメニュー→設定→RaspberryPiの設定→ローカライゼーション
(1)ロケールの設定「ja」「JP」「UTF-8」
(2)タイムゾーン「Asia」「Tokyo」
(3)キーボードの設定「日本」「日本語」
(4)無線LANの国「JP Japan」
9.Wi-Fiの省電力モード無効化
$ sudo iwconfig wlan0 power off
10.rootユーザのパスワード設定
$ sudo passwd root ※好きなパスワードを登録
#◆ ROS [kinetic]のインストール
1.下記のコマンドを実行
$ sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'
$ wget https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -O - | sudo apt-key add -
$ sudo apt-get update
$ sudo apt-get -y upgrade
$ sudo apt-get install -y python-rosdep python-rosinstall-generator python-wstool python-rosinstall build-essential cmake
$ sudo apt-get install -y python-pip python-setuptools python-yaml python-distribute python-docutils python-dateutil python-six
$ sudo rosdep init
$ rosdep update
$ mkdir -p ~/ros_catkin_ws
$ pushd ~/ros_catkin_ws
$ rosinstall_generator ros_comm common_msgs tf --rosdistro kinetic --deps --wet-only --tar > kinetic-ros_comm-wet.rosinstall
$ wstool init src kinetic-ros_comm-wet.rosinstall
$ rosdep install -y --from-paths src --ignore-src --rosdistro kinetic -r --os=debian:stretch
$ sudo ./src/catkin/bin/catkin_make_isolated --install -DCMAKE_BUILD_TYPE=Release --install-space /opt/ros/kinetic -j2
$ popd
$ echo "source /opt/ros/kinetic/setup.bash" >> ~/.bashrc
$ source ~/.bashrc
$ sudo reboot
#◆ 環境変数の追加
1.下記のコマンドを実行
$ export ROS_HOSTNAME=raspberrypi.local
$ export ROS_IP=`hostname -I`
$ export ROS_MASTER_URI=http://192.168.xxx.xxx:11311
※`hostname -I`の部分はPCのホスト名を入力するのではなく、hostnameとそのままの文脈で入力する
※RaspberryPi側でマスターを起動する場合は、export ROS_MASTER_URI=http://`hostname -I`:11311
※上記の環境変数を削除する場合は、unset ROS_MASTER_URI
※RaspberryPi以外の端末をマスターとする場合はIP部分を読み替える
例)リモートのUbuntuをマスターとする場合は、Ubuntu側で下記を追加
PC起動のたびに下記コマンドを打つ必要があるため、~/.bashrcに書いておくと良い
$ export ROS_HOSTNAME=ubuntu.local
$ export ROS_IP=`hostname -I`
$ export ROS_MASTER_URI=http://`hostname -I`:11311
#◆ Sambaのインストール
1.下記のコマンドを実行
$ sudo apt-get install -y samba
$ sudo nano /etc/samba/smb.conf
2.設定ファイル(smb.conf)に下記を追記して保存
[pi]
path = /home/pi
read only = No
guest ok = Yes
force user = pi
[etc]
path = /etc
read only = No
guest ok = Yes
force user = root
[usr]
path = /usr
read only = No
guest ok = Yes
force user = root
[tmp]
path = /tmp
read only = No
guest ok = Yes
force user = root
[opt]
path = /opt
read only = No
guest ok = Yes
force user = root
3.sambaのデーモンを再起動する
$ sudo service smbd restart
#◆ TMP領域の拡張とログファイルのRAMDISK化
1.下記のコマンドを実行
$ cd /etc
$ sudo cp fstab fstab_org
$ sudo nano /etc/fstab
2.ファイルの末尾に下記を追記して保存
# TMP領域の拡張
tmpfs /tmp tmpfs defaults,size=512m,noatime,mode=1777 0 0
tmpfs /var/tmp tmpfs defaults,size=128m,noatime,mode=1777 0 0
# /var/log をRAMディスクにマウント
tmpfs /var/log tmpfs defaults,size=32m,noatime,mode=0755 0 0
# ~/.ros/log をRAMディスクにマウント
tmpfs /home/pi/.ros/log tmpfs defaults,size=32m,noatime,mode=1777 0 0
3.Raspberry Piを再起動
$ sudo reboot
#◆ 無用なシステムログの無効化
1.下記コマンドを実行
$ cd /etc
$ sudo cp rsyslog.conf rsyslog.conf_org
$ sudo nano rsyslog.conf
2.下記のように書き換えて保存する
###############
#### RULES ####
###############
#
# First some standard log files. Log by facility.
#
auth,authpriv.* /var/log/auth.log
*.*;auth,authpriv.none -/var/log/syslog
#cron.* /var/log/cron.log
daemon.* -/var/log/daemon.log
#kern.* -/var/log/kern.log
#lpr.* -/var/log/lpr.log
#mail.* -/var/log/mail.log
#user.* -/var/log/user.log
#
# Logging for the mail system. Split it up so that
# it is easy to write scripts to parse these files.
#
#mail.info -/var/log/mail.info
#mail.warn -/var/log/mail.warn
#mail.err /var/log/mail.err
#◆ Raspberry Pi起動時にログ出力先フォルダを自動生成するよう変更
1.下記コマンドを実行
$ cd /etc
$ sudo cp rc.local rc.local_org
$ sudo nano rc.local
2.既に入力済みの部分を下記のように書き換えて保存する
# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
printf "My IP address is %s\n" "$_IP"
fi
#
# RAMディスクに自動的にフォルダを追加
#
mkdir -p /var/log/ConsoleKit
mkdir -p /var/log/samba
mkdir -p /var/log/fsck
mkdir -p /var/log/apt
mkdir -p /var/log/ntpstats
#chown root.ntp /var/log/ntpstats
chown root.adm /var/log/samba
touch /var/log/lastlog
touch /var/log/wtmp
touch /var/log/btmp
chown root.utmp /var/log/lastlog
chown root.utmp /var/log/wtmp
chown root.utmp /var/log/btmp
exit 0
#◆SWAP領域の一時的な拡張 2018/03/17追記
これを実施しておかないとOpenCVのビルド時にスワップが大量に発生してフリーズする、かつ SWAP領域が不足してビルド中に異常終了する、 かつ ビルドが1日経っても終わらない。ビルドのシーケンスとdf -h
コマンド、free -h
コマンドの状況を張り付いて見ていたところ、OpenCVビルド時にはMEM:1GB + SWAP:1GB以上消費するようだ。単位はMB。
$ sudo nano /etc/dphys-swapfile
CONF_SWAPSIZE=2048
$ sudo /etc/init.d/dphys-swapfile restart swapon -s
$ free -h
#◆ 必要なパッケージの一部分インストール
1.下記のコマンドを実行する
$ sudo apt-get update
$ sudo apt-get upgrade
$ sudo apt-get install -y build-essential libc6-dev libncurses5-dev libncursesw5-dev libreadline6-dev libdb5.3-dev
$ sudo apt-get install -y libgdbm-dev libsqlite3-dev libssl-dev libbz2-dev libexpat1-dev liblzma-dev zlib1g-dev
$ sudo apt-get install -y cmake git pkg-config unzip qtbase5-dev python-dev python3-dev python-numpy python3-numpy
$ sudo apt-get install -y cmake-qt-gui mesa-utils libgl1-mesa-dri libprotobuf-dev protobuf-compiler libvtk6-dev
$ sudo apt-get install -y libvtk6-qt-dev python-vtk6 tcl-vtk6 libopencv-dev libgtk-3-dev libdc1394-22 libdc1394-22-dev
$ sudo apt-get install -y libjpeg-dev libpng12-dev libtiff5-dev libjasper-dev libavcodec-dev libavformat-dev
$ sudo apt-get install -y libswscale-dev libxine2-dev libgstreamer0.10-dev libgstreamer-plugins-base0.10-dev libv4l-dev
$ sudo apt-get install -y libmp3lame-dev libopencore-amrnb-dev libopencore-amrwb-dev libtheora-dev libvorbis-dev
$ sudo apt-get install -y libxvidcore-dev v4l-utils gfortran python-opencv libgtk2.0-dev libx264-dev libqt5core5a
$ sudo apt-get install -y libqtgui4 libqt4-test libqt4-opengl-dev libatlas-base-dev libeigen3-dev libtesseract-dev
$ sudo apt-get install -y libleptonica-dev tesseract-ocr tesseract-ocr-jpn tesseract-ocr-osd libblas-dev liblapack-dev
$ sudo apt-get install -y python-setuptools python3-decorator python3-scipy python3-pandas python3-h5py libhdf5-dev libpq5 libpq-dev apt-show-versions ffmpeg
$ sudo reboot
$ sudo pip3 install h5py;sudo pip3 install imageio;sudo apt-get update;sudo apt-get upgrade;sudo apt-get clean;
$ sudo apt-get clean;sudo pip3 install --upgrade pillow
$ sudo apt-get clean;sudo pip3 install --upgrade matplotlib
$ sudo apt-get update;sudo apt-get upgrade
$ sudo reboot
#◆ Python3.x版 Tensorflow1.4.0のインストール
1.下記のコマンドを実行
$ cd ~
$ mkdir tensorflow1.4.0;cd tensorflow1.4.0
$ wget https://github.com/lhelontra/tensorflow-on-arm/releases/download/v1.4.0/tensorflow-1.4.0-cp35-none-linux_armv7l.whl
$ sudo pip3 install tensorflow-1.4.0-cp35-none-linux_armv7l.whl
$ sudo apt-get update;sudo apt-get upgrade
$ python3
>>> import tensorflow
>>> exit()
#◆TBB (Intel Threading Building Blocks)の導入 2018/03/17追記
毎度ビルドするのが面倒なため、お手軽導入用パッケージを作った。
OpenCVの並列処理対応用。
あえて自分でビルドしたい物好きな人はこちらの手順
https://github.com/PINTO0309/TBBonARMv7/blob/master/TBB_BuildProcedure_2018U2_arm.txt
【導入による効果】
OpenCVの並列化クラスParallelLoopBodyとparallel_for_ - Qiita
C++17時代の並列ソート - Qiita
1.TBB(2018 U2)インストール用debファイルのダウンロード
$ cd ~
$ wget https://github.com/PINTO0309/TBBonARMv7/raw/master/libtbb-dev_2018U2_armhf.deb
2.下記のコマンドを実行してインストール
$ sudo dpkg -i ~/libtbb-dev_2018U2_armhf.deb
$ sudo ldconfig
#◆ Neural Compute Stick SDKのインストール
1.Neural Compute Stick をRaspberry PiのUSBポートへ挿入する
※Raspberry PiのUSBポート残りの3個のうち1個は、Neural Compute Stickの横幅が太いため挿せなくなる。
※常時4ポート使用したい場合はUSBハブの追加を検討する。
※このタイミングでNeural Compute Stickを挿しておかないと後続のビルドに失敗する、ように見える。
※処理途中に表示されるWarningは無視してもかまわない。
2.Neural Compute Stick SDKのインストール
【参考】https://movidius.github.io/ncsdk/install.html
$ cd ~
$ git clone https://github.com/movidius/ncsdk.git
$ cd ~/ncsdk
$ nano ./install-opencv.sh
3.下記のように、ファイル中盤あたりに記載されているopenCV周りの記述を変更して保存
※バックスラッシュ「\」は「半角の¥」に読み替える。
※この部分はOpenCVを単体でインストールしたい時のシーケンスとしてもそのまま使える。
cd ~
wget -O opencv.zip https://github.com/Itseez/opencv/archive/3.4.0.zip
unzip opencv.zip
wget -O opencv_contrib.zip https://github.com/Itseez/opencv_contrib/archive/3.4.0.zip
unzip opencv_contrib.zip
cd ~/opencv-3.4.0/
mkdir build
cd build
cmake -D CMAKE_CXX_FLAGS="-DTBB_USE_GCC_BUILTINS=1 -D__TBB_64BIT_ATOMICS=0" \
-D CMAKE_BUILD_TYPE=RELEASE \
-D CMAKE_INSTALL_PREFIX=/usr/local \
-D INSTALL_PYTHON_EXAMPLES=OFF \
-D OPENCV_EXTRA_MODULES_PATH=~/opencv_contrib-3.4.0/modules \
-D BUILD_EXAMPLES=OFF \
-D PYTHON_DEFAULT_EXECUTABLE=$(which python3) \
-D INSTALL_PYTHON_EXAMPLES=OFF \
-D BUILD_opencv_python2=ON \
-D BUILD_opencv_python3=ON \
-D WITH_OPENCL=OFF \
-D WITH_OPENGL=OFF \
-D WITH_TBB=ON \
-D BUILD_TBB=OFF \
-D WITH_CUDA=OFF \
-D ENABLE_NEON:BOOL=ON \
-D WITH_QT=OFF \
-D BUILD_opencv_dnn_modern=OFF ..
make -j $(($(nproc) + 1))
sudo make install
sudo ldconfig
4.下記のコマンドを実行
※ make examples
で openCV3.4.0/opencv_contrib3.4.0 が自動でフルインストールされる、ワーニングが4~5件表示されるが無視してよし
$ make install
$ make examples
$ sudo /bin/bash -c 'echo "/usr/local/lib" > /etc/ld.so.conf.d/opencv.conf'
$ sudo /bin/bash -c 'echo "/usr/lib" >> /etc/ld.so.conf.d/opencv.conf'
$ sudo ldconfig
$ sudo apt-get update
$ cd ~;sudo rm opencv.zip;sudo rm opencv_contrib.zip
$ python3
>>> import cv2
>>> exit()
$ sudo reboot
#◆ Keras2.1.2インストール
1.下記のコマンドを実行
$ sudo pip3 install keras
2.実行確認、importしてエラーが出なければ正常
$ python3
>>> import keras
Using TensorFlow backend.
>>> exit()
#◆ Jupyter notebookのインストール
1.下記のコマンドを実行
$ cd ~
$ git clone https://github.com/kleinee/jns.git
$ cd jns
$ sudo chmod +x *.sh
$ sudo pip3 install jupyter;sudo pip3 install readline;sudo pip3 install ipyparallel
$ ./configure_jupyter.sh
$ sudo ./install_tex.sh;sudo ./install_stack.sh;
2.Jupyterのインストール先パス確認
※ 表示されたパスは後続の作業で使用 (1)
$ which jupyter
3.Jupyter notebookの自動起動設定
$ sudo nano /etc/systemd/system/jupyter.service
※空のファイルが開かれるので下記のとおり入力して保存(notebookの左側のパスを(1)で置き換え)
[Unit]
Description=Jupyter notebook
[Service]
Type=simple
PIDFile=/var/run/jupyter-notebook.pid
ExecStart=/usr/local/bin/jupyter notebook ←(1)
User=pi
Group=pi
WorkingDirectory=/home/pi/notebooks
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
4.下記のコマンドを実行
$ sudo systemctl start jupyter;sudo systemctl enable jupyter;sudo systemctl status jupyter
$ sudo reboot
#◆ Jupyter notebook動作確認
1.操作用PCのブラウザから「http://(Raspberry PiのIPアドレス):8888/」にアクセス
2.ログインパスワード:jns
#◆ 後始末
1.下記コマンドを実行
$ sudo apt-get autoremove
$ sudo apt-get clean
#◆ Webカメラ + YoloV2 での複数動体検出環境の導入と味見
1.下記のコマンドを実行
$ cd ~
$ git clone https://github.com/duangenquan/YoloV2NCS.git
$ cd YoloV2NCS
$ nano ~/YoloV2NCS/src/PythonWrapper.cpp
※下記のとおり編集して保存。
//long buflen;
int buflen;
$ make
$ mvNCCompile ./models/caffemodels/yoloV2Tiny20.prototxt -w ./models/caffemodels/yoloV2Tiny20.caffemodel -s 12
$ cd detectionExample
$ mkdir utils
$ nano app_utils.py
2.下記のソースを全コピペ
# From http://www.pyimagesearch.com/2015/12/21/increasing-webcam-fps-with-python-and-opencv/
import struct
import six
import collections
import cv2
import datetime
from threading import Thread
from matplotlib import colors
class FPS:
def __init__(self):
# store the start time, end time, and total number of frames
# that were examined between the start and end intervals
self._start = None
self._end = None
self._numFrames = 0
def start(self):
# start the timer
self._start = datetime.datetime.now()
return self
def stop(self):
# stop the timer
self._end = datetime.datetime.now()
def update(self):
# increment the total number of frames examined during the
# start and end intervals
self._numFrames += 1
def elapsed(self):
# return the total number of seconds between the start and
# end interval
return (self._end - self._start).total_seconds()
def fps(self):
# compute the (approximate) frames per second
return self._numFrames / self.elapsed()
class WebcamVideoStream:
def __init__(self, src, width, height):
# initialize the video camera stream and read the first frame
# from the stream
#print(src)
self.stream = cv2.VideoCapture(src)
self.stream.set(cv2.CAP_PROP_FRAME_WIDTH, width)
self.stream.set(cv2.CAP_PROP_FRAME_HEIGHT, height)
(self.grabbed, self.frame) = self.stream.read()
# initialize the variable used to indicate if the thread should
# be stopped
self.stopped = False
def start(self):
# start the thread to read frames from the video stream
Thread(target=self.update, args=()).start()
return self
def update(self):
# keep looping infinitely until the thread is stopped
while True:
# if the thread indicator variable is set, stop the thread
if self.stopped:
return
# otherwise, read the next frame from the stream
(self.grabbed, self.frame) = self.stream.read()
def read(self):
# return the frame most recently read
return self.frame
def stop(self):
# indicate that the thread should be stopped
self.stopped = True
def standard_colors():
colors = [
'AliceBlue', 'Chartreuse', 'Aqua', 'Aquamarine', 'Azure', 'Beige', 'Bisque',
'BlanchedAlmond', 'BlueViolet', 'BurlyWood', 'CadetBlue', 'AntiqueWhite',
'Chocolate', 'Coral', 'CornflowerBlue', 'Cornsilk', 'Crimson', 'Cyan',
'DarkCyan', 'DarkGoldenRod', 'DarkGrey', 'DarkKhaki', 'DarkOrange',
'DarkOrchid', 'DarkSalmon', 'DarkSeaGreen', 'DarkTurquoise', 'DarkViolet',
'DeepPink', 'DeepSkyBlue', 'DodgerBlue', 'FireBrick', 'FloralWhite',
'ForestGreen', 'Fuchsia', 'Gainsboro', 'GhostWhite', 'Gold', 'GoldenRod',
'Salmon', 'Tan', 'HoneyDew', 'HotPink', 'IndianRed', 'Ivory', 'Khaki',
'Lavender', 'LavenderBlush', 'LawnGreen', 'LemonChiffon', 'LightBlue',
'LightCoral', 'LightCyan', 'LightGoldenRodYellow', 'LightGray', 'LightGrey',
'LightGreen', 'LightPink', 'LightSalmon', 'LightSeaGreen', 'LightSkyBlue',
'LightSlateGray', 'LightSlateGrey', 'LightSteelBlue', 'LightYellow', 'Lime',
'LimeGreen', 'Linen', 'Magenta', 'MediumAquaMarine', 'MediumOrchid',
'MediumPurple', 'MediumSeaGreen', 'MediumSlateBlue', 'MediumSpringGreen',
'MediumTurquoise', 'MediumVioletRed', 'MintCream', 'MistyRose', 'Moccasin',
'NavajoWhite', 'OldLace', 'Olive', 'OliveDrab', 'Orange', 'OrangeRed',
'Orchid', 'PaleGoldenRod', 'PaleGreen', 'PaleTurquoise', 'PaleVioletRed',
'PapayaWhip', 'PeachPuff', 'Peru', 'Pink', 'Plum', 'PowderBlue', 'Purple',
'Red', 'RosyBrown', 'RoyalBlue', 'SaddleBrown', 'Green', 'SandyBrown',
'SeaGreen', 'SeaShell', 'Sienna', 'Silver', 'SkyBlue', 'SlateBlue',
'SlateGray', 'SlateGrey', 'Snow', 'SpringGreen', 'SteelBlue', 'GreenYellow',
'Teal', 'Thistle', 'Tomato', 'Turquoise', 'Violet', 'Wheat', 'White',
'WhiteSmoke', 'Yellow', 'YellowGreen'
]
return colors
def color_name_to_rgb():
colors_rgb = []
for key, value in colors.cnames.items():
colors_rgb.append((key, struct.unpack('BBB', bytes.fromhex(value.replace('#', '')))))
return dict(colors_rgb)
def draw_boxes_and_labels(
boxes,
classes,
scores,
category_index,
instance_masks=None,
keypoints=None,
max_boxes_to_draw=20,
min_score_thresh=.5,
agnostic_mode=False):
"""Returns boxes coordinates, class names and colors
Args:
boxes: a numpy array of shape [N, 4]
classes: a numpy array of shape [N]
scores: a numpy array of shape [N] or None. If scores=None, then
this function assumes that the boxes to be plotted are groundtruth
boxes and plot all boxes as black with no classes or scores.
category_index: a dict containing category dictionaries (each holding
category index `id` and category name `name`) keyed by category indices.
instance_masks: a numpy array of shape [N, image_height, image_width], can
be None
keypoints: a numpy array of shape [N, num_keypoints, 2], can
be None
max_boxes_to_draw: maximum number of boxes to visualize. If None, draw
all boxes.
min_score_thresh: minimum score threshold for a box to be visualized
agnostic_mode: boolean (default: False) controlling whether to evaluate in
class-agnostic mode or not. This mode will display scores but ignore
classes.
"""
# Create a display string (and color) for every box location, group any boxes
# that correspond to the same location.
box_to_display_str_map = collections.defaultdict(list)
box_to_color_map = collections.defaultdict(str)
box_to_instance_masks_map = {}
box_to_keypoints_map = collections.defaultdict(list)
if not max_boxes_to_draw:
max_boxes_to_draw = boxes.shape[0]
for i in range(min(max_boxes_to_draw, boxes.shape[0])):
if scores is None or scores[i] > min_score_thresh:
box = tuple(boxes[i].tolist())
if instance_masks is not None:
box_to_instance_masks_map[box] = instance_masks[i]
if keypoints is not None:
box_to_keypoints_map[box].extend(keypoints[i])
if scores is None:
box_to_color_map[box] = 'black'
else:
if not agnostic_mode:
if classes[i] in category_index.keys():
class_name = category_index[classes[i]]['name']
else:
class_name = 'N/A'
display_str = '{}: {}%'.format(
class_name,
int(100 * scores[i]))
else:
display_str = 'score: {}%'.format(int(100 * scores[i]))
box_to_display_str_map[box].append(display_str)
if agnostic_mode:
box_to_color_map[box] = 'DarkOrange'
else:
box_to_color_map[box] = standard_colors()[
classes[i] % len(standard_colors())]
# Store all the coordinates of the boxes, class names and colors
color_rgb = color_name_to_rgb()
rect_points = []
class_names = []
class_colors = []
for box, color in six.iteritems(box_to_color_map):
ymin, xmin, ymax, xmax = box
rect_points.append(dict(ymin=ymin, xmin=xmin, ymax=ymax, xmax=xmax))
class_names.append(box_to_display_str_map[box])
class_colors.append(color_rgb[color.lower()])
return rect_points, class_names, class_colors
3../detectionExample/Main.py をWebカメラ対応のロジックに変更
$ cd ..
$ cp ./detectionExample/Main.py ./detectionExample/Main_BK.py
$ nano ./detectionExample/Main.py
4.下記のソースを全コピペ
import sys,os,time,csv,getopt,cv2,argparse
import numpy as np
from datetime import datetime
from ObjectWrapper import *
from Visualize import *
from utils.app_utils import FPS, WebcamVideoStream
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--graph', dest='graph', type=str,
default='graph', help='MVNC graphs.')
parser.add_argument('-src', '--source', dest='video_source', type=int,
default=0, help='Device index of the camera.')
parser.add_argument('-wd', '--width', dest='width', type=int,
default=400, help='Width of the frames in the video stream.')
parser.add_argument('-ht', '--height', dest='height', type=int,
default=300, help='Height of the frames in the video stream.')
args = parser.parse_args()
network_blob=args.graph
detector = ObjectWrapper(network_blob)
video_capture = WebcamVideoStream(src=args.video_source,
width=args.width,
height=args.height).start()
# image preprocess
img = video_capture.read()
while True:
results = detector.Detect(img)
imdraw = Visualize(img, results)
cv2.imshow('Demo',imdraw)
#print(datetime.now())
key = cv2.waitKey(1)
if key == ord('q'):
break
img = video_capture.read()
video_capture.stop()
cv2.destroyAllWindows()
5.WEBカメラ (UVC [USB Video Class] 対応のもの) をRaspberry PiのUSBポートへ接続
6.動体検知の実行テスト、下記コマンドを実行
$ startx ← CLIモードで作業中のときのみ実行、GUIモードへ切り替え、SSHで作業していないときは無視
$ cd ~/YoloV2NCS ← GUI側(Desktop側)の「端末」アプリで実行
$ python3 ./detectionExample/Main.py ← GUI側(Desktop側)の「端末」アプリで実行
#◆SWAP領域の縮小
$ sudo nano /etc/dphys-swapfile
CONF_SWAPSIZE=100
$ sudo /etc/init.d/dphys-swapfile restart swapon -s
#◆ TMP領域の縮小
1.下記のコマンドを実行
$ cd /etc
$ sudo nano /etc/fstab
2.ファイルの下記の箇所を変更して保存
tmpfs /tmp tmpfs defaults,size=32m,noatime,mode=1777 0 0
tmpfs /var/tmp tmpfs defaults,size=32m,noatime,mode=1777 0 0
3.下記のコマンドを実行
$ sudo reboot
#◆ おまけ
##(1) 実行時にSWAP領域が不足した場合は下記実施
$ sudo nano /etc/dphys-swapfile
CONF_SWAPSIZE=1024
$ sudo /etc/init.d/dphys-swapfile restart swapon -s
##(2) SDカード長寿命化のためSWAPを無効化
1.下記のコマンドを実行
$ free
$ sudo swapoff --all
$ sudo apt-get remove dphys-swapfile
$ sudo reboot
##(3) Python3 コマンドを Python コマンドへ誘導する設定
1.下記のコマンドを実行
$ sudo nano ~/.bashrc
2.下記一行をファイルの一番下に追記
alias python=python3
3.下記コマンドを実行
$ source ~/.bashrc
4.下記コマンドを実行、PythonコマンドでPython3が起動するようになる
$ python
>>>
##(4) Ubuntu 16.04 amd64,x86/x64用 TBB(2018 U2) debパッケージ
deb: https://drive.google.com/open?id=1MyaI9dgTO47_18HeVjmycC2zZeE46rdo
ビルドシーケンス: https://drive.google.com/open?id=10FbuthIF2EEDilN1j0RoK-InmPKNYb_A