前面使用的Dlib中提供的68点特征检测模型,使用的数据集来自300-W(300 Faces In-The-Wild Challenge)。300-W是一项专注于人脸特征点的检测的竞赛,通常与ICCV这类著名的计算机视觉活动相伴举行。在该竞赛中,参赛队伍需要从600张图片中检测出人脸,并且将面部的68个特征点全部标记出来。
300W数据的压缩包有2G多。包含各种各样已经标记好的人脸信息。
因为在如此大的数据集上训练需要大量的资源和时间。所以,在本次实训的学习中,我们使用极少量的数据集来训练。数据虽少,但流程健全。
使用到的图片数据集如下:
我们使用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>
其中:
我们使用5张图片作为测试集数据。同样的,其中人脸相关的标注数据,存放于XML文件中。其格式与训练集文件格式相同。
在准备好训练集和测试集之后,就可以开始使用Dlib进行训练了。
人脸检测模型中包含大量可以设置的参数,所以我们首先定义参数设置函数:
options = dlib.shape_predictor_training_options()
大部分参数,在此我们使用默认值,针对我们的训练集,我们主要设定如下几个参数。
options.oversampling_amount = 300
nu: 正则项
nu越大,表示对训练样本fit越好。
tree depth: 树深
本例中通过增加正则化(将nu调小)和使用更小深度的树来降低模型的容量:
options.nu = 0.05
options.tree_depth = 2
options.be_verbose = True
使用dlib.train_shape_predictor进行训练,示例如下:
dlib.train_shape_predictor(training_xml_path, "predictor.dat", options)
# training_xml_path是训练数据标记文件路径
# options是我们前一步设置的值,将最后的检测器输出为 predictor.dat文件。
最后,我们调用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
# 人脸区域检测器
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: 281
第1个点: (234, 235), 第68个: (255, 267) ...
Detection 1: Left: 104 Top: 163 Right: 179 Bottom: 237
第1个点: (106, 183), 第68个: (135, 219) ...
Detection 2: Left: 344 Top: 156 Right: 434 Bottom: 245
第1个点: (357, 199), 第68个: (395, 227) ...
原图:
使用刚训练的模型,绘制人脸区域和特征点之后的图片效果如下:
上一篇文章中列举了JavaIO中FileDescriptor和File类提供的一些文件操作,这些操作还只是对文件系统中的文件进行创建或删除操作。鉴于大一玩过Window编程(对Linux API不是很熟悉),所以这篇文章会从Windows C API去分析一下Java提供给我们的几个文件读写类。 建议结合着源代码看这篇文章(这篇文章就是记录我看源代码的过程,这里的java版本是1.8.0_...
在Windows系统下如何搭建PHP开发环境?为了快速进入编程状态,顺利地完成第一个PHP程序,我们选择使用PHP集成环境包。什么是PHP集成环境包?类似的软件又有哪些呢?要回答这个问题,我们需要知道开发PHP程序需要怎么样的开发环境。PHP开发环境有哪些?PHP开发环境大致分为两大阵营,一类是在Linux系统下,Linux系统大家可能比较陌生,不过没关系,因为这个后面我们会介...
解决方法: 鼠标点击红色字,然后Intellij出现小红灯,选择Fetch external resource即可解决 转载于:https://my.oschina.net/u/...
RUP概述RUP(Rational Unified Process),统一软件开发过程,统一软件过程是一个面向对象且基于网络的程序开发方法论。在RUP中采用“4+1”视图模型来描述软件系统的体系结构。“4+1”视图包括逻辑视图、实现视图、进程视图、部署视图和用例视图。最终用户关心的是系统的功能,因此会侧重于逻辑视图;程序员关心的是系统的配置、装配等问题,因此会侧重于实现(开发)视...
来源:https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html#================================================= ==================#COMMON SPRING BOOT PROPERT...
pl/sql基本特征1.过程、函数、触发器是pl/sql编写的2.过程、函数、触发器是存在oracle中的3.plsql是过程语言4.过程、函数可以在java程序中调用它的优缺点分别是:优点1.提高应用程序的运行性能2.模块化的设计思想(分页的过程,订单的过程,转账的过程)3.减少网络传输量4.提高安全性缺点1.移植性不好plsql是
该软件可以挂机每天准点推送xml里面的url到各大平台,可第一时间告知爬虫网站最新内容。适合新站、每日更新内容频繁的站长。 填写xml远程地址并测试一下, 填写和对应各大搜索平台api推送接口。 目前支持百度、必应、神马api提交 定时提交,自动获取远程sitemap.xml文件内的url 只需简单添加任务,即可每天定时提交 -------------------------------------------------------各大平台api地
把人脸检测系统完成之后就开始准备测试程序,让它能够在其它机器上运行。在把haarcascade_frontalface_alt.xml拷贝到我的项目目录(含有代码的那个目录)里面之后,修改了我的程序中的分类器加载路径。刚开始一直使用相对路径“.//haarcascade_frontalface_alt.xml”(程序运行的时候默认程序路径是定位到项目目录那个路径的,而不是程序所在的release
本文实例讲述了C++线程优先级SetThreadPriority的使用方法,分享给大家供大家参考。具体方法如下:// ThreadPriority.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include DWORD WINAPI ThreadProcIdle(LPVOID lpParameter){for (int i=0;i<20;i++){pr...
#include#include#include#include#include#include#include#include#include#include#include#include#include#include#include#define iinf 2000000000#define linf 1000000000000000000LL#defin
首先需要将数据组装成树状数据,就这个样子的数据组装数据的函数如下: //组装数据 pId为父节点的id function rec(data,id){ var arr = []; for (var i = 0; i < data.length; i++) { //如果是当前节点子节点 if(data[i].pId == id){ //深度遍历 ...
setAttribute这个方法,在JSP内置对象session和request都有这个方法,这个方法作用就是保存数据,然后还可以用getAttribute方法来取出。比如现在又个User对象,User curruser = new User("zhangsan", 20, "男");1,request.setAttribute(“curruser”, curruser)这个方法是将curru