dlib 人脸识别

其实很不明白,这个库存在这么久了,但csdn有关其的资料那么少,这里写点抛砖引玉。

代码思路:

  1. 获取人脸
  2. 人脸对齐
  3. 对齐后的人脸转128维向量
  4. 人脸识别(计算向量的距离)

效果:

 dlib检测人脸确实有点慢,居然耗时81ms!!!

 main.cpp

#include <dlib/opencv.h>
#include <opencv2/opencv.hpp>
#include <dlib/image_processing/frontal_face_detector.h>
#include <dlib/image_processing/render_face_detections.h>
#include <dlib/image_processing.h>
#include <dlib/image_io.h>
#include <dlib/dnn.h>

#include <chrono>



using namespace dlib;
using namespace std;


template <template <int,template<typename>class,int,typename> class block, int N, template<typename>class BN, typename SUBNET>
using residual = add_prev1<block<N,BN,1,tag1<SUBNET>>>;

template <template <int,template<typename>class,int,typename> class block, int N, template<typename>class BN, typename SUBNET>
using residual_down = add_prev2<avg_pool<2,2,2,2,skip1<tag2<block<N,BN,2,tag1<SUBNET>>>>>>;

template <int N, template <typename> class BN, int stride, typename SUBNET>
using block  = BN<con<N,3,3,1,1,relu<BN<con<N,3,3,stride,stride,SUBNET>>>>>;

template <int N, typename SUBNET> using ares      = relu<residual<block,N,affine,SUBNET>>;
template <int N, typename SUBNET> using ares_down = relu<residual_down<block,N,affine,SUBNET>>;

template <typename SUBNET> using alevel0 = ares_down<256,SUBNET>;
template <typename SUBNET> using alevel1 = ares<256,ares<256,ares_down<256,SUBNET>>>;
template <typename SUBNET> using alevel2 = ares<128,ares<128,ares_down<128,SUBNET>>>;
template <typename SUBNET> using alevel3 = ares<64,ares<64,ares<64,ares_down<64,SUBNET>>>>;
template <typename SUBNET> using alevel4 = ares<32,ares<32,ares<32,SUBNET>>>;

using anet_type = loss_metric<fc_no_bias<128,avg_pool_everything<
                            alevel0<
                            alevel1<
                            alevel2<
                            alevel3<
                            alevel4<
                            max_pool<3,3,2,2,relu<affine<con<32,7,7,2,2,
                            input_rgb_image_sized<150>
                            >>>>>>>>>>>>;

int main()
{
    // face detector
    frontal_face_detector detector = get_frontal_face_detector();

    // face landmarking model
    shape_predictor sp;
    deserialize("/home/jason/file/dlib_models/shape_predictor_5_face_landmarks.dat") >> sp;

    // dnn for face recognition
    anet_type net;
    deserialize("/home/jason/file/dlib_models/dlib_face_recognition_resnet_model_v1.dat") >> net;

    // read img and display it
    matrix<rgb_pixel> img;
    load_image(img, "/home/jason/work/01-img/shuchang.png");


    // face detect
    auto start = std::chrono::system_clock::now();
    std::vector<dlib::rectangle> faces = detector(img);
    for (auto face : faces){
        cv::rectangle(dlib::toMat(img), cv::Point(face.left(), face.top()), cv::Point(face.right(), face.bottom()), cv::Scalar(0,0,255),1);
    }
    auto end = std::chrono::system_clock::now();
    cv::imshow("face detect",dlib::toMat(img));

    auto timeUse = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
    cout << "dlib face detect time use:" << timeUse << "ms\n";

    // face 对齐
     std::vector<matrix<rgb_pixel>> alignedFaces;
    for (auto face:faces){

        // get 5 face landmark points
        auto shape = sp(img,face);

        matrix<rgb_pixel> face_chip;
        extract_image_chip(img,get_face_chip_details(shape, 150, 0.25), face_chip);
        alignedFaces.push_back(move(face_chip));
    }
    cv::imshow("face align", dlib::toMat(alignedFaces[0]));

    // use dnn convert face chip to a 128D verctor
    std::vector<matrix<float,0,1>> face_descriptors = net(alignedFaces);

    // compute distance
    float difference =  length(face_descriptors[0] - face_descriptors[0]);
    cout << "differrence : " << difference << endl;
//    cout << "128D-vector:" << face_descriptors[0] << endl;

    cv::waitKey(0);

    return 0;


}

CmakeList.txt

cmake_minimum_required(VERSION 3.5)


PROJECT(example)   #设置工程名

SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -O2 -DDLIB_JPEG_SUPPORT")

IF(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
  SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Weverything")
ELSEIF(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
  SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra")
ENDIF()

#INCLUDE OPENCV
FIND_PACKAGE(OpenCV REQUIRED)
INCLUDE_DIRECTORIES(${OpenCV_INCLUDE_DIRS})
message(STATUS "Opencv include dir found at ${OpenCV_INCLUDE_DIRS}")

#包含头文件
INCLUDE_DIRECTORIES(/home/jason/file/dlib) #dlib根目录地址

LINK_DIRECTORIES(/home/jason/file/dlib/build/dlib) #dlib编译后bulid下dlib地址

#生产类似于.exe的可执行文件
ADD_EXECUTABLE(dlib_facedetector main.cpp
    /home/jason/file/dlib/dlib/cuda/cpu_dlib.h
    /home/jason/file/dlib/dlib/cuda/cpu_dlib.cpp

    /home/jason/file/dlib/dlib/cuda/tensor_tools.h
    /home/jason/file/dlib/dlib/cuda/tensor_tools.cpp
    )
#链接库
TARGET_LINK_LIBRARIES(dlib_facedetector dlib ${OpenCV_LIBS})
TARGET_LINK_LIBRARIES(dlib_facedetector libjpeg.so)

猜你喜欢

转载自blog.csdn.net/weixin_45824067/article/details/131296953