人感センサー(HC-SR501)誤検知あるので、カメラとAIで人を検知させることにした。人感センサーはただのかわいい飾りとなる。

人感センサー(HC-SR501)誤検知あるので、カメラとAIで人を検知させることにしました。人感センサーはただのかわいい飾りとなります。
# 準備
参考サイト
https://qiita.com/SHIJIMI_EN/items/668663d334755a9a1669
１．人検知プログラムダウンロード
モデルとPythonPgmがダウンロードされます。
```
git clone https://github.com/arisaEN/human-detection.git
```
# 監視カメラ　不在時(9:30-11:30)に侵入者がいれば、Line通知。改定
人感センサー部分を改定。この時だけ検知した場合、検知画像を保存。
２．camera_jimkan.pyよりcamera_human_detect.pyとして作成
```
camera_human_detect.py
#!/usr/bin/env python3
import os
import time
import datetime
import subprocess
import human_detect

if __name__ == '__main__':
    try:
        # 時間計測開始
        t_start = time.perf_counter()
        print("main t_start " + str(t_start))
        while True:
            # 現在時刻取得
            t_end = time.perf_counter()
            print("main t_end " + str(t_end))
            # 経過時間計算
            elaps = t_end - t_start
            print("main elaps " + str(elaps))
            # 2h超えたらブレーク
            if elaps > 7200:
                print("2h over Person nothing")
                break
            human_sw = '0'
            result = human_detect.sw(human_sw)
            print("main Person detect! =" + result)
            if result  == '1':
                print("man search")
                subprocess.check_call('sudo python3 /home/pi/pushMsg.py', shell=True)
                break
            else:
                print("man no search")
                time.sleep(1)
    finally:
        print("end")
```
３．ダウンロードしたscriputのhuman_detection.pyを改定してhuman_detect.pyとしてサブモジュール化。人検知部分をサブモジュール化。これで汎用性があるものになる。
```
human_detect.py
import cv2
import os
import numpy as np
import time
from picamera2 import Picamera2
import requests
import subprocess
from datetime import datetime

def sw(human_sw):
    print("check init1")
    # モデルファイルの絶対パスを設定
    base_dir = "/home/pi/human-detection/models/"
    prototxt_path = os.path.join(base_dir, "deploy.prototxt")
    model_path = os.path.join(base_dir, "mobilenet_iter_73000.caffemodel")
    # モデルを読み込み
    net = cv2.dnn.readNetFromCaffe(prototxt_path, model_path)

    # Picamera2の初期化
    print("check init2")
    picam2 = Picamera2()
    picam2.configure(picam2.create_preview_configuration(main={"size": (500, 375)}))
    picam2.start()
    print("check init3")

# クラスID 15が「person（人）」を指す
    PERSON_CLASS_ID = 15

    save_dir = f"/home/pi/画像"

    print("check start")
    start_time = time.time()

    # カメラからフレームを取得
    frame = picam2.capture_array()

    # もしフレームが4チャネル（RGBA）なら、3チャネル（RGB）に変換
    if frame.shape[2] == 4:
        frame = cv2.cvtColor(frame, cv2.COLOR_RGBA2BGR)
    else:
        frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)

    # 画像サイズ
    h, w = frame.shape[:2]

    # 入力画像をBlob形式に変換
    blob = cv2.dnn.blobFromImage(cv2.resize(frame, (300, 300)), 0.007843, (300, 300), 127.5)
    net.setInput(blob)

    # 推論を実行
    detections = net.forward()

    # 時間計測開始
    t_start = time.perf_counter()
    print("Person Search start")

    # 検出結果の解析
    for i in range(detections.shape[2]):
        # 現在時刻取得
        t_end = time.perf_counter()
        # 経過時間計算
        elaps = t_end - t_start
        print(elaps)
        # 10秒超えたらブレーク    
        if elaps > 10:
            print("Nothing!")
            time.sleep(2)
            break
        confidence = detections[0, 0, i, 2]
        if confidence > 0.5:  # 信頼度50%以上の検出結果のみ表示
            class_id = int(detections[0, 0, i, 1])
            if class_id == PERSON_CLASS_ID:
                # バウンディングボックスの計算
                box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])
                (startX, startY, endX, endY) = box.astype("int")

                # フレームに矩形を描画
                cv2.rectangle(frame, (startX, startY), (endX, endY), (0, 255, 0), 2)
                cv2.putText(frame, "Person", (startX, startY - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
                # personが検出された場合の処理
                print("Person detected!")
                # ひまじんが不在の時に画像を保存
                print("human_sw save jpg = " + human_sw)
                if human_sw == '0':
                    current_time = datetime.now()
                    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
                    filename = f"{save_dir}/{timestamp}.jpg"
                    # フレームをJPEGファイルとして保存
                    cv2.imwrite(filename, frame)
                human_sw = '1'
                time.sleep(2)
                break
            else:
                print("No Person")
                time.sleep(2)
                break
        else:
            print("confidence <= 0.5")
            time.sleep(1)

# カメラを解放 stop & close ※　closeしないと２回目でcamera busyとなる。
    picam2.stop()
    picam2.close()
    print("check end")
    return human_sw

if __name__ == "__main__":
    sw()
```
３．実行してみる。問題無。
```
python3 camera_human_detect.py
```
```
main t_start 31889.949770554
main t_end 31889.949918731
main elaps 0.00014817699775449
check init1
check init2
[8:51:30.253180831] [6920]  INFO Camera camera_manager.cpp:297 libcamera v0.0.5+83-bde9b04f
[8:51:30.398765099] [6924]  INFO RPI vc4.cpp:437 Registered camera /base/soc/i2c0mux/i2c@1/imx708@1a to Unicam device /dev/media0 and ISP device /dev/media1
[8:51:30.398907546] [6924]  INFO RPI pipeline_base.cpp:1101 Using configuration file '/usr/share/libcamera/pipeline/rpi/vc4/rpi_apps.yaml'
[8:51:30.414192390] [6920]  INFO Camera camera.cpp:1033 configuring streams: (0) 500x374-XBGR8888 (1) 1536x864-SBGGR10_CSI2P
[8:51:30.415064675] [6924]  INFO RPI vc4.cpp:565 Sensor: /base/soc/i2c0mux/i2c@1/imx708@1a - Selected sensor format: 1536x864-SBGGR10_1X10 - Selected unicam format: 1536x864-pBAA
check init3
check start
Person Search start
0.00014468700101133436
Person detected!
human_sw save jpg = 0
check end
main Person detect! =1
man search
end
```
検知した場合、以下の画像が保存される。
ひまじんが居ない時の処理だが、ひまじんがいるので以下の画像が保存される。
![20250112_162745.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433305/f26bef82-828f-1a3c-b56f-520ad0c55381.jpeg)

