Học phần: NHẬP MÔN THỊ GIÁC MÁY TÍNH VỚI PYTHON

CAMERA AN NINH THÔNG MINH

Hệ thống hoạt động theo tiêu chuẩn camera an ninh hiện đại:

  1. Phát hiện đối tượng bằng YOLOv8: Chỉ kích hoạt khi nhận diện chính xác nhãn person (tránh báo động giả do chó mèo hoặc rèm cửa lay động).

  2. Cơ chế Cooldown (Thời gian hạ nhiệt): Sau khi chụp ảnh cảnh báo, hệ thống chờ 10–15 giây trước khi chụp lượt kế tiếp để không bị spam thông báo.

  3. Lưu trữ bằng chứng & Báo động đa kênh:

    • Tự động chụp ảnh góc quay thời điểm đột nhập, đóng dấu thời gian (Timestamp) và lưu vào thư mục alerts/.

    • Phát chuông báo động bằng âm thanh winsound.

    • Tích hợp gửi ngay ảnh và tin nhắn cảnh báo tức thì về Telegram Bot của bố mẹ qua HTTP API (hoặc in log sẵn sàng nếu chưa cấu hình bot).

Mã nguồn Đồ án 2: smart_security_camera.py

import cv2
import time
import os
import datetime
import threading
import winsound
import requests
from ultralytics import YOLO

class SecurityAlerter:
    """Module phụ trách lưu ảnh và gửi thông báo đa kênh"""
    def __init__(self, telegram_token="", chat_id=""):
        self.token = telegram_token
        self.chat_id = chat_id
        self.save_dir = "alerts"
        os.makedirs(self.save_dir, exist_ok=True)

    def trigger_alert(self, frame):
        """Kích hoạt chuỗi hành động cảnh báo chạy trên luồng phụ (Thread) để không đứng camera"""
        threading.Thread(target=self._process_alert, args=(frame.copy(),), daemon=True).start()

    def _process_alert(self, frame):
        # 1. Phát âm thanh còi hú báo động
        try:
            for _ in range(2):
                winsound.Beep(2200, 300)
                time.sleep(0.05)
        except Exception:
            pass

        # 2. Lưu ảnh bằng chứng với dấu mốc thời gian
        now_str = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
        img_path = os.path.join(self.save_dir, f"intruder_{now_str}.jpg")
        
        # Đóng dấu ngày giờ lên ảnh
        cv2.putText(frame, f"CANH BAO XAM NHAP: {now_str}", (20, 40),
                    cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 255), 2)
        cv2.imwrite(img_path, frame)
        print(f"📸 [SECURITY] Đã lưu ảnh bằng chứng: {img_path}")

        # 3. Gửi ảnh qua Telegram Bot (nếu có cấu hình)
        if self.token and self.chat_id:
            try:
                url = f"https://api.telegram.org/bot{self.token}/sendPhoto"
                with open(img_path, "rb") as f:
                    requests.post(url, data={"chat_id": self.chat_id, "caption": f"🚨 Phát hiện người đột nhập lúc {now_str}!"}, files={"photo": f}, timeout=5)
                print("📨 [TELEGRAM] Đã gửi thông báo thành công đến điện thoại!")
            except Exception as e:
                print(f"⚠️ Gửi Telegram thất bại: {e}")


class SmartSecurityCameraApp:
    def __init__(self, camera_index=0):
        self.cap = cv2.VideoCapture(camera_index)
        self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
        self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)

        # Nạp mô hình YOLOv8 Nano nhẹ
        self.model = YOLO("yolov8n.pt")
        
        # Cấu hình Token và Chat ID Telegram (để trống nếu chỉ test lưu ảnh & còi hú)
        self.alerter = SecurityAlerter(telegram_token="", chat_id="")

        # Quản lý thời gian chống spam cảnh báo
        self.cooldown_seconds = 12
        self.last_alert_time = 0

    def run(self):
        if not self.cap.isOpened():
            print("❌ Không mở được camera.")
            return

        print("--- CAMERA AN NINH THÔNG MINH YOLOv8 ĐANG HOẠT ĐỘNG ---")
        print(" -> Hệ thống quét người xâm nhập tự động")
        print(" -> Nhấn [Q] để tắt camera")

        while True:
            ret, frame = self.cap.read()
            if not ret:
                break

            # Dự đoán với YOLOv8, ngưỡng tin cậy 0.6
            results = self.model(frame, conf=0.6, verbose=False)
            person_detected = False

            for box in results[0].boxes:
                cls_id = int(box.cls[0])
                label = self.model.names[cls_id]

                # CHỈ QUAN TÂM ĐẾN CON NGƯỜI (person)
                if label == "person":
                    person_detected = True
                    x1, y1, x2, y2 = map(int, box.xyxy[0])
                    conf = float(box.conf[0])

                    # Vẽ khung đỏ cảnh báo
                    cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 0, 255), 2)
                    cv2.putText(frame, f"Nguoi {int(conf*100)}%", (x1, y1 - 10),
                                cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 255), 2)

            curr_time = time.time()
            time_since_last_alert = curr_time - self.last_alert_time

            # Kích hoạt báo động nếu phát hiện người và đã hết thời gian Cooldown
            if person_detected:
                if time_since_last_alert > self.cooldown_seconds:
                    self.last_alert_time = curr_time
                    self.alerter.trigger_alert(frame)
                else:
                    # Đang trong thời gian hạ nhiệt Cooldown
                    remaining = int(self.cooldown_seconds - time_since_last_alert)
                    cv2.putText(frame, f"COOLDOWN: {remaining}s", (20, 70),
                                cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 255), 2)

            # Đèn báo trạng thái hệ thống
            status_color = (0, 0, 255) if person_detected else (0, 255, 0)
            status_text = "CANH BAO: CO NGUOI!" if person_detected else "HE THONG AN TOAN"
            cv2.circle(frame, (30, 30), 10, status_color, cv2.FILLED)
            cv2.putText(frame, status_text, (50, 35),
                        cv2.FONT_HERSHEY_SIMPLEX, 0.7, status_color, 2)

            cv2.imshow("Smart Security AI Monitor", frame)
            if cv2.waitKey(1) & 0xFF == ord('q'):
                break

        self.cap.release()
        cv2.destroyAllWindows()
        print(" Đã tắt hệ thống an ninh.")

if __name__ == "__main__":
    app = SmartSecurityCameraApp()
    app.run()

HƯỚNG DẪN BÁO CÁO TỐT NGHIỆP CÙNG BÉ

  1. Với Đồ án 1 (Nhà thông minh):

    • Cho bé đứng cách xa camera 1–2 mét và làm các cử chỉ: xòe bàn tay để bật đèn, nắm tay để tắt đèn và giơ 2 ngón để tự động bật trình duyệt.

    • Giải thích cho bé: Cơ chế này hoàn toàn có thể thay bằng việc gửi tín hiệu xuống một con chip ESP32/Arduino nối với bóng đèn 220V ngoài đời thực.

  2. Với Đồ án 2 (Camera an ninh):

    • Hướng camera vào cửa phòng. Khi bố hoặc bé bước vào, còi hú kêu lên, màn hình chớp đỏ và ảnh chụp khuôn mặt lập tức được lưu vào thư mục alerts/.

    • Giúp con hiểu được sự khác biệt giữa AI nhận diện vật thể thông minh (chỉ bắt người) với các loại cảm biến chuyển động hồng ngoại đơn giản ngoài thị trường.