人感センサー(HC-SR501)誤検知あるので、カメラとAIで人を検知させることにしました。人感センサーはただのかわいい飾りとなります。
準備
参考サイト
https://qiita.com/SHIJIMI_EN/items/668663d334755a9a1669
1.人検知プログラムダウンロード
モデルとPythonPgmがダウンロードされます。
git clone https://github.com/arisaEN/human-detection.git
監視カメラ 不在時(9:30-11:30)に侵入者がいれば、Line通知。改定
人感センサー部分を改定。この時だけ検知した場合、検知画像を保存。
2.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")
3.ダウンロードした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しないと2回目でcamera busyとなる。
picam2.stop()
picam2.close()
print("check end")
return human_sw
if __name__ == "__main__":
sw()
3.実行してみる。問題無。
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
検知した場合、以下の画像が保存される。
ひまじんが居ない時の処理だが、ひまじんがいるので以下の画像が保存される。
4.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~PCを起動する。 → ラズパイ AI&カメラで人が居るときのみ8:00~11:00~14:00~18:00~PCを起動する。
1.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")
2.実行してみる。問題無。
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
3.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を実現。改定
1.人がいる時にMariaDBのテーブルに人がいることを書き込む。 kenchi_man.py を改修。
1)本体 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")
2.実行してみる。問題無。
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
3.cronはそのまま
sudo crontab -e
中身は以下
50 6 * * * /usr/bin/python3 /home/pi/kenchi_man.py > /tmp/cronm.log 2>&1