DLIB关键点检测初探

主要还是项目要求吧,需要进行人脸68个关键点检测,然后网上寻找一番,发现DLIB库使用还是挺高的,然后就在上篇博客中简单记录了一下DLIB 19.17的配置过程,但是还是要尝试下它的程序的。

LZ修改过的版本由于保密原因就不进行展示(≧▽≦)/啦啦啦,给出官方给的源码吧。

#include <dlib/image_processing/frontal_face_detector.h>
#include <dlib/image_processing/render_face_detections.h>
#include <dlib/image_processing.h>
#include <dlib/gui_widgets.h>
#include <dlib/image_io.h>
#include <iostream>

using namespace dlib;
using namespace std;

// ----------------------------------------------------------------------------------------

int main(int argc, char** argv)
{  
    try
    {
        // This example takes in a shape model file and then a list of images to
        // process.  We will take these filenames in as command line arguments.
        // Dlib comes with example images in the examples/faces folder so give
        // those as arguments to this program.
        //这里要去对应的网址下载关键点检测的数据,网速还是很渣渣
        if (argc == 1)
        {
            cout << "Call this program like this:" << endl;
            cout << "./face_landmark_detection_ex shape_predictor_68_face_landmarks.dat faces/*.jpg" << endl;
            cout << "\nYou can get the shape_predictor_68_face_landmarks.dat file from:\n";
            cout << "http://dlib.net/files/shape_predictor_68_face_landmarks.dat.bz2" << endl;
            return 0;
        }

        // We need a face detector.  We will use this to get bounding boxes for
        // each face in an image.
        // 初始化检测器
        frontal_face_detector detector = get_frontal_face_detector();
        // And we also need a shape_predictor.  This is the tool that will predict face
        // landmark positions given an image and face bounding box.  Here we are just
        // loading the model from the shape_predictor_68_face_landmarks.dat file you gave
        // as a command line argument.
        shape_predictor sp;
        deserialize(argv[1]) >> sp;


        image_window win, win_faces;
        // Loop over all the images provided on the command line.
        for (int i = 2; i < argc; ++i)
        {
            cout << "processing image " << argv[i] << endl;
            array2d<rgb_pixel> img;
            load_image(img, argv[i]);
            // Make the image larger so we can detect small faces.
            pyramid_up(img);

            // Now tell the face detector to give us a list of bounding boxes
            // around all the faces in the image.
            std::vector<rectangle> dets = detector(img);
            cout << "Number of faces detected: " << dets.size() << endl;

            // Now we will go ask the shape_predictor to tell us the pose of
            // each face we detected.
            std::vector<full_object_detection> shapes;
            for (unsigned long j = 0; j < dets.size(); ++j)
            {
                full_object_detection shape = sp(img, dets[j]);
                cout << "number of parts: "<< shape.num_parts() << endl;
                cout << "pixel position of first part:  " << shape.part(0) << endl;
                cout << "pixel position of second part: " << shape.part(1) << endl;
                // You get the idea, you can get all the face part locations if
                // you want them.  Here we just store them in shapes so we can
                // put them on the screen.
                shapes.push_back(shape);
            }

            // Now let's view our face poses on the screen.
            win.clear_overlay();
            win.set_image(img);
            win.add_overlay(render_face_detections(shapes));

            // We can also extract copies of each face that are cropped, rotated upright,
            // and scaled to a standard size as shown here:
            dlib::array<array2d<rgb_pixel> > face_chips;
            extract_image_chips(img, get_face_chip_details(shapes), face_chips);
            win_faces.set_image(tile_images(face_chips));

            cout << "Hit enter to process the next image..." << endl;
            cin.get();
        }
    }
    catch (exception& e)
    {
        cout << "\nexception thrown!" << endl;
        cout << e.what() << endl;
    }
}


其实上述代码LZ觉得官方还是很良心的,仔细看看,基本上每一步都讲解的非常清楚,下面是对应的CMakeLists.txt。

cmake_minimum_required(VERSION 3.14)
project(gaze_correction_v1)

set(CMAKE_CXX_STANDARD 11)

#opencv
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})

#DLIB19.17
add_subdirectory(/home/felaim/Documents/software/dlib-19.17/dlib dlib_build)
#include_directories(/usr/local/include/dlib)

add_executable(gaze_correction_v1 main.cpp)

target_link_libraries(gaze_correction_v1 ${OpenCV_LIBS}
        dlib::dlib
        )

LZ把include_directories部分给注释掉了,因为不注释汇报一个错,说DLIB路径不能include,类似错误啦(≧▽≦)/啦啦啦

后面进行测试,通常情况下C++版本的基本上都会比python版本的速度要快一些,但是LZ运行了上述代码,居然奇慢无比,处理一张640*480的图片要2000多ms,然后LZ就疯狂百度,发现其他小伙伴测试人脸检测速度也不快,大概50ms~100ms左右,但是LZ电脑好歹也是i7,给我的感觉仿佛是个i3。。。,后来总算找到了原因,LZ编译成debug模式,DLIB库在Debug模式下奇慢!非常慢!

最后修改成release模式,人脸检测大概需要38ms,关键点检测需要3ms,虽然速度还可以,但是远远达不到项目要求/(ㄒoㄒ)/~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值