【Dlib人脸特征提取】1. 训练人脸特征点模型

【 1. 数据集 】

前面使用的Dlib中提供的68点特征检测模型,使用的数据集来自300-W(300 Faces In-The-Wild Challenge)。300-W是一项专注于人脸特征点的检测的竞赛,通常与ICCV这类著名的计算机视觉活动相伴举行。在该竞赛中,参赛队伍需要从600张图片中检测出人脸,并且将面部的68个特征点全部标记出来。
在这里插入图片描述
300W数据的压缩包有2G多。包含各种各样已经标记好的人脸信息。
因为在如此大的数据集上训练需要大量的资源和时间。所以,在本次实训的学习中,我们使用极少量的数据集来训练。数据虽少,但流程健全。
使用到的图片数据集如下:
在这里插入图片描述

【 2. 训练集 】

我们使用4张图片作为训练集数据。其中人脸相关的标注数据,存放于XML文件中,格式如下:

<?xml version='1.0' encoding='ISO-8859-1'?>
<?xml-stylesheet type='text/xsl' href='image_metadata_stylesheet.xsl'?>
<dataset>
<name>Training faces</name>
<comment>These are images from the PASCAL VOC 2011 dataset.
 The face landmarks are from dlib's shape_predictor_68_face_landmarks.dat landmarking model.  The model uses the 68 landmark scheme used by the iBUG 300-W dataset.
</comment>
<images>
  <image file='2007_007763.jpg'>
    <box top='90' left='194' width='37' height='37'>
      <part name='00' x='201' y='107'/>
      <part name='01' x='201' y='110'/>
      <part name='02' x='201' y='113'/>
      ......
      <part name='67' x='209' y='121'/>
    </box>
    </image>
    ......
</images>

其中:

  • image file代表图像文件名;
  • box中 top、left、width和height 指定了人脸区域,一张图中可能包含多个人脸,所以可能有多个Box;
  • part 即为对应人脸特征点,每张图有68个标记点。

【 3. 测试集 】

我们使用5张图片作为测试集数据。同样的,其中人脸相关的标注数据,存放于XML文件中。其格式与训练集文件格式相同。

【 4. 训练模型 】

在准备好训练集和测试集之后,就可以开始使用Dlib进行训练了。

1. 定义参数

人脸检测模型中包含大量可以设置的参数,所以我们首先定义参数设置函数:

options = dlib.shape_predictor_training_options()

大部分参数,在此我们使用默认值,针对我们的训练集,我们主要设定如下几个参数。

  • Oversampling_amount: 通过对训练样本进行随机变形扩大样本数目
    比如原本有N张训练图片,通过设置该参数,训练样本数将变成N * oversampling_amount张。所以一般而言,值越大越好,只是训练耗时也会越久。
    因为本例中训练集数据较少,所以我们将值设得较高(300):
  options.oversampling_amount = 300
  • nu: 正则项
    nu越大,表示对训练样本fit越好。

  • tree depth: 树深
    本例中通过增加正则化(将nu调小)和使用更小深度的树来降低模型的容量:

  options.nu = 0.05
  options.tree_depth = 2
  • be_verbose,是否输出训练的过程中的相关训练信息
    设置为真:
  options.be_verbose = True

2. 生成模型

使用dlib.train_shape_predictor进行训练,示例如下:

dlib.train_shape_predictor(training_xml_path, "predictor.dat", options)

#	training_xml_path是训练数据标记文件路径
#	options是我们前一步设置的值,将最后的检测器输出为 predictor.dat文件。

3. 测试模型

最后,我们调用test_shape_predictor进行模型测试:

dlib.test_shape_predictor(testing_xml_path, "predictor.dat")

#	表示,读取predictor.dat和testing_xml_path测试数据文件进行模型测试。

完整的训练代码如下:

import os
import sys
import dlib
# 数据集路径
faces_folder = 'step3/data'
# 1. 定义模型训练需要的参数
options = dlib.shape_predictor_training_options()
# 2.参数设定 
# 通过对训练样本进行随机变形扩大样本数目
options.oversampling_amount = 300
# 通过增加正则化(将nu调小)和使用更小深度的树来降低模型的容量
options.nu = 0.05
options.tree_depth = 2
options.be_verbose = True
# 3. 调用训练模型函数
# 训练集路径
training_xml_path = os.path.join(faces_folder, "training_with_face_landmarks.xml")
dlib.train_shape_predictor(training_xml_path, "predictor.dat", options)
# 训练集的准确度
print("\nTraining accu\fracy: {}".format(
    dlib.test_shape_predictor(training_xml_path, "predictor.dat")))
# 4. 调用测试模型函数,测试训练完成的模型
# 测试集路径
testing_xml_path = os.path.join(faces_folder, "testing_with_face_landmarks.xml")
# 测试集的准确度
print("Testing accu\fracy: {}".format(
    dlib.test_shape_predictor(testing_xml_path, "predictor.dat")))

运行训练程序,输出如下:

Training with cascade depth: 10
Training with tree depth: 2
Training with 500 trees per cascade level.
Training with nu: 0.05
Training with random seed:
Training with oversampling amount: 300
Training with oversampling translation jitter: 0
Training with landmark_relative_padding_mode: 1
Training with feature pool size: 400
Training with feature pool region padding: 0
Training with 0 threads.
Training with lambda_param: 0.1
Training with 20 split tests.
Fitting trees...
Training complete
Training complete, saved predictor to file predictor.dat
Training accu\fracy: 0.0032679738562091504
Testing accu\fracy: 1.750984517526159

4. 使用模型

# 人脸区域检测器
detector = dlib.get_frontal_face_detector()
# 从本地导入人脸特征点检测器
predictor = dlib.shape_predictor("predictor.dat")
# 检测人脸以及人脸特征点
faces_folder = 'step3/dataSet'
for f in glob.glob(os.path.join(faces_folder, "*.jpg")):
    print("处理文件: {}".format(f))
    # 加载图片
    img = dlib.load_rgb_image(f)
    # 检测图片
    dets = detector(img, 1)
    print("检测到的人脸个数为: {}".format(len(dets)))
    # 遍历图片中识别出的每一个人脸
    for k, d in enumerate(dets):
        # 打印人脸区域位置
        print("Detection {}: Left: {} Top: {} Right: {} Bottom: {}".format(
            k, d.left(), d.top(), d.right(), d.bottom()))
        # 获取每一个人脸区域内的特征点
        shape = predictor(img, d)
        # 打印第1个和第68个特征点
        print("Part 1: {}, Part 1: {} ...".format(shape.part(0), shape.part(67)))

运行的部分结果如下:

处理文件: ../examples/faces/2008_001322.jpg
检测到的人脸个数为: 3
Detection 0: Left: 232 Top: 218 Right: 294 Bottom: 2811个点: (234, 235),68: (255, 267) ...
Detection 1: Left: 104 Top: 163 Right: 179 Bottom: 2371个点: (106, 183),68: (135, 219) ...
Detection 2: Left: 344 Top: 156 Right: 434 Bottom: 2451个点: (357, 199),68: (395, 227) ...

原图:
在这里插入图片描述
使用刚训练的模型,绘制人脸区域和特征点之后的图片效果如下:
在这里插入图片描述

  • 7
    点赞
  • 71
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MR_Promethus

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值