４．crontab修正（名前の変更）
```
sudo crontab -e
```
中身は以下
30 9 * * * /usr/bin/python3 /home/pi/camera_human_detect.py > /tmp/cronj.log 2>&1

# ラズパイ　人感センサーで人が居るときのみ8:00～11:00～14:00～18:00～ＰＣを起動する。 →　ラズパイ　AI＆カメラで人が居るときのみ8:00～11:00～14:00～18:00～ＰＣを起動する。
１．wakeonlan.py 改修
```
wakeonlan.py
#!/usr/bin/ python3
from datetime import datetime
import time
import subprocess
import human_detect

INTERVAL = 3
SLEEPTIME = 20

cmd = "sudo node /home/pi/etherwake.js"

if __name__ == '__main__':
    try:
        print("cancel CTRL+C")
        print("start")
        cnt = 1
        # 時間計測開始
        t_start = time.perf_counter()
        print("main t_start " + str(t_start))
        while True:
            # 現在時刻取得
            t_end = time.perf_counter()
            print("main t_end " + str(t_end))
            # 経過時間計算
            elaps = t_end - t_start
            print("main elaps " + str(elaps))
            # 2h超えたらブレーク
            if elaps > 7200:
                print("2h over Person nothing")
                break
            human_sw = '9'
            result = human_detect.sw(human_sw)
            print("main Person detect =" + result)
            if result  == '1':
                print(datetime.now().strftime('%Y/%m/%d %H:%M:%S') +
                      ":" + str("{0:05d}".format(cnt)) + " human look")
                print("pc wake")
                subprocess.check_call(cmd, shell=True) 
                time.sleep(SLEEPTIME)
                break
            else:
                print("human nolook")
                time.sleep(INTERVAL)
    except KeyboardInterrupt:
        print("stop runnig...")
    finally:
        print("end")
```
２．実行してみる。問題無。
```
python3 wakeonlan.py
```
```
cancel CTRL+C
start
main t_start 32017.425669125
main t_end 32017.425733499
main elaps 6.437399861169979e-05
check init1
check init2
[8:53:37.727907273] [6948]  INFO Camera camera_manager.cpp:297 libcamera v0.0.5+83-bde9b04f
[8:53:37.882913092] [6952]  INFO RPI vc4.cpp:437 Registered camera /base/soc/i2c0mux/i2c@1/imx708@1a to Unicam device /dev/media0 and ISP device /dev/media1
[8:53:37.883134028] [6952]  INFO RPI pipeline_base.cpp:1101 Using configuration file '/usr/share/libcamera/pipeline/rpi/vc4/rpi_apps.yaml'
[8:53:37.897597367] [6948]  INFO Camera camera.cpp:1033 configuring streams: (0) 500x374-XBGR8888 (1) 1536x864-SBGGR10_CSI2P
[8:53:37.898599443] [6952]  INFO RPI vc4.cpp:565 Sensor: /base/soc/i2c0mux/i2c@1/imx708@1a - Selected sensor format: 1536x864-SBGGR10_1X10 - Selected unicam format: 1536x864-pBAA
check init3
check start
Person Search start
0.004816112999833422
Person detected!
human_sw save jpg = 9
check end
main Person detect =1
2025/01/14 00:53:40:00001 human look
pc wake


end
```
３．crontab修正
```
sudo crontab -e
```
中身は以下　11時30分としたいところだが、侵入者検知が9:30-11:30としているのでバッテングしないように11:35分とした。
0 8 * * * /usr/bin/python3 /home/pi/wakeonlan.py > /tmp/cronw.log 2>&1
35 11 * * * /usr/bin/python3 /home/pi/wakeonlan.py > /tmp/cronw.log 2>&1
0 14 * * * /usr/bin/python3 /home/pi/wakeonlan.py > /tmp/cronw.log 2>&1
0 18 * * * /usr/bin/python3 /home/pi/wakeonlan.py > /tmp/cronw.log 2>&1

