dlib人脸关键点检测器训练(194关键点)

转自:https://blog.csdn.net/longji/article/details/77984753

 版权声明:技术分享,csdn longji https://blog.csdn.net/longji/article/details/77984753

01 dlib人脸检测器原始数据获取

68个关键点的训练数据集(1.7GB):http://dlib.net/files/data/ibug_300W_large_face_landmark_dataset.tar.gz 
194个关键点的数据集(需要翻墙):http://stackoverflow.com/questions/36711905/dlib-train-shape-predictor-ex-cpp?answertab=votes#tab-top

02 训练代码

dlib中examples中的代码。 
dlib/examples/train_shape_predictor_ex.cpp

// dlib/examples/train_shape_predictor_ex.cpp
#include <dlib/image_processing.h>
#include <dlib/data_io.h>
#include <iostream>

using namespace dlib;
using namespace std;

std::vector<std::vector<double> > get_interocular_distances (
    const std::vector<std::vector<full_object_detection> >& objects
);

int main(int argc, char** argv)
{
    try
    {
        if (argc != 2)
        {
            cout << "Give the path to the examples/faces directory as the argument to this" << endl;
            cout << "program.  For example, if you are in the examples folder then execute " << endl;
            cout << "this program by running: " << endl;
            cout << "   ./train_shape_predictor_ex faces" << endl;
            cout << endl;
            return 0;
        }
        const std::string faces_directory = argv[1];
        dlib::array<array2d<unsigned char> > images_train, images_test;
        std::vector<std::vector<full_object_detection> > faces_train, faces_test;
        // 1. 载入训练集,测试集
        // load_image_dataset(images_train, faces_train, faces_directory+"/training_with_face_landmarks.xml");
        // load_image_dataset(images_test, faces_test, faces_directory+"/testing_with_face_landmarks.xml");
        // 68个点的训练数据集:http://dlib.net/files/data/ibug_300W_large_face_landmark_dataset.tar.gz
        load_image_dataset(images_train, faces_train, faces_directory + "/labels_ibug_300W_train.xml");
        load_image_dataset(images_test, faces_test, faces_directory + "/labels_ibug_300W_test.xml");

        shape_predictor_trainer trainer;

        // 测试中调节了 tree_depth参数:2,4, 5, 10
        // 测试机器为8核,set_num_threads使用8,训练时cpu:70%
        trainer.set_oversampling_amount(300);
        trainer.set_nu(0.05);
        trainer.set_tree_depth(5);
        trainer.set_num_threads(8);
        trainer.be_verbose();
        // 训练
        shape_predictor sp = trainer.train(images_train, faces_train);

        cout << "mean training error: "<< 
            test_shape_predictor(sp, images_train, faces_train, get_interocular_distances(faces_train)) << endl;

        cout << "mean testing error:  "<< 
            test_shape_predictor(sp, images_test, faces_test, get_interocular_distances(faces_test)) << endl;
        // 保存模型
        serialize("sp.dat") << sp;
        std::string str;
        std::cin >> str;
    }
    catch (exception& e)
    {
        cout << "\nexception thrown!" << endl;
        cout << e.what() << endl;
    }
}

double interocular_distance (
    const full_object_detection& det
)
{
    dlib::vector<double,2> l, r;
    double cnt = 0;

    for (unsigned long i = 36; i <= 41; ++i) 
    {
        l += det.part(i);
        ++cnt;
    }
    l /= cnt;

    cnt = 0;
    for (unsigned long i = 42; i <= 47; ++i) 
    {
        r += det.part(i);
        ++cnt;
    }
    r /= cnt;

    return length(l-r);
}

std::vector<std::vector<double> > get_interocular_distances (
    const std::vector<std::vector<full_object_detection> >& objects
)
{
    std::vector<std::vector<double> > temp(objects.size());
    for (unsigned long i = 0; i < objects.size(); ++i)
    {
        for (unsigned long j = 0; j < objects[i].size(); ++j)
        {
            temp[i].push_back(interocular_distance(objects[i][j]));
        }
    }
    return temp;
}

03 训练结果

194关键点训练情况: 
tree_depth=2,num_threads=2, 
Release版本训练时间 5+小时 
Debug版本训练时间 148+小时(训练一定要使用Release版本) 
tree_depth=2,sp.dat=44.6MB,占用内存最大11GB 
tree_depth=10,sp.data=11GB

68关键点训练结果: 
tree_depth=2,num_threads=8,CPU:70% 内存:20+GB 6+小时 sp.data=15.8MB 
tree_depth=4,num_threads=8,CPU:70% 内存:20+GB 12+小时 sp.data=63.3MB 
tree_depth=5,num_threads=8,CPU:70% 内存:20+GB 16+小时 sp.data=126MB

tree_depth=5,num_threads=8
mean training error: 0.0479476
mean testing error:  0.0586204

04 测试效果

使用dlib中examples中的代码测试。 
dlib/examples/face_landmark_detection_ex.cpp 
也可食用dlib提供的训练模型: 
http://dlib.net/files/shape_predictor_68_face_landmarks.dat.bz2

原图: 
原图 
检测效果图: 
检测效果图

05 参考

http://blog.csdn.net/jcx1314/article/details/65937839 
http://blog.csdn.net/elaine_bao/article/details/53054533

  • 1
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
dlib是一个C++开源库,主要用于机学习和计算机视觉任务。其中,dlib中的人脸检测模块可以在图像或视频中识别出人脸,而人脸关键点检测功能可以在人脸上定位出一些重要的特征点,例如眼睛、鼻子、嘴巴等,以便进行更深入的人脸分析和处理。 dlib人脸关键点检测的原理基于基于人脸形状模型(Face Shape Model)和级联回归分类(Cascade Regression Classifier)。 首先,dlib人脸检测模块使用级联分类从图像或视频中识别出人脸。然后,对于每个检测到的人脸dlib使用形状模型来定位人脸上的关键点。 形状模型是一个基于训练数据的统计模型,它描述了人脸上的关键点相对于人脸的平均形状的变化。通过对大量人脸数据进行训练,可以得到一个形状模型,它可以在新的人脸图像中自动定位关键点。 然而,由于不同人脸之间的差异很大,形状模型在某些情况下可能无法准确地定位关键点。为了解决这个问题,dlib使用了级联回归分类,该分类可以对形状模型的输出进行微调。 级联回归分类是一个多层神经网络,每一层都对前一层的输出进行微调,最终输出关键点的坐标。通过多层级联回归分类的迭代,可以使得关键点的定位更加准确。 综上所述,dlib人脸关键点检测原理是基于形状模型和级联回归分类的组合。形状模型用于初步定位关键点,级联回归分类用于进一步微调关键点的位置,从而实现更准确的关键点检测

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值