# face_and_smile_detection.py

import cv2
from picamera2 import Picamera2

ESC = 27

# 載入 Haarcascade 分類器：人臉 + 笑臉
face_cascade = cv2.CascadeClassifier('haarcascades/haarcascade_frontalface_alt2.xml')
smile_cascade = cv2.CascadeClassifier('haarcascades/haarcascade_smile.xml')

# 確認 XML 正確載入
if face_cascade.empty():
    print("❌ 無法載入人臉分類器")
    exit()
if smile_cascade.empty():
    print("❌ 無法載入笑臉分類器")
    exit()

# 初始化 Picamera2
picam2 = Picamera2()
config = picam2.create_preview_configuration(main={'size': (640, 480), 'format': 'RGB888'})
picam2.configure(config)
picam2.start()

while True:
    # 擷取影像並翻轉
    frame = picam2.capture_array()
    frame = cv2.flip(frame, -1)  # -1：水平+垂直翻轉 (可依實際鏡頭安裝調整)

    # 轉為灰階
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    # 人臉偵測 (scaleFactor = 1.1, minNeighbors = 5)
    faces = face_cascade.detectMultiScale(
        gray,
        scaleFactor = 1.1,
        minNeighbors = 5,
        minSize=(30, 30)
    )
    print('偵測到人臉數:', len(faces))

    # 對每個人臉區域進行笑臉偵測
    for (x, y, w, h) in faces:
        # 裁剪臉部 Region of Interest
        roi_gray = gray[y:y + h, x:x + w]
        roi_color = frame[y:y + h, x:x + w]

        # 笑臉偵測 (對灰階臉部區進行)
        smiles = smile_cascade.detectMultiScale(
            roi_gray,
            scaleFactor = 1.7,
            minNeighbors = 22,
            minSize=(25, 25)
        )

        # 如果該臉部區域有偵測到笑，就畫黃色框與文字
        if len(smiles) > 0:
            # 繪製笑臉框 (大框為臉部, 小框可用於示範)
            cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 255), 2)
            cv2.putText(
                frame,
                'Smiling',
                (x, y - 10),
                cv2.FONT_HERSHEY_SIMPLEX,
                0.9,
                (0, 255, 255),
                2
            )
        else:
            # 僅有人臉未偵測到笑，畫綠色人臉框
            cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)

        # （選擇性）可將每個 smile 的子框畫出
        # for (sx, sy, sw, sh) in smiles:
        #     cv2.rectangle(roi_color, (sx, sy), (sx + sw, sy + sh), (255, 0, 0), 1)

    # 顯示結果
    cv2.imshow('Face & Smile Detection', frame)

    # 按下 ESC 離開
    if cv2.waitKey(1) == ESC:
        break

# 釋放資源
picam2.stop()
cv2.destroyAllWindows()