You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用DeepFace提取图像embedding向量,替换人脸识别项目的ResNet-34

人脸识别特征提取模块替换实现方案(DeepFace/VGGFace版)

前置准备

首先安装依赖库:

pip install deepface opencv-python imutils face-recognition pickle-mixin

说明:DeepFace内置VGGFace、Facenet等多种预训练人脸识别模型,无需手动实现网络结构,首次运行会自动下载对应权重文件。


一、encoding.py脚本修改

仅替换特征提取逻辑,剩余参数解析、遍历数据集、人脸检测、序列化保存逻辑完全不变,修改后代码如下:

from imutils import paths
import face_recognition
import argparse
import pickle
import cv2
import os
# 新增导入DeepFace
from deepface import DeepFace
import numpy as np

# construct the argument parser and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--dataset", required=True,
    help="path to input directory of faces + images")
ap.add_argument("-e", "--encodings", required=True,
    help="path to serialized db of facial encodings")
ap.add_argument("-d", "--detection-method", type=str, default="cnn",
    help="face detection model to use: either `hog` or `cnn`")
args = vars(ap.parse_args())

# grab the paths to the input images in our dataset
print("[INFO] quantifying faces...")
imagePaths = list(paths.list_images(args["dataset"]))
# initialize the list of known encodings and known names
knownEncodings = []
knownNames = []

# loop over the image paths
for (i, imagePath) in enumerate(imagePaths):
    # extract the person name from the image path
    print("[INFO] processing image {}/{}".format(i + 1,
        len(imagePaths)))
    name = imagePath.split(os.path.sep)[-2]
    # load the input image and convert it from BGR (OpenCV ordering)
    # to dlib ordering (RGB)
    image = cv2.imread(imagePath)
    rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
    # detect the (x, y)-coordinates of the bounding boxes
    # corresponding to each face in the input image
    boxes = face_recognition.face_locations(rgb,
        model=args["detection_method"])
    # --------------------------修改部分开始--------------------------
    # 替换原有ResNet34特征提取为VGGFace特征提取
    encodings = []
    for box in boxes:
        top, right, bottom, left = box
        # 裁剪出人脸区域
        face_crop = rgb[top:bottom, left:right]
        # 提取VGGFace特征,enforce_detection设为False跳过二次人脸检测
        embedding = DeepFace.represent(
            img_path=face_crop,
            model_name="VGG-Face", # 可替换为"Facenet"得到128维特征,适配原有阈值
            enforce_detection=False
        )[0]["embedding"]
        encodings.append(np.array(embedding))
    # --------------------------修改部分结束--------------------------
    # loop over the encodings
    for encoding in encodings:
        # add each encoding + name to our set of known names and
        # encodings
        knownEncodings.append(encoding)
        knownNames.append(name)

# dump the facial encodings + names to disk
print("[INFO] serializing encodings...")
data = {"encodings": knownEncodings, "names": knownNames}
f = open(args["encodings"], "wb")
f.write(pickle.dumps(data))
f.close()

二、预测脚本修改

同样仅替换特征提取逻辑,剩余加载编码、人脸检测、比对、绘图逻辑完全不变,修改后代码如下:

# import the necessary packages
import face_recognition
import argparse
import pickle
import cv2
# 新增导入DeepFace
from deepface import DeepFace
import numpy as np

# construct the argument parser and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-e", "--encodings", required=True,
    help="path to serialized db of facial encodings")
ap.add_argument("-i", "--image", required=True,
    help="path to input image")
ap.add_argument("-d", "--detection-method", type=str, default="hog",
    help="face detection model to use: either `hog` or `cnn`")
args = vars(ap.parse_args())


# load the known faces and embeddings
print("[INFO] loading encodings...")
data = pickle.loads(open(args["encodings"], "rb").read())


# load the input image and convert it from BGR to RGB
image = cv2.imread(args["image"])
rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
# detect the (x, y)-coordinates of the bounding boxes corresponding
# to each face in the input image, then compute the facial embeddings
# for each face
print("[INFO] recognizing faces...")
boxes = face_recognition.face_locations(rgb,
    model=args["detection_method"])
# --------------------------修改部分开始--------------------------
# 替换原有ResNet34特征提取为VGGFace特征提取
encodings = []
for box in boxes:
    top, right, bottom, left = box
    face_crop = rgb[top:bottom, left:right]
    embedding = DeepFace.represent(
        img_path=face_crop,
        model_name="VGG-Face", # 要和encoding.py用的模型名称完全一致
        enforce_detection=False
    )[0]["embedding"]
    encodings.append(np.array(embedding))
# --------------------------修改部分结束--------------------------

# initialize the list of names for each face detected
names = []

# loop over the facial embeddings
for encoding in encodings:
    # attempt to match each face in the input image to our known
    # encodings
    matches = face_recognition.compare_faces(data["encodings"],
        encoding, tolerance=0.7) # VGGFace可适当调大阈值,Facenet用默认0.6即可
    name = "Unknown"

    # check to see if we have found a match
    if True in matches:
        # find the indexes of all matched faces then initialize a
        # dictionary to count the total number of times each face
        # was matched
        matchedIdxs = [i for (i, b) in enumerate(matches) if b]
        counts = {}
        # loop over the matched indexes and maintain a count for
        # each recognized face face
        for i in matchedIdxs:
            name = data["names"][i]
            counts[name] = counts.get(name, 0) + 1
        # determine the recognized face with the largest number of
        # votes (note: in the event of an unlikely tie Python will
        # select first entry in the dictionary)
        name = max(counts, key=counts.get)
    
    # update the list of names
    names.append(name)
print(names)
# loop over the recognized faces
for ((top, right, bottom, left), name) in zip(boxes, names):
    # draw the predicted face name on the image
    cv2.rectangle(image, (left, top), (right, bottom), (0, 255, 0), 2)
    y = top - 15 if top - 15 > 15 else top + 15
    cv2.putText(image, name, (left, y), cv2.FONT_HERSHEY_SIMPLEX,
        0.75, (0, 255, 0), 2)
# show the output image
cv2.imshow("Image", image)
cv2.waitKey(0)

注意事项

  • 两个脚本的model_name参数必须完全一致,否则特征空间不匹配会导致识别完全失效
  • 若希望保持原有128维特征维度,可将model_name改为Facenet,此时tolerance参数保持默认0.6即可
  • 首次运行会自动下载对应预训练权重,存储在本地用户目录下的.deepface文件夹中,无需手动处理

内容的提问来源于stack exchange,提问作者Adrian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 11:09:01