You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

81 lines
3.5 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import cv2
from PIL import Image
from insightface.app import FaceAnalysis
import os
# 获取图片中人脸有哪些,返回人脸信息
# ctx_id: 如果有多块GPU那么ctx_id=0表示使用第一块显卡,如果是负数则是使用CPU执行预测
# det_thresh: 配置的是人脸检测的阈值
# det_size: 检测模型图片大小
# det_thresh = 0.50
def get_faces(v_image_path, v_ctx_id, v_det_thresh, v_det_size, v_image_path_flag=None):
try:
app.prepare(ctx_id=v_ctx_id, det_thresh=v_det_thresh, det_size=v_det_size)
img = cv2.imread(v_image_path) # 检测图片中人脸的个数
v_faces = app.get(img)
# 在图片上标识出人脸区域
if v_image_path_flag is not None and len(v_faces) > 0:
rimg = app.draw_on(img, v_faces)
cv2.imwrite(v_image_path_flag, rimg)
return v_faces
except Exception as err:
return None
# 获取面积最大的人脸
def get_first_face(v_faces, output_path):
# 计算每个面部的面积
face_areas = [(face['bbox'][2] - face['bbox'][0]) * (face['bbox'][3] - face['bbox'][1]) for face in v_faces]
# 根据面积降序排序面部
sorted_faces = [face for _, face in sorted(zip(face_areas, v_faces), reverse=True)]
# 输出排序后的面部数组
bbox = sorted_faces[0]['bbox'] # 最大的人脸
# 把一个图片的这个区域截取出来,另存在一个图片文件
img = Image.open(image_path)
# 将图像转换为RGB模式
img_rgb = img.convert('RGB')
# 截取矩形区域
cropped_image = img_rgb.crop(bbox)
# 保存截取的区域到新的图片文件
cropped_image.save(output_path)
# 关闭图像
cropped_image.close()
# 关闭图像
img_rgb.close()
if __name__ == '__main__':
# 声明 FaceAnalysis
app = FaceAnalysis(allowed_modules=['detection'], providers=['CUDAExecutionProvider', 'CPUExecutionProvider'],
download=False)
# 遍历目录下所有文件
directory = r'C:\Users\Administrator\Desktop\Upload'
# 对于多个人脸,打标记框
flag_directory = r'C:\Users\Administrator\Desktop\Flag'
# 第一个人脸
first_directory = r'C:\Users\Administrator\Desktop\FirstFace'
# 不存在就创建
if not os.path.exists(flag_directory):
os.makedirs(flag_directory)
if not os.path.exists(first_directory):
os.makedirs(first_directory)
with os.scandir(directory) as entries: # 使用os.scandir()获取目录条目
for entry in entries:
if entry.is_file(): # 检查是否是文件
image_path = os.path.join(directory, entry.name)
# 打标记框的图片
v_image_path_flag = os.path.join(flag_directory, entry.name)
# 第一个人脸图片
v_first_face_path = os.path.join(first_directory, entry.name)
# 获取人脸信息
faces = get_faces(v_image_path=image_path, v_ctx_id=0, v_det_thresh=0.2, v_det_size=(640, 640),
v_image_path_flag=v_image_path_flag)
if faces is not None and len(faces) > 0:
# 获取第一个人脸图片,只截取第一个人脸的方法是不可以的
get_first_face(faces, output_path=v_first_face_path)
else:
print("文件名称" + entry.name + ",人脸数量:" + str(len(faces)))