import imghdr
import face_recognition
import os
import cv2
import numpy as np
import matplotlib.pyplot as plt
def save_faces_from_folder(folder_path, output_folder):
# 确保输出文件夹存在
if not os.path.exists(output_folder):
os.makedirs(output_folder)
# 遍历文件夹内的所有图片文件
for path in os.listdir(folder_path):
for filename in os.listdir(os.path.join(folder_path,path)):
if filename.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp', '.gif')):
file_path = os.path.join(folder_path,path, filename)
print(f"Processing {file_path}")
# 加载图片
image = face_recognition.load_image_file(file_path)
# 检测图片中的人脸
face_locations = face_recognition.face_locations(image)
out_path = os.path.join(output_folder,path)
if not os.path.exists(out_path):
os.makedirs(out_path)
# 遍历检测到的人脸
for face_location in face_locations:
top, right, bottom, left = face_location
# 截取人脸部分
face_image =cv2.resize(image[top:bottom, left:right],(200,200))
# 保存截取后的人脸图片
# 这里我们使用原始文件名加上人脸的索引(如果有多个)作为新文件名
face_filename = f"{os.path.splitext(filename)[0]}_face_{face_locations.index(face_location)}.jpg"
face_file_path = os.path.join(out_path,face_filename)
# 使用OpenCV保存图片(因为face_recognition加载的图片不能直接保存)
cv2.imwrite(face_file_path, cv2.cvtColor(face_image, cv2.COLOR_RGB2BGR))
# 调用函数
folder_path = './faces' # 替换为你的图片文件夹路径
output_folder = './outputs' # 替换为你想要保存截取后人脸的文件夹路径
save_faces_from_folder(folder_path, output_folder)
def get_label(path):
fh = open("label.txt","w")
label = 0
for root ,dirs,file in os.walk(path):
for subdir in dirs:
subdir_path = os.path.join(root,subdir)
for file in os.listdir(subdir_path):
file_path = os.path.join(subdir_path,file)
imgType = imghdr.what(file_path)
if imgType == "jpeg" :
fh.write(file_path)
fh.write(":")
fh.write(str(label))
fh.write("\n")
label +=1
fh.close()
get_label(output_folder)
images = []
labels = []
fh = open("label.txt")
for line in fh :
arr = line.split(":")
img = cv2.imread(arr[0],0)
images.append(img)
labels.append(int(arr[1]))
try:
model = cv2.face.LBPHFaceRecognizer_create()
model.train(np.array(images),np.array(labels))
model.save("predict_face_xiaoming_ab.xml")
except cv2.error as e:
print(e)
def show(image):
plt.imshow(image)
plt.axis("off")
plt.show()
name = ["angel","xiaoming"]
model =cv2.face.LBPHFaceRecognizer_create()
model.read("predict_face_xiaoming_ab.xml")
for file in os.listdir("test"):
file = os.path.join('test',file)
imgType = imghdr.what(file)
if imgType == "jpeg" :
image =cv2.imread(file)
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
#级联分类器
detetor = cv2.CascadeClassifier("haarcascade_frontalface_alt.xml")
rects =detetor.detectMultiScale(gray,scaleFactor=1.1,minNeighbors=3,minSize=(20,20),flags=cv2.CASCADE_SCALE_IMAGE)
for (x,y,w,h) in rects:
cv2.rectangle(image,(x,y),(x+w,y+h),(0,255,0),2)
face = cv2.resize(gray[y:y+h,x:x+w],(200,200))
params = model.predict(face)
cv2.putText(image,name[params[0]],(x,y-20),cv2.FONT_HERSHEY_SIMPLEX,1,(255,0,0),2)
show(image)
说明:
使用方法:
准备数据集如下:
1、创建faces文件,文件内创建xiaoming,angel文件夹,xiaoming和angel文件夹内从百度下载黄晓明和杨颖的图片,格式为jpg
2、创建test文件夹,文件夹内下载黄晓明和杨颖的合照
注意事项:
1、训练与读取的要相同,
model = cv2.face.LBPHFaceRecognizer_create() model.train(np.array(images),np.array(labels)) model.save("predict_face_xiaoming_ab.xml")
model =cv2.face.LBPHFaceRecognizer_create() model.read("predict_face_xiaoming_ab.xml")
2、LBPHFaceRecognizer_create()要用这个方法,cv2.face可能没有这个方法,但是直接用就好
3、下面两个依赖包需要安装相同的版本
pip install opencv-contrib-python==4.9.0.80
pip install opencv-python==4.9.0.80
4、haarcascade_frontalface_alt.xml下载地址
5、name = ["angel","xiaoming"]下标要与label.txt文件后缀一致