【Dlib人脸特征提取】1. 训练人脸特征点模型_人脸特征点模型训练方法_MR_Promethus的博客-程序员秘密

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

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

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_44431690/article/details/106586722

智能推荐

JavaIO怎么调用WindowsAPI的——从Native层剖析JavaIO文件读写_Holmofy的博客-程序员秘密

上一篇文章中列举了JavaIO中FileDescriptor和File类提供的一些文件操作,这些操作还只是对文件系统中的文件进行创建或删除操作。鉴于大一玩过Window编程(对Linux API不是很熟悉),所以这篇文章会从Windows C API去分析一下Java提供给我们的几个文件读写类。 建议结合着源代码看这篇文章(这篇文章就是记录我看源代码的过程,这里的java版本是1.8.0_...

使用PHP环境一键安装包快速搭建PHP开发环境_真无名的博客-程序员秘密

在Windows系统下如何搭建PHP开发环境?为了快速进入编程状态,顺利地完成第一个PHP程序,我们选择使用PHP集成环境包。什么是PHP集成环境包?类似的软件又有哪些呢?要回答这个问题,我们需要知道开发PHP程序需要怎么样的开发环境。PHP开发环境有哪些?PHP开发环境大致分为两大阵营,一类是在Linux系统下,Linux系统大家可能比较陌生,不过没关系,因为这个后面我们会介...

mybatis配置mybatis-config.xml的时候提示mybatis-3-config.dtd找不到_chujianbi7142的博客-程序员秘密

解决方法: 鼠标点击红色字,然后Intellij出现小红灯,选择Fetch external resource即可解决 转载于:https://my.oschina.net/u/...

【软件架构】运用RUP 4+1视图软件架构设计(逻辑视图、实现视图、进程视图、物理视图和用例视图)_bandaoyu的博客-程序员秘密

RUP概述RUP(Rational Unified Process),统一软件开发过程,统一软件过程是一个面向对象且基于网络的程序开发方法论。在RUP中采用“4+1”视图模型来描述软件系统的体系结构。“4+1”视图包括逻辑视图、实现视图、进程视图、部署视图和用例视图。最终用户关心的是系统的功能,因此会侧重于逻辑视图;程序员关心的是系统的配置、装配等问题,因此会侧重于实现(开发)视...

SpringBoot配置文件全部属性汇总_大白给小白讲故事的博客-程序员秘密

来源:https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html#================================================= ==================#COMMON SPRING BOOT PROPERT...

oracle--plsql1---基础概念_plsql 属于那家公司产品_huyishero的博客-程序员秘密

pl/sql基本特征1.过程、函数、触发器是pl/sql编写的2.过程、函数、触发器是存在oracle中的3.plsql是过程语言4.过程、函数可以在java程序中调用它的优缺点分别是:优点1.提高应用程序的运行性能2.模块化的设计思想(分页的过程,订单的过程,转账的过程)3.减少网络传输量4.提高安全性缺点1.移植性不好plsql是

随便推点

sitemap网站地图提交工具1.0_一叶知秋网络的博客-程序员秘密

该软件可以挂机每天准点推送xml里面的url到各大平台,可第一时间告知爬虫网站最新内容。适合新站、每日更新内容频繁的站长。 填写xml远程地址并测试一下, 填写和对应各大搜索平台api推送接口。 目前支持百度、必应、神马api提交 定时提交,自动获取远程sitemap.xml文件内的url 只需简单添加任务,即可每天定时提交 -------------------------------------------------------各大平台api地

关于Haar分类器的加载错误问题_wackelbh的博客-程序员秘密

把人脸检测系统完成之后就开始准备测试程序,让它能够在其它机器上运行。在把haarcascade_frontalface_alt.xml拷贝到我的项目目录(含有代码的那个目录)里面之后,修改了我的程序中的分类器加载路径。刚开始一直使用相对路径“.//haarcascade_frontalface_alt.xml”(程序运行的时候默认程序路径是定位到项目目录那个路径的,而不是程序所在的release

C语言 线程 进程 优先级,C++线程优先级SetThreadPriority的使用实例_美业云营销的博客-程序员秘密

本文实例讲述了C++线程优先级SetThreadPriority的使用方法,分享给大家供大家参考。具体方法如下:// ThreadPriority.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include DWORD WINAPI ThreadProcIdle(LPVOID lpParameter){for (int i=0;i&lt;20;i++){pr...

poj 2528 线段树成段更新+离散化_Lawrence_Jang的博客-程序员秘密

#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#define iinf 2000000000#define linf 1000000000000000000LL#defin

Bootstrap多级下拉菜单_bootstrap 多级下拉菜单_小宋想站起来的博客-程序员秘密

首先需要将数据组装成树状数据,就这个样子的数据组装数据的函数如下: //组装数据 pId为父节点的id function rec(data,id){ var arr = []; for (var i = 0; i &lt; data.length; i++) { //如果是当前节点子节点 if(data[i].pId == id){ //深度遍历 ...

JSP内置对象session和request中setAttribute方法_leftforward的博客-程序员秘密

setAttribute这个方法,在JSP内置对象session和request都有这个方法,这个方法作用就是保存数据,然后还可以用getAttribute方法来取出。比如现在又个User对象,User curruser = new User("zhangsan", 20, "男");1,request.setAttribute(“curruser”, curruser)这个方法是将curru

推荐文章

热门文章

相关标签