使用Dlib來運行基於CNN的人臉檢測


檢測結果如下

這個示例程序需要使用較大的內存,請保證內存足夠。本程序運行速度比較慢,遠不及OpenCV中的人臉檢測。

注釋中提到的幾個文件下載地址如下
http://dlib.net/face_detection_ex.cpp.html
http://dlib.net/dnn_introduction_ex.cpp.html
http://dlib.net/dnn_introduction2_ex.cpp.html
http://dlib.net/dnn_mmod_ex.cpp.html

/*
    這個示例程序展示如何使用Dlib來運行基於CNN的人臉檢測。示例程序加載現有訓練模型數據,並使用它在圖像中查找人臉。CNN模型在運行時比基於HOG模型的檢測要精確很多,然而,只有在GPU上執行才能達到較快的速度。例如,在NVIDIA Titan X GPU上,此程序與face_detection_ex.cpp處理圖像的速度相同。
    另外,剛剛學習dlib深度學習API的用戶應該閱讀dnn_introduction_ex.cpp和dnn_introduction2_ex.cpp示例,來了解API的工作原理。有關對象檢測方法的介紹,您應該閱讀dnn_mmod_ex.cpp



    訓練模型 TRAINING THE MODEL
        最后,有興趣對面部檢測器進行訓練的用戶,可以閱讀dnn_mmod_ex.cpp示例程序。
        應該注意的是,本示例程序中使用的面部檢測器比dnn_mmod_ex.cpp中展示的具有更
        大的訓練數據集和更大的CNN架構,但是其他訓練條件是相同的。如果和dnn_mmod_ex.cpp
        代碼中的net_type比較,可以看到它們非常相似,只是增加了參數的數量。

        另外,訓練中以下訓練參數有所不同:
        dnn_mmod_ex.cpp中有以下更改
            mmod_options options(face_boxes_train,40*40)
            trainer.set_iterations_without_progress_threshold(300);
        在以下示例中使用訓練數據中使用參數為:
            mmod_options options(face_boxes_train, 80*80);
            trainer.set_iterations_without_progress_threshold(8000);

        此外,random_cropper保持默認設置,所以我們沒有調用以下函數:
            cropper.set_chip_dims(200, 200);
            cropper.set_min_object_height(0.2);

        用於訓練的數據也可在下面地址中找到
        http://dlib.net/files/data/dlib_face_detection_dataset-2016-09-30.tar.gz
*/


#include <iostream>
#include <dlib/dnn.h>
#include <dlib/data_io.h>
#include <dlib/image_processing.h>
#include <dlib/gui_widgets.h>


using namespace std;
using namespace dlib;

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

template <long num_filters, typename SUBNET> using con5d = con<num_filters,5,5,2,2,SUBNET>;
template <long num_filters, typename SUBNET> using con5  = con<num_filters,5,5,1,1,SUBNET>;

template <typename SUBNET> using downsampler  = relu<affine<con5d<32, relu<affine<con5d<32, relu<affine<con5d<16,SUBNET>>>>>>>>>;
template <typename SUBNET> using rcon5  = relu<affine<con5<45,SUBNET>>>;

using net_type = loss_mmod<con<1,9,9,1,1,rcon5<rcon5<rcon5<downsampler<input_rgb_image_pyramid<pyramid_down<6>>>>>>>>;

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


int main(int argc, char** argv) try
{
    argc = 3;
    char* v[] = {
        "test",
        "D:\\Picture\\mmod_human_face_detector.dat", /*這是下載的訓練數據*/
        "D:\\Picture\\222209_MIoI_1428332.jpg" /*用於檢測的文件*/
    };
    argv = v;

    if (argc == 1)
    {
        cout << "程序的使用,通過類似如下命令:" << endl;
        cout << "./dnn_mmod_face_detection_ex mmod_human_face_detector.dat faces/*.jpg" << endl;
        cout << "\n你可以從下面的地址獲取 mmod_human_face_detector.dat 文件:\n";
        cout << "http://dlib.net/files/mmod_human_face_detector.dat.bz2" << endl;
        return 0;
    }


    net_type net;
    deserialize(argv[1]) >> net; // 將訓練數據傳遞給檢測器

    image_window win;
    for (int i = 2; i < argc; ++i)
    {
        matrix<rgb_pixel> img;
        load_image(img, argv[i]); // 加載圖像

        // 向上采樣圖像將使得我們能夠檢測較小的面孔,但會導致程序使用更多的內存,並運行時間更長。
        while(img.size() < 512*512)
            pyramid_up(img);

        // 注意,您可以一次處理std::vector中的一堆圖像,並且這樣運行速度更快,
        // 因為這將形成小批量的圖像,從而利用GPU硬件,獲得更好的並行性。
        //但是,所有圖像的大小必須相同。為了避免相同尺寸的這一要求,我們在這個例子中單獨處理每一張圖像。

        auto dets = net(img); // 獲取檢測結果
        win.clear_overlay();  // 清除已經繪制的
        win.set_image(img);   // 繪制圖像
        // 將檢測結果繪制在窗口上
        for (auto&& d : dets){
            win.add_overlay(d);
        }

        // 按下enter鍵去處理下一個圖像
        cout << "Hit enter to process the next image." << endl;
        cin.get();
    }
    return 0;
}
catch(std::exception& e)
{
    cout << e.what() << endl;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM