用python写个人脸识别程序要求每新增一张人脸图片不从新训练
由于人脸识别涉及到深度学习和计算机视觉等领域,实现一个完整的人脸识别程序需要用到各种库和框架,比如OpenCV、Dlib、TensorFlow等。在此,我将以Dlib和OpenCV为例,简要介绍如何用Python实现一个基于人脸识别的程序,并且在新增人脸图片时不需要重新训练模型。
- 安装必要的库和框架
首先需要安装Dlib和OpenCV,可以使用pip命令进行安装:
pip install dlib
pip install opencv-python
- 加载人脸检测器和人脸识别器模型
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") # 人脸识别器
- 加载已有的人脸特征向量
为了避免每次新增人脸图片时都需要重新训练模型,可以将已有的人脸特征向量保存到本地文件中,并在需要时进行加载。可以使用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)
- 提取人脸特征向量
当新增一张人脸图片时,需要首先检测出人脸,并提取人脸特征向量。可以使用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为提取出的人脸特征向量。
- 添加新的人脸特征向量
当提取出人脸特征向量后,将其添加到已有的特征向量中。
# 添加新的人脸特征向量
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为对应的人脸标签。
- 识别人脸
当需要识别一张人脸图片时,首先需要提取出其特征向量,然后与已有的特征向量进行比对,找到最相似的人脸标签。
# 识别人脸
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)
需要注意的是,由于人脸识别是一项非常复杂的任务,本文中的代码只是一个基本的示例,实际应用中可能需要更多的优化和调试
原文地址: https://www.cveoy.top/t/topic/g94o 著作权归作者所有。请勿转载和采集!