LoginSignup
16
20

More than 5 years have passed since last update.

RekognitionとRaspberry piでペット監視

Last updated at Posted at 2017-01-03

あけましておめでとうございます。犬バカの藤向(ふじさき)です。
去年末にAmazon Rekognitionという画像認識できるサービスがリリースしていたと聞きましたので、さっそく遊びました。

作成の動機

人感センサ+ラズパイを使った監視カメラは、以前から作られてますが、結構ちょっとした動きでゴミデータまで撮ってしまうので、犬や家族のメンバーなど、限定された画像だけ選別して残して、あとは消去できたらいいな、と思った次第です。

準備

人感センサ & Raspberry Piで監視カメラを作る

材料

  • Raspberry pi3
  • メスメスジャンパケーブル3つ
  • Webカメラ(USB) (Logitech HD Webcam C525)
  • 人(犬)感センサー (SEEED-101020060 PIRモーションセンサ)

ラズパイと人感センサーの接続方法、またセンサーの動作調整等はcigalecigalesさんの、[Raspberry Pi] 夏だ!人感センサーを使って蝉を鳴かせよう
を参考にさせていただきました。ありがとうございました。
KIMG1860.JPG

ラズパイとUSBのWebカメラの連携はfswebcamを使います。こちらはオフィシャルページを参考にしました。

これをPythonから呼び出すために、os.systemを使います。

RekogDogCamera.py
import time
from time import gmtime,strftime
import RPi.GPIO as GPIO

INTERVAL = 3
SLEEPTIME = 5
SENSOR_PIN = 25

GPIO.setmode(GPIO.BCM)
GPIO.setup(SENSOR_PIN, GPIO.IN)

st = time.time()-INTERVAL
while True:
        if( GPIO.input(SENSOR_PIN) == GPIO.HIGH ) and (st + INTERVAL < time.time() ):
                st = time.time()
                strf = strftime("%Y%m%d-%H:%M:%S")
                strfile = strf + '.jpg'
                print("movement detected " + strf)
                os.system('fswebcam --no-banner /home/pi/myphoto/'+ strfile)

        time.sleep(SLEEPTIME)
GPIO.cleanup()

撮影した画像をS3にあげる

Boto3を使いました。ドキュメント通りに~/.aws/credentialsなどを設定した後、上記コードのループ内にS3にアップロードするあたりを足します。

RekogDogCamera.py
import boto3
bucket_name = 'mybucket'
s3_client = boto3.client('s3')
s3_client.upload_file('/home/pi/myphoto/' + strfile ,bucket_name, strfile)

これで準備は完了です。

さあ新しいもので遊んでみよう!

Rekognition使ってうちの子の写真だけ残す

Rekognitionのデモを試してみました。今回興味あるのは、Object and scene detectionです。
rekognitiondemo.JPG

Download SDKからたどって、ドキュメントを読みます。
Amazon Rekognition Developer Guide PDF 28ページ目くらいに欲しいものがありましたので一度コンソールから試します。
追記:HTML版はこちらにありました。→Exercise 1: Detect Labels in an Image (API)

$ aws rekognition detect-labels --image '{"S3Object":{"Bucket":"mybucket", "Name":"mydog.jpg"}}' --region us-east-1 --profile default

先ほどDemoで使った写真はこんな感じの返答が返ってきました。

