112 lines
3.0 KiB
Python
112 lines
3.0 KiB
Python
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()
|