物体検知で自動撮影&LINE送付してくれる簡単システム

#はじめに
物体が横切ると自動で撮影！LINEに画像送付してくれるシステムを紹介します。

**一泊二日の小旅行の時、飼い猫がちゃんとエサを食べているか？
水を飲んでいるか心配だったので作ってみました。**

ラズパイを使った簡単なシステムとなります、
ペット飼ってる人など、外出中にLINEでカメラ画像を確認できるのでオススメです。

####参考
書籍「[やさしくはじめるラズベリー・パイ](https://amzn.to/36fTfRT)」
ラズパイ初心者にはめちゃくちゃ分かりやすく、かなりオススメの書籍です。
今回のシステムはズバリ8割ぐらい、こちらの書籍からアイデアを借用いたしましたm(_ _)m

##システム説明
コチラがGitHubリポジトリとなります。
https://github.com/akiraseto/security_cam

####大まかな流れ

1. Pythonプログラムを起動し、スタンバイ
2. 猫がセンサーの近くを通りかかると、自動検知
3. 信号を受け取ったら、USB接続してあるWebcamで画像を取得、保存
4. 保存した最新画像をLINEnotifyを通して画像を通知する
5. 外出中でもLINEで画像が見れる！

####ラズパイ
センサーと、カメラのつなぎ込みにRaspberryPi(以下:ラズパイ)を使用します。

GPIOで人感センサーを接続 
赤外線を利用して人や動物など周囲より高温なものが動いた場合を検出します。
人感センサーはセット品の無印部品を使いましたが、秋月で売ってる[「SE-10」](http://akizukidenshi.com/catalog/g/gM-02471/)などで使用は問題ないと思います。　　
ラズパイのGPIO:23番にセンサーのOUTPUTを接続
ラズパイのGPIO:18番にLEDのアノードを接続
*適宜、必要な抵抗を入れ挟んでください*

webcamとUSB接続　　
PCと同じ様にUSB端子にぶっ刺すだけで、特に工夫はいらないです。

こんな感じ↓↓
![photo.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215645/a02e9a2c-22ee-5949-9330-e117f56255bd.jpeg)

####LINEnotify
LINEが提供しているAPIで、プログラムに組み込むことで様々なお知らせを自由にLINEに飛ばすことができます。
結構便利で、いろんな使い道がありそうです。
https://notify-bot.line.me/ja/

こちらのページが詳しいです。
https://qiita.com/iitenkida7/items/576a8226ba6584864d95

登録、連携してアクセストークンを発行しておきます。
アクセストークンは一度しか表示されないのでコピペ忘れに要注意です。

####全体構成

```
security_cam/
├── README.md
├── config.py #LINENotifyのトークン
└── security_cam.py

#画像保存用ディレクトリ
/media/pi/rasUSB/security_cam/img

```
*アカウント名:pi 外部ストレージ(USBメモリ)名:rasUSB*

画像に関しては起動ディスクの容量を圧迫したくないので、別途USBメモリに保存しています。
全体構成と大袈裟に言いましたが、実際のプログラムファイルは`security_cam.py`のみです。

####メインコード

```py:security_cam.py
import RPi.GPIO as GPIO
from time import sleep
import datetime, requests, cv2, os, glob, config

# LINE Notifyトークン
TOKEN = config.TOKEN
API = 'https://notify-api.line.me/api/notify'

# GPIOポートの設定
SENSOR_PORT = 23
LED_PORT = 18
GPIO.setmode(GPIO.BCM)
GPIO.setup(SENSOR_PORT, GPIO.IN)
GPIO.setup(LED_PORT, GPIO.OUT)

# CV2準備
camera = cv2.VideoCapture(0)
IMG_SIZE = (600,400)

# 写真の撮影コマンドを実行(ファイル名を日時に)
last_post = datetime.datetime(2000, 1, 1) # 適当に初期化
def take_photo():
    global last_post
    # 写真を撮影
    now = datetime.datetime.now()
    fname = "/media/pi/rasUSB/security_cam/img/" + now.strftime('%Y-%m-%d_%H-%M-%S') + ".jpg"

    # 古い画像を削除
    file_list = glob.glob("/media/pi/rasUSB/security_cam/img/*jpg")
    dif_time = datetime.timedelta(days=3)
    for file in file_list:
        file_time = datetime.datetime.fromtimestamp(os.path.getatime(file))
        if (file_time < now  - dif_time):
            print("remove：{0}".format(file))
            os.remove(file)

    # 撮影
    _, frame = camera.read()
    img = cv2.resize(frame, IMG_SIZE)
    ret = cv2.imwrite(fname, img)
    if ret:
        print('撮影画像: ' + fname)
    else:
        print('Failed to write image.')

    # LINEに通知
    # ただし10分は通知しない --- (*1)
    sec = (now - last_post).seconds
    if sec < 10 * 60: return
    last_post = now
    # 通知をLINEに挿入 --- (*2)
    post_data = {'message': 'ニャンズ'}
    headers = {'Authorization': 'Bearer ' + TOKEN}
    files={'imageFile': open(fname,'rb')}
    res = requests.post(API, data=post_data,
        headers=headers,files=files)
    print(res.text)

try:
    sw = 0 # 連続撮影防止
    # 繰り返しセンサーの値を得る
    while True:
        v = GPIO.input(SENSOR_PORT)
        if v == GPIO.HIGH:
            GPIO.output(LED_PORT, GPIO.HIGH)
            take_photo()
            sw = 1
        else:
            GPIO.output(LED_PORT, GPIO.LOW)
            sw = 0
        sleep(10.0)
except KeyboardInterrupt:
        pass
GPIO.cleanup()
```

- カメラ撮影に`opencv`ライブラリを使用しています。  
opencvのラズパイへのインストールはいくつか方法はありますが、コチラが一番簡単で早くおすすめです。  
https://karaage.hatenadiary.jp/entry/2018/10/05/073000
- 保存画像は3日以上前は削除するようにしています。  
日数を伸ばしたい場合は、L30:`dif_time = datetime.timedelta(days=3)`で適当な日数に変更してください。

以上、シンプルなプログラムとなります。

##おわりに
正直、時々しか使ってません。
猫だけでなく、家族が横切るたびにLINEの通知がバンバン来ちゃって。。(´Д｀)
オススメの使い方として、
1泊2日の小旅行や、家族で朝から晩まで外出などしばらく家をあける時ですね、
猫の様子をチェックするのにけっこう活躍していい感じです。

外出中のペットの食事や水飲みが心配な方はいかがでしょうかね？
もちろん「水飲みに来たのかな？」「餌食べすぎだろw」などLINEを通してホッコリするのも楽しいです。