目次
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通知する仕組みなんかも出来るので、お好みに合わせて改変すると良いと思います。
これ読んでも分からんという方へ
それではまた!
この記事へのコメントはありません。