概要
部屋に何人いるかを可視化するシステムを作ります.
カメラで部屋を写し,そこに何人の人間がいるかを検出して,その情報を slack の専用チャンネルに定期投稿します.
用意したもの
- Raspberry Pi 2 Model B
- microSD (64GB)
- ラズパイ用の電源一式
- LANケーブル
- Logicool C270(UVCに対応していればよい)
扱うソフトウェア
- raspbian (2019-04-08-raspbian-stretch-lite)
- uvccapture version 0.4
- darknet commit: 61c9d02
手順
ラズパイのセットアップ
microSD に書き込んで, ssh 接続できるようにします.
時刻合わせ
JSTになっていない場合はJSTにしておきます.
$ date
Wed 29 May 02:17:03 BST 2019
ファイルを念のためバックアップし,タイムゾーンを変更します.
$ sudo cp /etc/localtime /etc/localtime.org
$ sudo ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
$ date
Wed 29 May 10:17:49 JST 2019
microSDの論理破損対策
Raspberry PiのSDカードが壊れた!寿命を延ばす方法 5+1選!【運用編を追加】をやれるだけやります.
ssh接続の設定
passwd
コマンドで,piとrootのパスワードを変更します.
公開鍵を.ssh/authorized_keys
に追記.
以下を変更して公開鍵認証を強制します.
PasswordAuthentication no
ChallengeResponseAuthentication no
ついでにIPアドレスを固定しておきます.
interface インタフェース名
static ip_address=アドレス(CIDR表記可)
static routers=アドレス
static domain_name_servers=アドレス
参考:Raspberry Pi 2 (Raspbian: jessie) でIPアドレスを固定する
カメラでの撮影
uvccapture
を用います.
$ sudo apt -y install uvccapture
uvccapture -oファイル名
で撮影できますが,そのままでは色味がおかしく,サイズも小さいです.
また,画像は一度検出するためにしか使用しないので,microSDではなく,RAMディスク上の一時領域に書きたいです.
実際には,次のコマンド及びオプションで撮影します.
色味や明るさのパラメータは環境に合わせて要調整です.
$ uvccapture -m -v -B-3 -C20 -S9 -G-15 -q100 -x1280 -y720 -o/tmp/ファイル名
参考:uvccaptureで画像取得
参考:RaspbianでWebカメラを使ってみる(uvccaptureとかmotion)
darknetの用意
部屋に何人の人がいるか検出するために, darknet を使用します.
まずは拾ってきてコンパイルします.
~ $ git clone https://github.com/pjreddie/darknet
~ $ cd darknet
~/darknet $ make
学習済みパラメータを入手します.
~/darknet $ wget http://pjreddie.com/media/files/yolo.weights
静止画認識の方法
darknet (実行ファイル)を,次のようなオプションで実行します.
~/darknet $ ./darknet detect cfg/yolov2.cfg yolo.weights 読み込ませる画像
cfg
ディレクトリにはいくつかのコンフィグファイルらしきものが見当たりますが,いろいろ試して適切なものを選びます.今回はyolov2を選びました.
また,実行後に検出結果としてPredict.jpg
というファイルが作成されますが,これは利用しません.
標準出力にも検出結果が出るため,画像内に"People"がいくつ検出できたかを知るにはこれで十分だからです.
次のコマンドで,ある画像内の"People"の数を得ます.
$ /home/pi/darknet/darknet detect cfg/yolov2.cfg yolo.weights (読み込ませる画像) \
| grep "People" | wc -l
参考:【Darknet】リアルタイムオブジェクト認識 YOLOをTensorflowで試す
slack にメッセージを投稿する
Incoming Webhooks を利用します.
あらかじめ, slack に専用のチャンネルを作っておくことを推奨します.
https://slack.com/services/new/incoming-webhook にアクセスして,先ほど作成したチャンネルを選び,インテグレーションの追加をします.
そうすると, Webhook URL が割り当てられます.
この Webhook URL に所定の形式でデータを送れば,slackに投稿することができます.簡単な例を次に示します.
$ curl -X POST --data-urlencode 'payload={"text":"これはテストです."}' 与えられたURL
参考:SlackのIncoming Webhooksを使い倒す
一連の操作を行うシェルスクリプトを作成する.
作成しました.
#!/bin/sh
uvccapture -m -v -B-3 -C20 -S9 -G-15 -q100 -x1280 -y720 -o/tmp/cam1.jpg
cd /home/pi/darknet/
res=`./darknet detect cfg/yolov2.cfg yolo.weights /tmp/cam1.jpg | grep person | wc -l`
text="\"現在部屋には ${res}名います.\""
content="payload={\"text\":${text}}"
curl -X POST --data-urlencode "$content" アドレス
これを sudo crontab -u root -e
してcron に登録.
*/15 8-22 * * * sh /home/pi/darknet/watcher.sh
8時から22時の間,15分おきに実行するように設定しました.
しばらく待って,slackに投稿されていたらokです.
(私の例では,投稿名,アイコンと文章が若干異なります)
まとめ
カメラによる撮影,darknetの利用,slackの投稿,および一連の処理を連携させて自動実行する方法を示しました.
カメラの画角の都合上,カメラ1個では部屋の一部しかチェックできないでしょう(私の環境ではできません).余裕があれば,カメラを追加して全体をチェックできるようにしたいですね.
更新履歴
2019年7月8日 タイトルを変更(頭に【構築編】をつけました)