サクッとLINE通知できる監視カメラの作り方。対動物観察にも。

Let’s play with AI.

こんにちは。

AI coordinator管理人の清水秀樹です。

最近はyoutubeばかりでブログの更新をしてませんでした。

youtube楽しいですね。

ということで、表題の通り、今回はブログで「LINE通知できる監視カメラの作り方」を紹介したいと思います。

とても簡単にできるので興味ある方はぜひ作ってみてください。

どんな監視カメラ?

動体を検知すると10秒おきに写真を撮影しLINEに通知するというもの。

動体検知なので、動くものを見つけた瞬間から写真撮影を始めます。

必要なもの

です。ラズパイ持ってねぇ~よって方はPCでも大丈夫です。

ただラズパイの方が置き場所のスペースが少なくて済みます。

監視方法

人だの鳥だのを検知した時に写真とるぞ!!っと意気込んでもよいのですが、マシンパワー必要だし時間かかるしで、今回紹介するのは簡単にカメラ映像から動体検知して写真撮る方法で紹介します。

ちなみに動体検知ってなんだよって方はこの動画を参考にしてください。

LINE通知方法

ラズパイ(またはPC)から撮影した写真でLINE通知するにはLINE Notifyを使用します。

無料です。

ログインしてトークンを発行しましょう。

やり方については紹介しているサイトが他にたくさんあるのでここでは割愛します。

ラズパイのセットアップ

カメラを使えるようにしましょう。

こちらもやり方は適当にググってください。

いきなりソースコード

githubに公開しています。

line_notify_tokenとline = に発行した自身のトークンに変更して使用してください。

それだけで動きます。

# -*- coding: utf-8 -*-
import cv2
import os
import datetime
import time
import numpy as np
import requests,os

# os.chdir("./photo") #画像保存先に移動
line_notify_token = '発行したトークン'
line_notify_api = 'https://notify-api.line.me/api/notify'
message = '誰かな??'

def flame_sub(im1,im2,im3,th,blur):
    d1 = cv2.absdiff(im3, im2)
    d2 = cv2.absdiff(im2, im1)
    diff = cv2.bitwise_and(d1, d2)
    # True if the difference is smaller than the threshold.
    mask = diff < th
    # Generate an array with the same size as the background image
    im_mask = np.empty((im1.shape[0],im1.shape[1]),np.uint8)
    im_mask[:][:]=255
    # True parts (background) are painted in black.
    im_mask[mask]=0
    # Small noise reduction
    im_mask = cv2.medianBlur(im_mask,blur)

    return  im_mask

if __name__ == '__main__':
    cam = cv2.VideoCapture(0)
    #cam.set(3, 640)  # Width
    #cam.set(4, 380)  # Heigh
    im1 = cv2.cvtColor(cam.read()[1], cv2.COLOR_RGB2GRAY)
    im2 = cv2.cvtColor(cam.read()[1], cv2.COLOR_RGB2GRAY)
    im3 = cv2.cvtColor(cam.read()[1], cv2.COLOR_RGB2GRAY)

    new_dir_path = 'data'
    save_flg = 0

    #Create a saving folder
    try:
        os.makedirs(new_dir_path)
    except FileExistsError:
        pass

    start = time.time()

    while True:
        # Difference between frames
        im_fs = flame_sub(im1,im2,im3,5,7)
        #cv2.imshow("Motion Mask",im_fs)

        #Detecting contours
        cnts = cv2.findContours(im_fs, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
        cnts = cnts[0] if len(cnts) == 2 else cnts[1]
        ret, frame = cam.read()

        backup_frame = frame.copy()

        #Surround the outline with squares.
        for c in cnts:
           x,y,w,h = cv2.boundingRect(c)
           if w < 40: continue
           save_flg = 1
           cv2.rectangle(frame, (x, y), (x+w, y+h),(0, 255, 0), 3)

        # motion detection
        time_lag = time.time() - start
        if save_flg == 1 and time_lag > 10:
            start = time.time()
            save_path = new_dir_path + '/' + str('{0:%Y%m%d%H%S}'.format(datetime.datetime.now())) + '.jpg'
            cv2.imwrite(save_path, backup_frame,[cv2.IMWRITE_JPEG_QUALITY,30])
            save_flg = 0

            #line
            payload = {'message': message}
            headers = {'Authorization': 'Bearer ' + line_notify_token}
            files = {'imageFile': open(save_path, "rb")} #バイナリファイルを開く
            line_notify = requests.post(line_notify_api, data=payload, headers=headers, files=files)

        #cv2.imshow("Input",frame)

        im1 = im2
        im2 = im3
        im3 = cv2.cvtColor(cam.read()[1], cv2.COLOR_RGB2GRAY)
        key = cv2.waitKey(10)
        # Press the Esc key and you're done.
        if key == 27:
            cv2.destroyAllWindows()
            break

自動起動

ラズパイを使用する場合は、電源入れたときに上記プログラムが自動起動するように設定する必要があります。

いくつかやり方があるようですが、systemdにserviceファイルを作るやり方が良いです。

こちらのサイトが参考になります。

自動再起動の設定

フリーズしたら再起動するという素晴らしい設定方法があります。

Watchdog timerというやつです。

これをやらないとラズパイの場合、一晩でフリーズして動かなくなるので、ラズパイで運用する際は、この設定は必須といえるでしょう。

これで準備完了

監視したい場所に設置してカメラの前でウニョウニョ動いてみましょう。

10秒おきにLINEに写真が送られてくると思います。

応用編

今回は動体を検知したら10秒おきに写真を撮影してLINE通知する仕組みを構築しました。

これをOPENCVのカスケードファイルを使用して、人を検知したら通知するといったように作り変えることも可能です。

YOLOを使ってLINE通知する仕組みなんかも出来るので、お好みに合わせて改変すると良いと思います。

これ読んでも分からんという方へ

一緒に作りませんか

 

それではまた!

あなたにオススメの記事

コメント

  1. この記事へのコメントはありません。

  1. この記事へのトラックバックはありません。

PAGE TOP