result
 {
    "Labels": [
        {
            "Confidence": 98.25569915771484,
            "Name": "Animal"
        },
        {
            "Confidence": 98.25569915771484,
            "Name": "Canine"
        },
        {
            "Confidence": 98.25569915771484,
            "Name": "Dog"
        },
        {
            "Confidence": 98.25569915771484,
            "Name": "Husky"
        },
        {
            "Confidence": 98.25569915771484,
            "Name": "Mammal"
        },
        {
            "Confidence": 98.25569915771484,
            "Name": "Pet"
        },
        {
            "Confidence": 95.74263763427734,
            "Name": "Eskimo Dog"
        },

(※余談:エスキモー犬でもハスキーでもなく、うちの子は紀州犬です...)

先ほどのPythonコードからの呼び出しを試します。お手軽にos.systemを使うのでクオートをがんばってエスケープします。

RekogDogCamera.py
result = os.system("aws rekognition detect-labels --image \'{\"S3Object\":{\"Bucket\":\""+bucket_name+"\", \"Name\":\""+ strfile +"\"}}\' --region us-east-1 --profile default > temp.json")

帰ってくる返答をループにかけて、もし"Name" に "Canine" があって、しかも"Confidence" が55以上なら、"Canine found"と、Confidenceを報告するようにします。。

RekogDogCamera.py
with open('temp.json') as json_data:
    data = json.load(json_data)
    for d in data["Labels"]:
        if (d["Name"] == "Canine" and d["Confidence"] > 55.0):
            print ("Canine found: " + str(d["Confidence"]))
        break

(※最初Confidenceを95くらいにしていたのですが、暗めの室内の写真だと60以上あまり行かないので、55にしました)

そして、犬が検知されなかった写真は、S3から排除します。

RekogDogCamera.py
        else:
            s3_client.delete_object(Bucket=bucket_name, Key=strfile) 

実行します。
KIMG1858 (1).jpg

$ python3 RekogDogCamera.py
--- Opening /dev/video0...
Trying source module v4l2...
/dev/video0 opened.
No input was specified, using the first.
Adjusting resolution from 384x288 to 352x288.
--- Capturing frame...
Captured frame in 0.00 seconds.
--- Processing captured image...
Disabling banner.
Writing JPEG image to '/home/pi/myphoto/20170103-00:08:15.jpg'.
Canine found: 71.327880859375
20170102-23-57-58.jpg

撮れました!


最終的にこんな感じのファイルになります。

RekoDogCamera.py
import time
from time import gmtime,strftime
import RPi.GPIO as GPIO
import json
import os
import boto3

INTERVAL = 3
SLEEPTIME = 5
SENSOR_PIN = 25
#使用するアクセス権のあるバケットを指定
bucket_name = 'mybucket'

GPIO.setmode(GPIO.BCM)
GPIO.setup(SENSOR_PIN, GPIO.IN)

st = time.time()-INTERVAL
s3_client = boto3.client('s3')
while True:
         #犬感センサーからデータの流入があり、なおかつ時間間隔が規定以上なら…
        if( GPIO.input(SENSOR_PIN) == GPIO.HIGH ) and (st + INTERVAL < time.time() ):
                st = time.time()
                strf = strftime("%Y%m%d-%H:%M:%S")
                strfile = strf + '.jpg'
                #写真を撮ります
                os.system('fswebcam --no-banner /home/pi/myphoto/'+ strfile)
                #撮った写真をS3のバケットに移動します。
                s3_client.upload_file('/home/pi/myphoto/' + strfile ,bucket_name, strfile)
                #Rekognitionに、写真の中に犬がいるかどうか訊きます。
                result = os.system("aws rekognition detect-labels --image \'{\"S3Object\":{\"Bucket\":\""+bucket_name+"\", \"Name\":\""+ strfile +"\"}}\' --region us-east-1 --profile default > temp.json")
                #Rekognitionから帰ってきたJsonデータに犬がいたら…
                with open('temp.json') as json_data:
                    data = json.load(json_data)
                    for d in data["Labels"]:
                        if (d["Name"] == "Canine" and d["Confidence"] > 55.0):
                                #犬がいたよ!とConfidentと併せて報告します
                                print ("Canine found: " + str(d["Confidence"]))
                                break
                        else:

                                #そうでなければ、容赦なく削除します。
                s3_client.delete_object(Bucket=bucket_name, Key=strfile)

        time.sleep(SLEEPTIME)
# Clean Up
GPIO.cleanup()
os.system('rm /home/pi/myphoto/* temp.json')

16
20
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
20