OpenCV、Dlib与MTCNN人脸检测算法性能对比
# 人脸检测 - Dlib优化版
import cv2
import dlib
import glob
import datetime
# 图像分类目录
PROCESSED_DIR = "output/processed/"
UNDETECTED_DIR = "output/undetected/"
ERROR_DIR = "output/error/"
MULTI_DIR = "output/multi_face/"
ORIGINAL_DIR = "input/"
# 初始化检测器
face_detector = dlib.get_frontal_face_detector()
landmark_predictor = dlib.shape_predictor("models/shape_predictor_68_face_landmarks.dat")
start_time = datetime.datetime.now()
image_count = 0
error_count = 0
for img_path in glob.glob(ORIGINAL_DIR + "*.jpg"):
image = cv2.imread(img_path)
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 多尺度检测
faces = face_detector(gray_image, 3)
face_num = len(faces)
filename = img_path.split("\\")[-1]
if face_num > 1:
print("多人脸检测:", filename)
cv2.imwrite(MULTI_DIR + filename, image)
continue
if face_num == 0:
error_count += 1
print(f"未检测到人脸({error_count}):", filename)
cv2.imwrite(UNDETECTED_DIR + filename, image)
continue
# 提取面部特征点
face_shape = landmark_predictor(image, faces[0])
if len(face_shape.parts()) < 68:
print("异常检测结果:", filename)
cv2.imwrite(ERROR_DIR + filename, image)
continue
# 绘制检测框与特征点
for point in face_shape.parts():
cv2.circle(image, (point.x, point.y), 1, (0, 255, 0), 2)
x, y, w, h = faces[0].left(), faces[0].top(), faces[0].width(), faces[0].height()
cv2.rectangle(image, (x, y), (x+w, y+h), (0, 255, 0), 2)
cv2.imwrite(PROCESSED_DIR + filename, image)
image_count += 1
print("检测耗时:", datetime.datetime.now() - start_time)
# 人脸检测 - OpenCV增强版
import cv2
import glob
import datetime
# 初始化分类器
face_cascade = cv2.CascadeClassifier("models/haarcascade_frontalface_default.xml")
input_dir = "input/"
output_dir = "output/"
start_time = datetime.datetime.now()
undetected_count = 0
for img_path in glob.glob(input_dir + "*.jpg"):
image = cv2.imread(img_path)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 多级图像预处理
_, binary1 = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_TRIANGLE)
_, binary2 = cv2.threshold(gray, 100, 255, cv2.THRESH_OTSU)
binary3 = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY, 25, 10)
# 高斯降噪
processed = cv2.GaussianBlur(binary3, (7,7), 0)
# 多尺度检测
faces = face_cascade.detectMultiScale(processed, scaleFactor=1.2,
minNeighbors=3, minSize=(32,32))
filename = img_path.split("\\")[-1]
face_num = len(faces)
if face_num > 1:
print("多人脸检测:", filename)
cv2.imwrite(output_dir + "multi/" + filename, image)
continue
if face_num == 0:
undetected_count += 1
print(f"未检测到人脸({undetected_count}):", filename)
cv2.imwrite(output_dir + "undetected/" + filename, image)
continue
# 绘制检测结果
for (x, y, w, h) in faces:
cv2.rectangle(image, (x, y), (x+w, y+h), (0, 255, 0), 2)
cv2.circle(image, (x + w//4, y + h//4 + 30), min(w//8, h//8), (0, 255, 0))
cv2.circle(image, (x + 3*w//4, y + h//4 + 30), min(w//8, h//8), (0, 255, 0))
cv2.rectangle(image, (x + 3*w//8, y + 3*h//4),
(x + 5*w//8, y + 7*h//8), (0, 255, 0))
cv2.imwrite(output_dir + "detected/" + filename, image)
print("检测耗时:", datetime.datetime.now() - start_time)
# 人脸检测 - MTCNN实现
import mxnet as mx
import cv2
import glob
import time
import datetime
# 初始化检测器
mtcnn_model = MtcnnDetector(model_folder="models/mxnet", ctx=mx.cpu(0),
num_worker=4, accurate_landmark=False)
input_dir = "input/"
output_dir = "output/"
start_time = datetime.datetime.now()
undetected_count = 0
def process_images():
for img_path in glob.glob(input_dir + "*.jpg"):
image = cv2.imread(img_path)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
filename = img_path.split("\\")[-1]
# 执行检测
start = time.time()
results = mtcnn_model.detect_face(image)
elapsed = time.time() - start
if results is None:
undetected_count += 1
print(f"未检测到人脸({undetected_count}):", filename)
cv2.imwrite(output_dir + "undetected/" + filename, image)
continue
boxes, points = results
face_num = len(boxes)
if face_num > 1:
print("多人脸检测:", filename)
for box in boxes:
cv2.rectangle(image, (int(box[0]), int(box[1])),
(int(box[2]), int(box[3])), (0, 255, 0), 2)
for p in points:
for i in range(5):
cv2.circle(image, (p[i], p[i+5]), 1, (0, 255, 0), 2)
cv2.imwrite(output_dir + "multi/" + filename, image)
continue
if face_num == 0:
undetected_count += 1
print(f"未检测到人脸({undetected_count}):", filename)
cv2.imwrite(output_dir + "undetected/" + filename, image)
continue
# 绘制检测结果
for box in boxes:
cv2.rectangle(image, (int(box[0]), int(box[1])),
(int(box[2]), int(box[3])), (0, 255, 0), 2)
for p in points:
for i in range(5):
cv2.circle(image, (p[i], p[i+5]), 1, (0, 255, 0), 2)
cv2.imwrite(output_dir + "detected/" + filename, image)
print(f"检测耗时: {elapsed:.4f}s")
process_images()
print("总耗时:", datetime.datetime.now() - start_time)