Python 人脸识别:使用 OpenCV 和 PCA 实现实时人脸检测和识别
import cv2
import os
import numpy as np
from sklearn.decomposition import PCA
def detect_face(img, face_cascade):
gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30), flags=cv2.CASCADE_SCALE_IMAGE)
if len(faces) == 0:
return None
for (x, y, w, h) in faces:
face = gray[y:y + w, x:x + h].astype(np.float32)
face = cv2.resize(face, (150, 150))
return face
def prepare_training_data(data_folder_path):
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_alt.xml')
dirs = os.listdir(data_folder_path)
faces = []
labels = []
for dir_name in dirs:
label = int(dir_name)
subject_dir_path = data_folder_path + '/' + dir_name
subject_images_names = os.listdir(subject_dir_path)
for image_name in subject_images_names:
image_path = subject_dir_path + '/' + image_name
image = cv2.imread(image_path)
if image is None:
continue
gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
rect = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30),flags=cv2.CASCADE_SCALE_IMAGE)
for (x, y, w, h) in rect:
face = gray[y:y + w, x:x + h].astype(np.float32)
face = cv2.resize(face, (150, 150))
if face is not None:
face_vector = np.reshape(face,(1,-1))[0]
faces.append(face_vector)
labels.append(label)
faces= np.array(faces)
labels= np.array(labels)
return faces, labels
def preprocess_image(img, face_cascade, pca):
face = detect_face(img, face_cascade)
if face is not None:
face_pca = pca.transform(face.reshape(1, -1))
img_processed = cv2.cvtColor(face, cv2.COLOR_GRAY2RGB)
return face_pca, img_processed
else:
return None, None
def main():
cap = cv2.VideoCapture(0)
stop = False
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
pca = PCA(n_components=60, svd_solver='full')
faces, labels = prepare_training_data('raw1')
faces = pca.fit_transform(faces)
while not stop:
success, img = cap.read()
face_pca, img_processed = preprocess_image(img, face_cascade, pca)
if face_pca is not None:
subjects = ['xu', 'LU', 'ZHOU']
img1 = img_processed.copy()
faces_cascade = face_cascade.detectMultiScale(img, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30),flags=cv2.CASCADE_SCALE_IMAGE)
if len(faces_cascade) > 0:
(x, y, w, h) = faces_cascade[0]
cv2.rectangle(img1, (x, y), (x + w, y + h), (0, 255, 0), 2)
min_d = 1000000000000
c = -1
for i, f in enumerate(faces):
d = ((face_pca - f) ** 2).sum()
if d < min_d:
min_d = d
c = labels[i]
print(subjects[c])
cv2.imshow('test', img1)
cv2.putText(img1, subjects[c], (x, y), cv2.FONT_HERSHEY_COMPLEX, 1, (128, 128, 0), 2)
c = cv2.waitKey(1)
if c & 0xFF == ord('q'):
stop = True
cv2.destroyAllWindows()
if __name__ == '__main__':
main()
代码功能
- 人脸检测:使用 OpenCV 的
CascadeClassifier检测图像中的人脸。 - 特征提取:使用 PCA 对检测到的人脸进行特征提取,减少维度。
- 人脸识别:将提取的特征与已知人员的特征进行比较,识别出人脸。
- 实时处理:利用 OpenCV 的
VideoCapture读取摄像头图像,实时进行人脸识别。
使用方法
- 确保已安装 OpenCV、NumPy 和 scikit-learn 库。
- 在
prepare_training_data函数中,将data_folder_path设置为训练数据的文件夹路径。 - 在
main函数中,将subjects列表设置为已知人员的姓名。 - 运行代码,即可进行实时人脸识别。
注意
- 训练数据需要包含每个已知人员的多个图像,并根据人员进行分类整理。
- 该代码仅提供了一个基本的示例,实际应用中可能需要根据具体情况进行调整。
- 使用 PCA 进行特征提取时,需要根据实际情况调整
n_components参数。
原文地址: https://www.cveoy.top/t/topic/mJ0A 著作权归作者所有。请勿转载和采集!