yukのブログ

ラズパイで監視カメラ(LINE通知まで)

やること

・ラズパイの初期設定
・ライブラリの導入
・顔認識プログラムの実行

使用したもの

ラズベリーパイ 4 コンピューターモデルB 8GB Raspberry Pi 4 ラズパイ 4

raspberry-pi.ksyic.com

・EMEET Webカメラ HD1080P

https://amzn.asia/d/0eA1PQDo

ラズパイの初期設定

初期設定は下記のサイトを参考にしました。

zenn.dev

ライブラリの導入

sudo apt install -y libatlas-base-dev
pip install numpy --upgrade
pip install opencv-python

しかし、pipコマンドを実行すると

error: externally-managed-environment

というエラーが発生しました。
エラーを調べると仮想環境内であればpipが使用できるとのことだったので、仮想環境を作成します。

python3 -m venv default

※以降のpip/python3コマンドはdefault環境を使用するため

./default/bin/pip numpy --upgrade
./default/bin/pip opencv-python

のようなパスで呼び出します。

プログラムの実行

カメラとopencvを使用したプログラムを実行します。
ですが、その前に顔認識を行うための学習済みモデルをダウンロードしておきます。

モデルのダウンロード

github.com

プログラム

やっていることは
・カメラの映像を表示
・顔が認識された場合、「Face Detected」という文字を表示する
・顔が認識されると画像を保存し、LINEに画像を送信する。
・何度も通知されないように、通知すると5分のクールタイムを取るようにする。

実際に運用する場合はカメラの映像や文字の表示は不要になるかと思います。

human-detect.py

import cv2
import time
import requests
import datetime

face_detector = cv2.FaceDetectorYN_create("/set/your/path/yunet_n_640_640.onnx", "", (0, 0))
cap = cv2.VideoCapture(0)

cooldown = 300
now = time.time() - cooldown

while True:
    ret, img = cap.read()
    height, width, _ = img.shape
    face_detector.setInputSize((width, height))
    _, faces = face_detector.detect(img)
    
    if faces is not None :
        cv2.putText(img, 'Face Detected', (20,50), cv2.FONT_HERSHEY_SIMPLEX, 1.2, (0,0,200), 2, cv2.LINE_AA)
        detected_at = time.time()
        if detected_at - now > cooldown:
            now = time.time()
            # save photo
            dt_now = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
            filename = "/your/path/Downloads/jpg/" + dt_now + ".jpg"
            cv2.imwrite(filename, img)
            # notify to line
            strToken = "YOUR_TOKEN";
            payload = {
                'message': "someone passed through in front of your home!!!",
            }
            files = {'imageFile': open(filename, 'rb')}
            headers = {
                "Authorization" : "Bearer "+ strToken
            }
            response = requests.post("https://notify-api.line.me/api/notify", data=payload, headers=headers, files=files)
        
    cv2.imshow('video image', img)
    key = cv2.waitKey(10)
    if key == 27:
        break
    
cap.release()
cv2.destroyAllWindows()

参考

Raspberry Pi 4 model Bを買ったけどディスプレイとかないのでMacだけで初期設定をする

【初心者】ラズパイでタイムラプス動画を作成する #初心者 - Qiita

【AI/ML】OpenCVによる顔検出と顔認識(CascadeClassifier, FaceDetectorYN, FaceRecognizerSF) | イー・レンジャー株式会社

ラズベリーパイbookwormのPython環境