1. 人脸关键点检测介绍
人脸关键点检测是检测人脸上的一些特征,通常检测点的数量为5,68,98点。 其流程为:输入一张图片->网络模型->关键点。 此博客以68点为例实现人脸关键点检测。 如图:
实现步骤:
- 获得到人脸图片以及其关键点坐标,也就是数据集。
- 数据处理
- 构建网络模型
- 训练模型
- 预测图片
2. 数据集
链接:https://pan.baidu.com/s/14W6OIU3h3FVwSEoEmlx8xA 提取码:bj9n 或者登录:https://aistudio.baidu.com/aistudio/datasetdetail/69065
3. 数据预处理
灰度化和数据归一化 由于是对人脸的特征点进行预测,对颜色是不敏感的,所以我们可以把图片进行灰度化处理,然后对图片进行归一化,再将将坐标点放缩到 [-1, 1]加快模型训练速度。 Resize和RandomCrop 将图片调整为指定大小并随机位置裁剪输入的图像,也就是数据增强。
4. 构建网络模型
我们使用mobilenetv2作为主干网络进行特征提取,只需在网络模型后面增加一层ReLU函数和一层输出为68的点的线性层即可。
import paddle
import paddle.nn as nn
from paddle.vision.models import mobilenet_v1, mobilenet_v2, resnet50
class FaceKeyPointsNetBody(nn.Layer):
def __init__(self, kpt_num=68, backbone='mobilenetv1'):
if backbone not in ['mobilenetv1', 'mobilenetv2', 'resnet50']: assert "Backbone definition error"
super(FaceKeyPointsNetBody, self).__init__()
if backbone == 'mobilenetv1':
self.backbone = mobilenet_v1(pretrained=True, scale=1.0)
elif backbone == 'mobilenetv2':
self.backbone = mobilenet_v2(pretrained=True, scale=1.0)
else:
self.backbone = resnet50(pretrained=True)
self.linear1 = nn.Linear(1000, out_features=512)
self.act1 = nn.ReLU()
self.linear2 = nn.Linear(512, kpt_num*2)
def forward(self, x):
x = self.backbone(x)
x = self.linear1(x)
x = self.act1(x)
x = self.linear2(x)
return x
5. 训练模型
评估指标
人脸关键点一般是NMS作为评估指标,即所有预测点和真实标签之间的L2 Norm,在除以关键点的个数x两只眼睛的距离。
????????????
e
=
∑
i
=
1
N
∣
∣
x
i
?
x
i
?
∣
∣
2
N
×
d
e=\frac{\sum^N_{i=1}||x_i - x^*_i||_2}{N \times d}
e=N×d∑i=1N?∣∣xi??xi??∣∣2??
其中:
x
i
x_i
xi?为预测第
i
i
i个的坐标。
x
i
?
x^*_i
xi??为第
i
i
i个真实标签。
d
d
d为距离,两眼瞳孔距离或者两眼外眼角距离。
损失函数
使用SmoothL1Loss。 SmoothL1Loss对于离群点更加鲁棒,回归更好。
6. 预测图片
效果如下:
7. 代码仓库
gitee地址:https://gitee.com/Hao_gg/facekeypoints-pp github地址:https://github.com/hao-ux/facepoints-pp
|