import cv2 as cv
import numpy as np
from joblib import load

classifier = load('models/classifier.pkl')

# 预处理图像
def pre_detect(img):
    pre_img = img.copy()
    pre_img = cv.resize(pre_img, (50, 50))
    pre_img = cv.cvtColor(pre_img, cv.COLOR_BGR2GRAY)
    _, pre_img = cv.threshold(pre_img, 127, 255, cv.THRESH_BINARY)
    pre_img = cv.blur(pre_img, (3, 3))
    return pre_img

# 特征提取
def pre_detect(img):
    pre_img = img.copy()
    pre_img = cv.resize(pre_img, (50, 50))
    pre_img = cv.cvtColor(pre_img, cv.COLOR_BGR2GRAY)
    _, pre_img = cv.threshold(pre_img, 127, 255, cv.THRESH_BINARY)
    pre_img = cv.blur(pre_img, (3, 3))
    return pre_img

# 特征提取
def extract_contour_features(img):
    contours, _ = cv.findContours(img, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
    if len(contours) == 0:
        return [0, 0]  # 如果没有轮廓，返回默认值
    contour = contours[0]
    area = cv.contourArea(contour)
    perimeter = cv.arcLength(contour, True)
    return [area, perimeter]

def extract_shape_features(contour):
    x, y, w, h = cv.boundingRect(contour)
    aspect_ratio = float(w) / h
    rect_area = w * h
    shape_factor = cv.contourArea(contour) / rect_area
    return [aspect_ratio, shape_factor]

def extract_hu_moments(contour):
    moments = cv.moments(contour)
    hu_moments = cv.HuMoments(moments)
    return hu_moments.flatten()


def extract_features(img):
    contours, _ = cv.findContours(img, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
    if len(contours) == 0:
        # 如果没有找到轮廓，返回 11 个零，保持特征数量一致
        return [0] * 11
    contour = contours[0]

    # 提取轮廓特征
    contour_features = extract_contour_features(img)

    # 提取形状特征
    shape_features = extract_shape_features(contour)

    # 提取 Hu 矩
    hu_moments = extract_hu_moments(contour)

    # 合并所有特征为一个特征向量，确保总共有 11 个特征
    feature_vector = contour_features + shape_features + hu_moments.tolist()
    return feature_vector


# 读取图像并进行预处理
img = cv.imread('test.jpg')
pre_img = pre_detect(img)

features = extract_features(pre_img)

features = np.array(features).reshape(1, -1)

predict_label = classifier.predict(features)

cv.imshow('face? ' + str(predict_label[0]), img)
cv.waitKey(0)
cv.destroyAllWindows()

# 读取视频并进行检测
cap = cv.VideoCapture(1)

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

    # 预处理
    pre_img = pre_detect(frame)

    # 提取特征
    features = extract_features(pre_img)
    features=np.array(features).reshape(1, -1)

    predict_label = classifier.predict(features)

    # 在帧上显示预测结果
    label_text = 'Face' if predict_label[0] else 'Non-Face'
    cv.putText(frame, label_text, (50, 50), cv.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2, cv.LINE_AA)

    # 展示
    cv.imshow('video', frame)

    if cv.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv.destroyAllWindows()
