概述
因为我的项目中缺一不可的一部分是提取人脸特征,因为以前并没有接触过人脸的项目,所以想把自己每次的一点点进步和学习都记录下来,这次是记录我学习切割人脸图片并保存,以及将人脸检测框和五个特征点坐标信息保存在.txt
文件中。
这篇文档的方法一要稍微复杂一点点,我结合Retinaface_pytorch项目中的detect.py(检测单张图片)来检测人脸,并通过以下方法一成功的剪切出人脸,并保存特征点信息。方法二要更简单一些,相当于我用一行代码代替了方法二中的多行代码,并实现了批量检测并切割人脸图片并保存。
- 首先附上Retinaface_pytorch项目的GitHub链接:
https://github.com/biubug6/Pytorch_Retinaface
一. 复现Retinaface_pytorch
根据Retina_pytorch项目在GitHub上给出的教程来复现Retinaface_pytorch项目的预训练模型。跑通项目中的detect.py
,改变程序中的图片路径你可以试一下检测自己的单张照片。确保detect.py
可以正常检测人脸。
- 运行效果图:
二.剪切人脸图(方法一)
1. 方法简述
参考:Python 3 利用 Dlib 实现人脸检测和剪切
这一篇博客介绍了利用 Python 开发,借助 Dlib 库进行人脸检测 / face detection 和剪切。里面既讲了将检测到的人脸剪切下来,依次排序平铺显示在新的图像上,也讲了将检测到的人脸存储为单个人脸图像,讲的很清晰明了。主要的大概思路就是根据检测到的人脸框坐标,计算人脸框的大小,根据这个人脸框大小生成空白的图片,接着再将人脸的图的像素点依次填充在空白图上,完成人脸的剪切。
-
将检测到的人脸剪切下来,依次排序平铺显示在新的图像上(效果图)
-
将检测到的人脸存储为单个人脸图像(效果图)
- Retinaface_pytorch的detect.py检测单张图片中的人脸+剪切单个人脸图
#调用相关模块和包
from __future__ import print_function
import os
import argparse
import torch
import torch.backends.cudnn as cudnn
import numpy as np
from data import cfg_mnet, cfg_re50
from layers.functions.prior_box import PriorBox
from utils.nms.py_cpu_nms import py_cpu_nms
import cv2
from models.retinaface import RetinaFace
from utils.box_utils import decode, decode_landm
import time
parser = argparse.ArgumentParser(description='Retinaface')
#设置供选择的参数(基本上保持Retinaface_pytorch中detect.py的代码不变添加或改动了几个参数使得该项目默认在CPU上运行)
parser.add_argument('-m', '--trained_model', default='./weights/Resnet50_Final.pth',
type=str, help='Trained state_dict file path to open')
parser.add_argument('--network', default='resnet50', help='Backbone network mobile0.25 or resnet50')
parser.add_argument('--cpu', action="store_true", default=True, help='Use cpu inference')
parser.add_argument('--confidence_threshold', default=0.02, type=float, help='confidence_threshold')
parser.add_argument('--top_k', default=5000, type=int, help='top_k')
parser.add_argument('--nms_threshold', default=0.4, type=float, help='nms_threshold')
parser.add_argument('--keep_top_k', default=750, type=int, help='keep_top_k')
parser.add_argument('-s', '--show_image', action="store_true", default=False, help='show detection results')
parser.add_argument('--vis_thres', default=0.6, type=float, help='visualization_threshold')
parser.add_argument('--show_cutting_image', action ="store_true", default =True, help = 'show_crop_images')
parser.add_argument('--save_folder', default='curve/', type=str, help='Dir to save results')
args = parser.parse_args()
#保持源代码不变
def check_keys(model, pretrained_state_dict):
ckpt_keys = set(pretrained_state_dict.keys())
model_keys = set(model.state_dict().keys())
used_pretrained_keys = model_keys & ckpt_keys
unused_pretrained_keys = ckpt_keys - model_keys
missing_keys = model_keys - ckpt_keys
print('Missing keys:{}'.format(len(missing_keys)))
print('Unused checkpoint keys:{}'.format(len(unused_pretrained_keys))