YOLOは1回の畳み込みニューラルネットワーク(CNN)で処理する物体検出モデルです。画像全体を1つのグリッドに分割し、物体の存在を一括で解析、検出するため高速で誤検出が少なくなります(との事です)。
今回トライするのは、先ずは動体検知と通知システムです。
1.接続したカメラでリアルタイム監視をする
2.検知すると音声アラートを出す(Windowsのみ)
3.動画でターゲットを表示する
4.ログを残す
5.メールで通知する
6.スナップショットを保存
import cv2 # OpenCV(カメラ映像取得)
import torch # PyTorch(YOLOを動かすため)
import datetime # 日時の取得
import winsound # 音声アラート(Windows)
import smtplib # メール送信
from email.mime.text import MIMEText # メール送信用
from ultralytics import YOLO # 最新の YOLOv8 を使用
# 🔹 GPUを使用可能ならCUDA、なければCPUを使用
device = 'cuda' if torch.cuda.is_available() else 'cpu'
# 🔹 YOLOv8モデルをロード(物体検出用)
model = YOLO("yolov8s.pt")
# 🔹 カメラを開く(0はデフォルトのカメラ)
cap = cv2.VideoCapture(0)
if not cap.isOpened():
print("カメラが開けませんでした。プログラムを終了します。")
exit()
# 🔹 監視ログファイルを作成
log_file = "detection_log.txt"
with open(log_file, "w") as f:
f.write("=== 監視カメラログ ===\n")
# 🔹 メール通知設定
EMAIL_SENDER = "<メアド>"
EMAIL_PASSWORD = "<パスワード>"
EMAIL_RECEIVER = "<メアド>"
def send_alert(message):
""" 検出した異常をメールで送信 """
msg = MIMEText(message)
msg["Subject"] = "【監視カメラアラート】異常検出"
msg["From"] = EMAIL_SENDER
msg["To"] = EMAIL_RECEIVER
try:
# with smtplib.SMTP_SSL("<メールサーバ>", 465) as server: SSLの場合
with smtplib.SMTP("<メールサーバ>", 587) as server:
server.starttls()
server.login(EMAIL_SENDER, EMAIL_PASSWORD)
server.sendmail(EMAIL_SENDER, EMAIL_RECEIVER, msg.as_string())
print("📩 メール通知を送信しました!")
except Exception as e:
print("⚠️ メール通知の送信に失敗しました:", e)
# 🔹 監視を続ける
while True:
if cv2.waitKey(1) & 0xFF == ord('q'):
break
ret, frame = cap.read() # カメラの映像を取得
if not ret:
print("カメラの映像が取得できません。終了します。")
break
# 🔹 YOLOv8 で物体検出
results = model(frame)
# 🔹 検出されたオブジェクトをログに記録
detected_objects = []
for result in results:
for box in result.boxes:
class_id = int(box.cls[0]) # クラスID(例:人、車、犬など)
confidence = float(box.conf[0]) # 信頼度
label = model.names[class_id] # クラス名(YOLOのラベル)
# ログに保存
detected_objects.append(f"{label}(信頼度: {confidence:.2f})")
# 🔹 もし物体が検出されたらログに書き込み、アラートを鳴らす
if detected_objects:
now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
log_text = f"{now} - 検出: {', '.join(detected_objects)}\n"
print(log_text)
with open(log_file, "a") as f:
f.write(log_text)
# 🔹 スクリーンショットを保存
filename = f"screenshot_{now.replace(':', '-')}.jpg"
cv2.imwrite(filename, frame)
# 🔹 音声アラート(Windowsのみ)
winsound.Beep(1000, 500) # 1kHzの音を0.5秒鳴らす
# 🔹 メール通知
send_alert(log_text)
# 🔹 YOLOの検出結果を描画
frame_with_detections = results[0].plot()
# 🔹 画面にリアルタイム映像を表示
cv2.imshow("Security Cam", frame_with_detections)
# 🔹 'q'キーで監視終了
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# 🔹 カメラを解放し、ウィンドウを閉じる
cap.release()
cv2.destroyAllWindows()
では、早速このプログラムを実行してみます。
$ python <このプログラム名>.py
0: 480x640 1 person, 1 tie, 128.8ms
Speed: 3.1ms preprocess, 128.8ms inference, 1.4ms postprocess per image at shape (1, 3, 480, 640)
2025-03-03 19:51:49 - 検出: person(信頼度: 0.89), tie(信頼度: 0.25)
📩 メール通知を送信しました!
0: 480x640 1 person, 121.6ms
Speed: 2.6ms preprocess, 121.6ms inference, 0.7ms postprocess per image at shape (1, 3, 480, 640)
2025-03-03 19:51:54 - 検出: person(信頼度: 0.73)
📩 メール通知を送信しました!
うん!?早速、何者かが侵入して来た様だ!!
ログを見てみると確かに何者かが検知されている!!
C:\Users> type detection_log.txt
=== 監視カメラログ ===
2025-03-03 19:51:49 - 検出: person(信頼度: 0.89), tie(信頼度: 0.25)
2025-03-03 19:51:54 - 検出: person(信頼度: 0.73)
2025-03-03 19:51:57 - 検出: person(信頼度: 0.94), tie(信頼度: 0.30)
2025-03-03 19:52:00 - 検出: person(信頼度: 0.94)