import cv2
import time
from pathlib import Path

# ---------- 1. 单帧处理 ----------
def process_frame(img,
                  max_side: int = 1280,
                  padding: float = 0.05):
    """
    返回：画了框的图像 + 人脸个数
    """
    h0, w0 = img.shape[:2]

    # 等比例缩放
    scale = min(1.0, max_side / max(h0, w0))
    img_small = cv2.resize(img, None, fx=scale, fy=scale) if scale < 1.0 else img
    gray = cv2.cvtColor(img_small, cv2.COLOR_BGR2GRAY)

    # 加载分类器
    cascade_path = "./model/haarcascade_frontalface_default.xml"
    face_cascade = cv2.CascadeClassifier(cascade_path)
    faces = face_cascade.detectMultiScale(
        gray, scaleFactor=1.1, minNeighbors=7, minSize=(60, 60)
    )

    # 映射回原图 + 画框
    for (x, y, w, h) in faces:
        x, y, w, h = int(x/scale), int(y/scale), int(w/scale), int(h/scale)
        dw, dh = int(w*padding), int(h*padding)
        x1 = max(0, x - dw)
        y1 = max(0, y - dh)
        x2 = min(w0, x + w + dw)
        y2 = min(h0, y + h + dh)
        cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2)

    return img, len(faces)

# ---------- 2. 主循环 ----------
if __name__ == "__main__":
    # 读一次图，循环用
    img = cv2.imread("./img/friends.jpg")
    if img is None:
        raise FileNotFoundError("friends.jpg")
    # 用摄像头就把路径换成 0；用视频给文件路径
    #cap = cv2.VideoCapture("./img/friends.jpg")   # 视频/摄像头
    # cap = cv2.VideoCapture(0)

    fps_counter = 0
    fps_start = time.time()
    FPS_INTERVAL = 1.0          # 每 1 秒打印一次

    while True:
        #ret, frame = cap.read()
        frame = img.copy()          # ← 1. 每帧用同一张图

        out_frame, num_faces = process_frame(frame)
        fps_counter += 1

        # 显示
        cv2.imshow("Face Detection", out_frame)
        if cv2.waitKey(1) & 0xFF == 27:   # ESC 退出
            break

        # 每秒打印帧率 + 识别结果
        if time.time() - fps_start >= FPS_INTERVAL:
            fps = fps_counter / (time.time() - fps_start)
            print(f"FPS: {fps:5.2f}  |  Faces: {num_faces}")
            fps_counter = 0
            fps_start = time.time()

    #cap.release()
    #cv2.destroyAllWindows()
