どうもーisaaxの杉田です。この記事はisaaxアドベントカレンダー13日目の記事です。
今年の10月15日にAIoTLTでデモしたRaspberry Piで人数カウントしてTwitterに投稿するデバイスの作り方の解説をします。
仕組みはコチラのスライドを見てください。
3分で実装完了!エッジ AI デモ from Tomoyuki Sugita
ただ、スライドだけだとどんなデモをしたのかわからないと思うので、少しだけ中身の解説をします。
この記事のゴール
この記事を読んだ人がisaaxを使って同じ様に実装できるようになることを目指します。
注意点
Twitterに人の顔を許可なくアップロードすると__肖像権の侵害__や__プライバシーの侵害__で訴えられる可能性があります。間違っても許諾を取らずに人の顔写真をTwitterに投稿しないようにしてください。(Twitterに限らずですが)
もっとはっきり言うと、この記事を参考にしてみなさんがトラブルを起こしても私は一切責任をとりません。必ず__自己責任で__試してください。
前提条件
使用機材
- macOS HighSierra or Mojave
- Raspberry Pi 3B+
- Amazonで見つけた1400円位のカメラモジュール
Windowsでも開発出来ると思うけど未検証です。
私のスキルレベル
- Gitはバリバリ使える
- PHPはバリバリ書ける
- Pythonは何となく分かる
- Raspberry Piは自分でOS焼いてSSHログインして開発できる程度
- AIは理論はわかるが実装はできない
Pythonはできなくても、基本的なプログラミングができれば__気合__でなんとかなります。
サンプルコード
こちらのサンプルコードをForkしてisaaxに登録すればすぐに使えます。isaaxの使い方についてはコチラのチュートリアル記事を見てください。
ベースにしたコードはisaax勉強会で使ったものです。
https://camp.isaax.io/ja/examples/ai-camera-slack
ぶっちゃけSlackへの投稿をTwitterに変更するだけなので、誰でもできそう。
コードの解説
Twitterへの画像投稿は
- 画像を投稿してURLを取得
- ツイートに画像をアタッチする
という2段階になりますので、Qiitaで見つけたサンプルコードをベースに実装してきます。
コード全体はGithubで見てください。重要なポイントだけ解説します。
# Get from Enver Service via isaax
try:
CK = os.environ['TWITTER_CK'] # Consumer Key
CS = os.environ['TWITTER_CS'] # Consumer Secret
AT = os.environ['TWITTER_AT'] # Access Token
AS = os.environ['TWITTER_AS'] # Accesss Token Secert
except KeyError as e:
sys.stderr.write('You need to set {} using Isaax.\n'.format(e))
sys.stderr.write('See: https://isaax.io/docs/ja/environment-variables.html\n')
sys.exit(1)
TwitterのトークンとかシークレットとかGithubに上げたくないのでos.environ
で環境変数から取得します。環境変数がない場合はTwitterに投稿できないので例外終了します。
後述しますが、環境変数はisaaxを使って管理するので、例外発生時にsys.stderr.write
でisaaxの環境変数のマニュアルに誘導する親切設計にしてみました。
def upload(persons):
'''省略'''
# Media ID を付加してテキストを投稿
now = datetime.datetime.now()
params = {'status': '{}現在、人が{}人写ってるっぽいね〜 #iotlt #isaax'.format(now.strftime('%H:%M:%S'),persons), "media_ids": [media_id]}
req_media = twitter.post(url_text, params = params)
upload
関数の引数persons
はINTです。AIで人数をカウントして、このライブラリのupload
関数を呼び出して使います。
Twitterは同じ内容をばんばか投稿するとアカウント停止を食らう可能性があるので、投稿内容に{}現在
という文言を追加して同じ内容にならないようにします。
呼び出す箇所はperson_detector.py内に記載しました。コードで言うとこのへん。
if persons > 0:
timestamp = datetime.now()
if (timestamp - self.last_uploaded).seconds >= 30:
cv2.imwrite("image.jpg", frame)
print('Uploading...')
upload(persons)
self.last_uploaded = timestamp
print('Finished.')
ここでもやはり、Twitterへばんばかアップロードしてアカウント停止を食らうのが怖いので、if (timestamp - self.last_uploaded).seconds >= 30:
で30秒以上インターバルを空けないと投稿できないようにしています。
upload(persons)
の部分をすげ替えてあげれば、Twitter以外へも投稿できるようになるので、割とカスタマイズしやすいかと思います。元のサンプルコードは人数カウントとアップロード処理が同じファイルに書かれていて改造しにくかったので、きれいに分離する作業を頑張りました。
Raspberry Piのセットアップ
環境変数を設定する前に、Forkした私のサンプルコードをisaaxのプロジェクトに登録してください。やり方はチュートリアル記事に任せて割愛します。
あ、インストールした際に色んなモジュールが不足しているというエラーメッセージがisaaxのダッシュボードに表示されると思いますので、Raspberry Piにログインしてインストールコマンドを実行してください。
# AIのモデルをダウンロードします
cd /home/pi
wget https://github.com/chuanqi305/MobileNet-SSD/raw/master/MobileNetSSD_deploy.caffemodel
wget https://raw.githubusercontent.com/chuanqi305/MobileNet-SSD/master/MobileNetSSD_deploy.prototxt
# 必要なモジュールをインストールします
sudo apt update
sudo apt -y upgrade
sudo apt update
sudo apt install -y build-essential cmake pkg-config
sudo apt install -y libjpeg-dev libtiff5-dev libjasper-dev libpng12-dev
sudo apt install -y libavcodec-dev libavformat-dev libswscale-dev libv4l-dev
sudo apt install -y libxvidcore-dev libx264-dev
sudo apt install -y libgtk2.0-dev libgtk-3-dev
sudo apt install -y libatlas-base-dev gfortran
sudo apt install -y libqtgui4 libqt4-test
sudo apt install -y libilmbase12 libopenexr22 libgstreamer1.0-dev
sudo apt install -y python3-dev python3-pip
sudo pip3 install numpy opencv-python picamera[array] flask imutils pyzbar
AIのモデルはGithubのリポジトリに載せてしまうと重くなってしまうので、別にダウンロードします。
たぶん、無駄なPythonモジュールもインストールしてしまってると思うけど気にしない。。。
Isaaxで環境変数の設定
アプリケーションを動かすための最後の設定です。
isaaxのダッシュボードにアクセスして、作成したプロジェクトを開き、__DEFAULTクラスター__を開きます。
画面中程に__Cluster Settings__という項目を見つけることが出来るので、クリックして詳細を開きます。
__ユーザー変数__のタブをクリックします。
すると、RaspberryPiの環境変数を設定できる画面が表示されますので、TWITTER_CK
, TWITTER_CS
, TWITTER_AT
, TWITTER_AS
の4つを設定します。
設定した変数は、先述した下記のコードでPythonスクリプト内で読み込むことができます。
# Get from Enver Service via isaax
try:
CK = os.environ['TWITTER_CK'] # Consumer Key
CS = os.environ['TWITTER_CS'] # Consumer Secret
AT = os.environ['TWITTER_AT'] # Access Token
AS = os.environ['TWITTER_AS'] # Accesss Token Secert
except KeyError as e:
設定が終わったらアプリケーションを再起動して新しい環境変数を読み込みます。(Pythonはプロセスの起動時に環境変数を読み込むため、再起動しないと変更後の環境変数を取得できないため)
ポチッとな。
上手く動くとこんな感じでTwitterに投稿されます。
人が1人写ってるっぽいね〜 #iotlt #isaax pic.twitter.com/GL16en1myn
— Tomoyuki Sugita (@tomotomobile) 2018年10月15日
投稿時刻をツイートに含めることを忘れてたのでgit push
してコードを修正。
07:55:54現在、人が1人写ってるっぽいね〜 #iotlt #isaax pic.twitter.com/NJjtLgPAup
— Tomoyuki Sugita (@tomotomobile) 2018年10月15日
上手く動きました。
まとめ
AIの実装が全くと行っていいほど出てこなかったけど、それでもできちゃいました。
isaaxを使えばgit push
するだけですぐにデバイスに組み込んだソフトウェアの挙動を変えられるので超楽です。バージョン管理もgithubに紐付いているので、問題の調査も簡単です。
試しに使ってみてください。