ラクス Advent Calendar2017も2桁突入の10回目です。
昨日はfu-jiさんのCUIに苦手意識がある人でも使えるコマンドでした。
自分が使うコマンドにも偏りがありそうだなぁ、と思わせてくれる面白い記事でした。
さて、今回はラクスの自称IoT部長としての責務を果たすべく、Raspberry piとAIにチャレンジしてみたいと思います。
Web系の会社に所属しながらデバイスが持つ魅力に取り憑かれ、色々なデバイスに手を出しています。
ラズパイだけで言うと、Raspberry pi B+が発表された2013年頃からラズパイに魅せられ、B+を2台、pi2を1台、pi3を1台とムダ順調に増え続けています。
Zeroも欲しいのですが、残念ながらRaspberry pi Zero Wを未だに手に入れることができていません。人気があってなのか在庫が無いようです。安定して供給されるようになるまでもう少し我慢中。
今回のテーマはラズパイを使った物体認識のお話です。
昨今だと、Google Vision APIなどのクラウドサービスを使えば簡単にできそうですが、クラウドを使わずにやります。
とはいえ、難しいことに手を出すとモチベーションが続かないので、できるだけ簡単な方法を考えました。
前提
物体認識と言うは易し。実はめちゃくちゃ難しいので、識者が公開してくれている学習済みのデータ等を利用する。
今回準備したデバイス
- Raspberry pi3
- 3.5インチ LCD TFT Touch screen(今回はlandzoのディスプレイを利用)
- Raspberry pi Camera board rev1.3
ソフトウェア
- RASPBIAN STRETCH WITH DESKTOP
- LCDのドライバー(後述)
- DeepBeliefSDK (後述)
- Python Pygame
LCDのセットアップ
今回用意したLCDは比較的簡単にセットアップできます。
基本的には下記サイトにあるドライバーを使ってセットアップ手順に従うだけ。
利用したドライバーはLCD-show-161112.tar.gzです。
セットアップ手順はドライバーをダウンロードして解凍後、LCD35-show
コマンドを実行するだけ。
tar xvf LCD-show-*.tar.gz
cd LCD-show/
chmod +x LCD35-show
./LCD35-show
ディスプレイを180度回転したい場合は、下記のようにします。
./LCD35-show 180
DeepBeliefSDKのセットアップ
DeepBeliefSDK
とはラズパイだけでなく、iOSやAndroidなどでも動作する深層学習済みの画像認識フレームワークです。
では早速セットアップしましょう。
-
/boot/config.txt
の最終行にgpu_mem=128
を追加してreboot - 下記の通りDeepBelliefSDKをGitHubからcloneしてmake
参考:https://github.com/jetpacapp/DeepBeliefSDK#getting-started-on-a-raspberry-pi-2
mkdir ~/src
cd ~/src
sudo apt-get install -y mercurial
hg clone https://bitbucket.org/eigen/eigen
ln -s ~/src/eigen ~/projects/DeepBeliefSDK/eigen
cd ~/src/DeepBeliefSDK/source
make clean
sudo apt-get install gcc-4.8 g++-4.8
sudo rm -rf /usr/bin/gcc
sudo rm -rf /usr/bin/g++
sudo ln -s /usr/bin/gcc-4.8 /usr/bin/gcc
sudo ln -s /usr/bin/g++-4.8 /usr/bin/g++
make GEMM=eigen TARGET=pi3
pygameのインストール
sudo apt-get install python-pygame
pipが良い方はpip install pygame
ですね。
カメラのセットアップ
-
raspi-config
を実行してCameraを有効にする。 -
pygame.camera
で/dev/video0
のデバイスを使うために
/etc/modules-loaded.d/modules.conf
にbcm2835-v412
を追記する。
# /etc/modules: kernel modules to load at boot time.
#
# This file contains the names of kernel modules that should be loaded
# at boot time, one per line. Lines beginning with "#" are ignored.
i2c-dev
bcm2835-v4l2
プログラム
# -*- coding: utf-8 -*-
import pygame
import pygame.camera
import io
import os
import subprocess
def main():
# Init framebuffer/touchscreen environment variables
os.putenv('SDL_VIDEODRIVER', 'fbcon')
os.putenv('SDL_FBDEV' , '/dev/fb1')
os.putenv('SDL_MOUSEDRV' , 'TSLIB')
os.putenv('SDL_MOUSEDEV' , '/dev/input/touchscreen')
(x,y) = (0,0)
pygame.init()
pygame.camera.init()
pygame.font.init()
pygame.mouse.set_visible(False)
font = pygame.font.SysFont('Comic Sans MS', 24)
screen = pygame.display.set_mode((0,0), pygame.FULLSCREEN)
camera = pygame.camera.Camera("/dev/video0", (640,480))
camera.start()
while True:
snapshot = camera.get_image()
screen.blit(snapshot, (x, y))
for event in pygame.event.get():
# take picture
if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
filename = "/tmp/camera.jpg"
pygame.image.save(snapshot, filename)
cmd = '/home/pi/src/DeepBeliefSDK/source/jpcnn -i ' + filename + ' -n /home/pi/src/DeepBeliefSDK/networks/jetpac.ntwk -m s'
proc = subprocess.Popen(cmd, shell=True,stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
stdout, stderr = proc.communicate()
result = ["0.0",""]
for line in stdout.splitlines():
data = line.split("\t")
if float(result[0]) < float(data[0]):
result = data
textsurface = font.render(result[1], False, (0, 0, 0))
screen.blit(textsurface,(0,0))
pygame.display.update()
pygame.time.wait(2000)
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
pygame.display.update()
pygame.time.wait(30)
if __name__ == "__main__":
main()
実行
コンソールから上述のpythonコードをrootで実行する。
おおおおお!画面左上にcoffee mug
の文字が!
感想
認識にかかる時間はもうちょっと早いかなと思っていましたが、約10秒ほどかかります(遅っ!)。
しかし、学習済みデータを使うので、深層学習について深く知る必要はなく、ここまで簡単に試すことができました。
今回試した限りだとマグカップ以外に、PCのキーボード、iPodを認識しました。実際はiPodではなく、iPadだったんですが写真から物体の大きさが読み取れないので間違っても仕方ないかもしれません。
認識率で言うと決して高く無いようですが、深層学習をここまで手軽に試せるようになったことには驚きました。
これから色々なデバイスが今以上に進化していくと思うと楽しみでなりません。
Raspberry pi4の噂もちらほら聞きますので、今から待ち遠しいですね!