由于人脸识别涉及到深度学习和计算机视觉等领域,实现一个完整的人脸识别程序需要用到各种库和框架,比如OpenCV、Dlib、TensorFlow等。在此,我将以Dlib和OpenCV为例,简要介绍如何用Python实现一个基于人脸识别的程序,并且在新增人脸图片时不需要重新训练模型。

  1. 安装必要的库和框架

首先需要安装Dlib和OpenCV,可以使用pip命令进行安装:

pip install dlib
pip install opencv-python
  1. 加载人脸检测器和人脸识别器模型

Dlib提供了一个现成的人脸检测器模型和人脸识别器模型,可以直接使用。可以在官网上下载训练好的模型文件,并将其放在程序的同级目录下。

import dlib

# 加载人脸检测器和人脸识别器模型
detector = dlib.get_frontal_face_detector()  # 人脸检测器
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")  # 人脸特征点检测器
face_recognizer = dlib.face_recognition_model_v1("dlib_face_recognition_resnet_model_v1.dat")  # 人脸识别器
  1. 加载已有的人脸特征向量

为了避免每次新增人脸图片时都需要重新训练模型,可以将已有的人脸特征向量保存到本地文件中,并在需要时进行加载。可以使用pickle库将特征向量保存到本地文件中。

import pickle

# 加载已有的人脸特征向量
with open("face_encodings.pickle", "rb") as f:
    known_face_encodings = pickle.load(f)
    
# 加载已有的人脸标签
with open("face_labels.pickle", "rb") as f:
    known_face_labels = pickle.load(f)
  1. 提取人脸特征向量

当新增一张人脸图片时,需要首先检测出人脸,并提取人脸特征向量。可以使用Dlib的人脸检测器和人脸识别器来实现。

import cv2
import numpy as np

# 提取人脸特征向量
def extract_face_encodings(img):
    # 缩放图像,加快检测速度
    img_small = cv2.resize(img, (0, 0), fx=0.25, fy=0.25)
    # 转换为灰度图像
    img_gray = cv2.cvtColor(img_small, cv2.COLOR_BGR2GRAY)
    # 检测人脸
    faces = detector(img_gray, 1)
    if len(faces) == 0:
        return None
    # 提取人脸特征向量
    face_encodings = []
    for face in faces:
        landmarks = predictor(img_small, face)
        face_encoding = face_recognizer.compute_face_descriptor(img_small, landmarks)
        face_encodings.append(face_encoding)
    return face_encodings

其中,img为待处理的图像,face_encodings为提取出的人脸特征向量。

  1. 添加新的人脸特征向量

当提取出人脸特征向量后,将其添加到已有的特征向量中。

# 添加新的人脸特征向量
def add_face_encodings(face_encodings, label):
    known_face_encodings.append(face_encodings)
    known_face_labels.append(label)
    # 保存已有的人脸特征向量和标签
    with open("face_encodings.pickle", "wb") as f:
        pickle.dump(known_face_encodings, f)
    with open("face_labels.pickle", "wb") as f:
        pickle.dump(known_face_labels, f)

其中,face_encodings为待添加的人脸特征向量,label为对应的人脸标签。

  1. 识别人脸

当需要识别一张人脸图片时,首先需要提取出其特征向量,然后与已有的特征向量进行比对,找到最相似的人脸标签。

# 识别人脸
def recognize_face(img):
    # 提取人脸特征向量
    face_encodings = extract_face_encodings(img)
    if face_encodings is None:
        return None
    # 与已有的特征向量进行比对
    face_distances = np.linalg.norm(known_face_encodings - face_encodings, axis=1)
    best_match_index = np.argmin(face_distances)
    if face_distances[best_match_index] < 0.6:
        return known_face_labels[best_match_index]
    else:
        return None

其中,img为待识别的图像,返回值为对应的人脸标签,如果无法识别则返回None。

完整的代码如下:

import cv2
import dlib
import numpy as np
import pickle

# 加载人脸检测器和人脸识别器模型
detector = dlib.get_frontal_face_detector()  # 人脸检测器
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")  # 人脸特征点检测器
face_recognizer = dlib.face_recognition_model_v1("dlib_face_recognition_resnet_model_v1.dat")  # 人脸识别器

# 加载已有的人脸特征向量
with open("face_encodings.pickle", "rb") as f:
    known_face_encodings = pickle.load(f)
    
# 加载已有的人脸标签
with open("face_labels.pickle", "rb") as f:
    known_face_labels = pickle.load(f)

# 提取人脸特征向量
def extract_face_encodings(img):
    # 缩放图像,加快检测速度
    img_small = cv2.resize(img, (0, 0), fx=0.25, fy=0.25)
    # 转换为灰度图像
    img_gray = cv2.cvtColor(img_small, cv2.COLOR_BGR2GRAY)
    # 检测人脸
    faces = detector(img_gray, 1)
    if len(faces) == 0:
        return None
    # 提取人脸特征向量
    face_encodings = []
    for face in faces:
        landmarks = predictor(img_small, face)
        face_encoding = face_recognizer.compute_face_descriptor(img_small, landmarks)
        face_encodings.append(face_encoding)
    return face_encodings

# 添加新的人脸特征向量
def add_face_encodings(face_encodings, label):
    known_face_encodings.append(face_encodings)
    known_face_labels.append(label)
    # 保存已有的人脸特征向量和标签
    with open("face_encodings.pickle", "wb") as f:
        pickle.dump(known_face_encodings, f)
    with open("face_labels.pickle", "wb") as f:
        pickle.dump(known_face_labels, f)

# 识别人脸
def recognize_face(img):
    # 提取人脸特征向量
    face_encodings = extract_face_encodings(img)
    if face_encodings is None:
        return None
    # 与已有的特征向量进行比对
    face_distances = np.linalg.norm(known_face_encodings - face_encodings, axis=1)
    best_match_index = np.argmin(face_distances)
    if face_distances[best_match_index] < 0.6:
        return known_face_labels[best_match_index]
    else:
        return None

# 测试程序
if __name__ == '__main__':
    # 添加新的人脸特征向量
    img1 = cv2.imread("person1.jpg")
    face_encodings1 = extract_face_encodings(img1)
    add_face_encodings(face_encodings1[0], "person1")

    # 识别人脸
    img2 = cv2.imread("person2.jpg")
    label = recognize_face(img2)
    print(label)

需要注意的是,由于人脸识别是一项非常复杂的任务,本文中的代码只是一个基本的示例,实际应用中可能需要更多的优化和调试

用python写个人脸识别程序要求每新增一张人脸图片不从新训练

原文地址: https://www.cveoy.top/t/topic/g94o 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录