IoTとAWSでサービスを作ってみた
こんにちは、呉屋です。
今回は、IoTとAWSで作ったサービスを紹介します。
これまで「ラズパイ」・「カメラ」・「熱検知センサー」・「AWS」を検証してきました。
それぞれのできることが分かってきましたので、組み合わせてサービスを作ってみました。
それでは見ていきましょう!
サービスの紹介
ラズパイの前を人が通ると、自動的に撮影されて人数をカウントするものです。

構成図
構成図と処理の流れは、このようになります。
①熱検知センサーで"人"を検知
②カメラで画像撮影
③AWSに連携・処理
④Web画面確認

AWSサービス
利用するサービスは、こちらです。
・IoT Core
・Lambda
・S3
・DynamoDB
・Rekognition
・Api Gateway
・IAM ROLE
今回、初登場なものが「DynamoDB」です。
IoTから送られる撮影画像の履歴を管理するために使用します。
残りのサービスは、これまで投稿したものとなります。
参考までにリンクを載せますので、興味のある方は見てみて下さい。
①・②・③について

④について

IoTについて
ラズパイ、熱検知センサー、カメラの3つを使いました。
実物は、こちらです。

起動プログラム
ラズパイ側で実行するPythonプログラムは、こちらです。
ポイントは、二つあります。
一つ目は、カメラの撮影方法を"コマンドラインツール"から"Pythonモジュール"に変更したところです。
これまでは、"raspistillコマンド"を使っていましたが、撮影するまでのタイムラグがありました。
人を検知しても、もうすでに写っていなくて一歩遅い。。。という課題がありました。
これをPythonモジュールの"picamera"を使うことで、撮影処理を速くすることができました!
二つ目は、画像の解像度を変更することです。
IoT CoreでMQTT通信を使用する場合は、画像サイズが大きすぎると、転送処理がうまくいきません。
そのため、転送可能なサイズを調整しました!
ここは最初、原因が分からずに苦戦しました。
import time
from datetime import datetime, timedelta, timezone
import json
import base64
import AWSIoTPythonSDK.MQTTLib as AWSIoTPyMQTT
import RPi.GPIO as GPIO
import picamera
# IoT Core設定
endpoint = “XXXXX-ats.iot.ap-northeast-1.amazonaws.com"
clientId = “RaspberryPi_dev01"
certKey = “./cert/certificate.pem.crt"
privateKey = “./cert/private.pem.key"
rootKey = “./cert/root-ca.pem"
topic = “topic_s3_push"
bucket = “XXXXX"
# IoT Core MQTT設定
myAWSIoTMQTTClient = AWSIoTPyMQTT.AWSIoTMQTTClient(clientId)
myAWSIoTMQTTClient.configureEndpoint(endpoint, 8883)
myAWSIoTMQTTClient.configureCredentials(rootKey, privateKey, certKey)
# 熱検知センサー設定
GPIO_PIN = 18
GPIO.setmode(GPIO.BCM)
GPIO.setup(GPIO_PIN, GPIO.IN)
# カメラのインスタンス生成
camera = picamera.PiCamera()
# 接続開始
myAWSIoTMQTTClient.connect()
print(“センサー検証を開始します。「Ctrl + C」で終了します。")
print(“")
# Cameraファンクション
def capture():
# 解像度指定
camera.resolution = (300,300)
# 撮影
camera.capture('/home/pi/dev/contest/camera.jpg’)
# 待機
time.sleep(1)
# AWS IoTファンクション
def main():
# 画像読み込み
img = open(“/home/pi/dev/contest/camera.jpg", 'rb’).read()
# binaryからbase64変換
base64Img = base64.b64encode(img).decode(“utf-8")
# タイムスタンプ取得
jst = timezone(timedelta(hours=+9), 'JST’)
timestamp = datetime.now(jst)
timestamp = timestamp.strftime('%Y-%m-%d-%H%M%S’)
key = timestamp + “.jpg"
# json形式に変換
obj = json.dumps({
“img" : base64Img,
“bucket" : bucket,
“key" : key})
# 画像転送
print(“転送開始 ファイル名 : " + key)
myAWSIoTMQTTClient.publish(topic, obj, 1)
print(“転送終了")
print(“")
# メイン処理
try:
while True:
# 検知待機待機
if(GPIO.input(GPIO_PIN) == GPIO.HIGH):
print(“物体検知しましたので、撮影します。")
capture()
main()
finally:
# 切断
myAWSIoTMQTTClient.disconnect()
GPIO.cleanup
検証してみよう
ここからは、実際に動かしてみましょう!
色々なパターンで検証してみます。
正面の場合
ラズパイに接続して、実行します。

ラズパイの前を通ってみます。
すると、検知して、撮影・AWSに転送されます!

どのような画像が取れたのか、確認してみましょう!

しっかり、撮影されていることが分かります!
ラズパイの位置と人が通る場所を熱検知センサーで調整することが難しかったです。
後ろ姿の場合

顔の一部が見えていないと、カウントされていないことが分かります。
複数人の場合

実際には3人いますが、2人と認識されていますね。
やはりこの基準は、AWSのRekognitionです。
精度を上げたいのであれば、RekognitionのカスタムラベルやSageMakerを使って学習させる必要があります。
さいごに
IoTとAWSを使って、少しずつサービスが作れるようになりました。
次は、検知した人物が"誰なのか"を判定できるようにしていきたいです。
また、登録していない人物の場合は、動画を撮影したり、アラートを出したりなど展開していきたいと思います。
まだまだやることたくさんです٩( 'ω’ )و