# data[].attributes.body
Phạm Vũ Tuấn

Trần Ngọc Nguyên

Phạm Văn Sơn

Phạm Ngọc Tuấn

# data[].attributes.body
import cv2
import numpy as np
import os
from datetime import datetime
# Đường dẫn thư mục lưu video
save_directory = "luuvideo/"

# Khởi tạo camera
camera_id = 0
cap = cv2.VideoCapture(camera_id)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)
# Tạo bộ trừ nền dùng thuật toán MOG2
fgbg = cv2.createBackgroundSubtractorMOG2(history=500, varThreshold=25, detectShadows=True)

# Khởi tạo VideoWriter để lưu video

fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = None

# Trạng thái phát hiện chuyển động và file log
motion_detection_enabled = True  # Bắt đầu với chế độ phát hiện chuyển động được bật
motion_detected = False
log_file = open("Video_log.txt", "a")

# Vòng lặp chính để xử lý khung hình video
while True:
    ret, frame = cap.read()
    if not ret:
        break

    # Áp dụng trừ nền để lấy foreground mask
    fgmask = fgbg.apply(frame)

    # Làm mịn mặt nạ để giảm nhiễu
    kernel = np.ones((3, 3), np.uint8)
    fgmask = cv2.morphologyEx(fgmask, cv2.MORPH_OPEN, kernel)
    fgmask = cv2.morphologyEx(fgmask, cv2.MORPH_DILATE, kernel)

    # Giả định rằng không có chuyển động
    motion_detected = False

    # Kiểm tra nếu chế độ phát hiện chuyển động đang bật
    if motion_detection_enabled:
        contours, _ = cv2.findContours(fgmask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
        for contour in contours:
            if cv2.contourArea(contour) < 1000:
                continue

            x, y, w, h = cv2.boundingRect(contour)
            cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
            motion_detected = True

            # Lấy thời gian hiện tại để ghi log và đặt tên file video
            current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            log_file.write(f"Video detected at: {current_time}\n")

            # Đường dẫn thư mục lưu video
            save_directory = "luuvideo/"
            # Tạo file video để lưu khi phát hiện chuyển động nếu chưa có file ghi
            if out is None:
                video_filename = os.path.join(save_directory, f"Video_{current_time.replace(':', '-')}.avi")
                out = cv2.VideoWriter(video_filename, fourcc, 20.0, (640, 480))

    # Hiển thị thời gian hiện tại lên khung hình
    current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    cv2.putText(frame, current_time, (10, frame.shape[0] - 10), cv2.FONT_HERSHEY_SIMPLEX,
                0.6, (255, 255, 255), 1, cv2.LINE_AA)

    # Ghi khung hình vào file video nếu phát hiện chuyển động
    if motion_detected and out is not None:
        out.write(frame)

    # Hiển thị thông báo cảnh báo lên khung hình nếu phát hiện chuyển động
    if motion_detected:
        cv2.putText(frame, "CANH BAO!", (20, 50), cv2.FONT_HERSHEY_SIMPLEX,
                    1.5, (0, 0, 255), 3, cv2.LINE_AA)

    # Hiển thị trạng thái hiện tại của phát hiện chuyển động (ON/OFF)
    status_text = "Phat hien: ON" if motion_detection_enabled else "Phat hien: OFF"
    status_color = (0, 255, 0) if motion_detection_enabled else (0, 0, 255)
    cv2.putText(frame, status_text, (20, 80), cv2.FONT_HERSHEY_SIMPLEX, 0.8, status_color, 2, cv2.LINE_AA)

    # Hiển thị video feed và mặt nạ foreground
    cv2.imshow('Motion Detection', frame)
    cv2.imshow('Foreground Mask', fgmask)

    # Xử lý đầu vào từ bàn phím
    key = cv2.waitKey(1) & 0xFF
    if key == ord('q'):
        break
    elif key == ord('m'):
        motion_detection_enabled = not motion_detection_enabled

# Giải phóng tài nguyên sau khi hoàn tất
if out is not None:
    out.release()
log_file.close()
cap.release()
cv2.destroyAllWindows()

# data[].attributes.body
import cv2
import os
import numpy as np
from PIL import Image
import time

# Khởi tạo camera
cam = cv2.VideoCapture(0)
cam.set(3, 640)  # đặt chiều rộng video
cam.set(4, 480)  # đặt chiều cao video

# Tải bộ phát hiện khuôn mặt đã được huấn luyện trước
face_detector = cv2.CascadeClassifier(r'C:\levanan\pycharm\haarcascades\haarcascades\haarcascade_frontalface_default.xml')

# Đường dẫn đến thư mục chứa dữ liệu khuôn mặt
#Kiểm tra xem thư mục dataset có tồn tại không và tạo nó nếu không có.
dataset_path = 'dataset'
if not os.path.exists(dataset_path):
    os.makedirs(dataset_path)

# Tự động đặt ID theo số thứ tự
face_id = len(os.listdir(dataset_path)) + 1

print(f"\n [INFO] ID Khuôn Mặt: {face_id}")
print("\n [INFO] Khởi tạo camera...")

count = 0

while True:
    ret, img = cam.read()
    img = cv2.flip(img, 1)  # lật hình ảnh video theo chiều dọc
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    faces = face_detector.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(50, 50))

    for (x, y, w, h) in faces:
        cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)
        count += 1
        cv2.imwrite(f'{dataset_path}/User.{face_id}.{count}.jpg', gray[y:y + h, x:x + w])
        time.sleep(0.01)  # Chụp chậm lại mỗi 0.01 giây

    cv2.imshow('dataset', img)
    if cv2.waitKey(1) & 0xff == 27 or count >= 50:  # Nhấn 'ESC' để thoát hoặc chụp đủ 50 ảnh
        break

print("\n [INFO] Đã chụp đủ ảnh. Bắt đầu huấn luyện mô hình...")
cam.release()
cv2.destroyAllWindows()

# Huấn luyện mô hình
recognizer = cv2.face.LBPHFaceRecognizer_create()

def get_images_and_labels(path):
    image_paths = [os.path.join(path, f) for f in os.listdir(path) if f.endswith('.jpg')]
    #face_samples để lưu trữ các hình ảnh khuôn mặt và ids để lưu trữ các ID tương ứng.
    face_samples, ids = [], []
    for image_path in image_paths:
        #Mỗi hình ảnh được mở, chuyển đổi sang thang độ xám (sử dụng .convert('L')), và sau đó chuyển đổi thành một mảng NumPy kiểu uint8
        img_numpy = np.array(Image.open(image_path).convert('L'), 'uint8')
        id = int(os.path.split(image_path)[-1].split(".")[1])
        faces = face_detector.detectMultiScale(img_numpy)
        for (x, y, w, h) in faces:
            face_samples.append(img_numpy[y:y + h, x:x + w])
            ids.append(id)
    return face_samples, ids

faces, ids = get_images_and_labels(dataset_path)

# Kiểm tra dữ liệu huấn luyện trước khi tiến hành huấn luyện
if len(faces) == 0 or len(ids) == 0:
    print("[ERROR] Không có dữ liệu huấn luyện")
    exit()

recognizer.train(faces, np.array(ids))
recognizer.write('trainer.yml')
print(f"\n [INFO] {len(np.unique(ids))} khuôn mặt đã được huấn luyện. Thoát chương trình.")