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)))