# ラズパイ　赤外線で消し忘れを自動で消す、人がいる時にエアコンの暖房自動ONを実現。改定
１．人がいる時にMariaDBのテーブルに人がいることを書き込む。　kenchi_man.py を改修。
１）本体　Dbのテーブル更新は　サブ　mariadb_upd.py　で更新させる。
```
kenchi_man.py
#!/usr/bin/ python3
from datetime import datetime
import time
import mariadb_upd
import human_detect

INTERVAL = 3
SLEEPTIME = 20

if __name__ == '__main__':
    try:
        print("start")
        while True:
# 人検知
            cnt = 1
            human_sw = '9'
            result = human_detect.sw(human_sw)
            print("human_sw=" + result)
            if result  == '1':
# query table update run 人検知
                updsw = '1'
                mariadb_upd.sw(updsw)
                print(datetime.now().strftime('%Y/%m/%d %H:%M:%S') +
                    ":" + str("{0:05d}".format(cnt)) + " human look")
                time.sleep(SLEEPTIME)
                break
            else:
# query table update run 人未検知
                updsw = '0'
                mariadb_upd.sw(updsw)
                print("no look")
                time.sleep(INTERVAL)
                break
    finally:
        print("end")
```
２．実行してみる。問題無。
```
python3　kenchi_man.py
```
```
start
check init1
check init2
[8:56:02.325453590] [6992]  INFO Camera camera_manager.cpp:297 libcamera v0.0.5+83-bde9b04f
[8:56:02.474875176] [6996]  INFO RPI vc4.cpp:437 Registered camera /base/soc/i2c0mux/i2c@1/imx708@1a to Unicam device /dev/media0 and ISP device /dev/media1
[8:56:02.475008352] [6996]  INFO RPI pipeline_base.cpp:1101 Using configuration file '/usr/share/libcamera/pipeline/rpi/vc4/rpi_apps.yaml'
[8:56:02.489709867] [6992]  INFO Camera camera.cpp:1033 configuring streams: (0) 500x374-XBGR8888 (1) 1536x864-SBGGR10_CSI2P
[8:56:02.490775797] [6996]  INFO RPI vc4.cpp:565 Sensor: /base/soc/i2c0mux/i2c@1/imx708@1a - Selected sensor format: 1536x864-SBGGR10_1X10 - Selected unicam format: 1536x864-pBAA
check init3
check start
Person Search start
0.00024104000112856738
Person detected!
human_sw save jpg = 9
check end
human_sw=1
 jinkan_kenchi mae： [(1, '1', datetime.datetime(2025, 1, 13, 16, 38, 18))]
 jinkan_kenchi upd： [(1, '1', datetime.datetime(2025, 1, 14, 0, 56, 5))]
2025/01/14 00:56:05:00001 human look
end
```

３．cronはそのまま
```
sudo crontab -e
```
中身は以下
50 6 * * * /usr/bin/python3 /home/pi/kenchi_man.py > /tmp/cronm.log 2>&1

# システム完成