当前位置:   article > 正文

【人脸识别】Dlib 深度学习人脸识别_dlib人脸识别训练

dlib人脸识别训练

1,dlib库编译安装

(1)下载源码 dlib C++ Library 生成编译工程(使用cmake),可以选择gup选项,需要cuda9.0支持,点击generate后,Open project使用vs编译即可。

更多内容关注微信公众号:ML_Study

 

编译完成后创建工程,配置相关头文件,包含dlib文件夹的文件夹添加到#include搜索路径,将静态库加入工程,即可编译。

(2)也可将下载的源码直接加入工程,添加all目录的文件,即可在工程一同编译

但速度较慢。具体步骤:

(1),使用Visual Studio 2015或更新版本在Windows上编译只需创建一个空控制台项目。然后添加dlib/all/source.cpp。

(2),将包含dlib文件夹的文件夹添加到#include搜索路径。然后,您可以通过将示例程序添加到项目中来编译它。

(3),如果需要读取libjpeg和libpng图像文件,在Visual Studio中,dlib只使用jpeg和png文件最简单的方法是

将dlib/external文件夹中的所有libjpeg、libpng和zlib源文件添加到项目中,并定义DLIB_PNG_SUPPORT和DLIB_JPEG_SUPPORT预处理器指令。

2,人脸识别测试

 (1)下面是dlib提供的人脸识别例程,该算法在LFW上的人脸识别率为99.38%,官网也有训练方法,使用的是嵌入网络将人脸映射到128维子空间,通过对向量的比较判定是否为同一人,经验阈值为小于0.6则判定为同一人。

人脸关键点检测回归参数 下载

shape_predictor_5_face_landmarks.dat

与深度人脸特征提取的模型参数下载

dlib_face_recognition_resnet_model_v1.dat
  1. #include <dlib/dnn.h>
  2. #include <dlib/gui_widgets.h>
  3. #include <dlib/clustering.h>
  4. #include <dlib/string.h>
  5. #include <dlib/image_io.h>
  6. #include <dlib/image_processing/frontal_face_detector.h>
  7. using namespace dlib;
  8. using namespace std;
  9. // ----------------------------------------------------------------------------------------
  10. // The next bit of code defines a ResNet network. It's basically copied
  11. // and pasted from the dnn_imagenet_ex.cpp example, except we replaced the loss
  12. // layer with loss_metric and made the network somewhat smaller. Go read the introductory
  13. // dlib DNN examples to learn what all this stuff means.
  14. //
  15. // Also, the dnn_metric_learning_on_images_ex.cpp example shows how to train this network.
  16. // The dlib_face_recognition_resnet_model_v1 model used by this example was trained using
  17. // essentially the code shown in dnn_metric_learning_on_images_ex.cpp except the
  18. // mini-batches were made larger (35x15 instead of 5x5), the iterations without progress
  19. // was set to 10000, and the training dataset consisted of about 3 million images instead of
  20. // 55. Also, the input layer was locked to images of size 150.
  21. template <template <int,template<typename>class,int,typename> class block, int N, template<typename>class BN, typename SUBNET>
  22. using residual = add_prev1<block<N,BN,1,tag1<SUBNET>>>;
  23. template <template <int,template<typename>class,int,typename> class block, int N, template<typename>class BN, typename SUBNET>
  24. using residual_down = add_prev2<avg_pool<2,2,2,2,skip1<tag2<block<N,BN,2,tag1<SUBNET>>>>>>;
  25. template <int N, template <typename> class BN, int stride, typename SUBNET>
  26. using block = BN<con<N,3,3,1,1,relu<BN<con<N,3,3,stride,stride,SUBNET>>>>>;
  27. template <int N, typename SUBNET> using ares = relu<residual<block,N,affine,SUBNET>>;
  28. template <int N, typename SUBNET> using ares_down = relu<residual_down<block,N,affine,SUBNET>>;
  29. template <typename SUBNET> using alevel0 = ares_down<256,SUBNET>;
  30. template <typename SUBNET> using alevel1 = ares<256,ares<256,ares_down<256,SUBNET>>>;
  31. template <typename SUBNET> using alevel2 = ares<128,ares<128,ares_down<128,SUBNET>>>;
  32. template <typename SUBNET> using alevel3 = ares<64,ares<64,ares<64,ares_down<64,SUBNET>>>>;
  33. template <typename SUBNET> using alevel4 = ares<32,ares<32,ares<32,SUBNET>>>;
  34. using anet_type = loss_metric<fc_no_bias<128,avg_pool_everything<
  35. alevel0<
  36. alevel1<
  37. alevel2<
  38. alevel3<
  39. alevel4<
  40. max_pool<3,3,2,2,relu<affine<con<32,7,7,2,2,
  41. input_rgb_image_sized<150>
  42. >>>>>>>>>>>>;
  43. // ----------------------------------------------------------------------------------------
  44. std::vector<matrix<rgb_pixel>> jitter_image(
  45. const matrix<rgb_pixel>& img
  46. );
  47. // ----------------------------------------------------------------------------------------
  48. int main(int argc, char** argv) try
  49. {
  50. if (argc != 2)
  51. {
  52. cout << "Run this example by invoking it like this: " << endl;
  53. cout << " ./dnn_face_recognition_ex faces/bald_guys.jpg" << endl;
  54. cout << endl;
  55. cout << "You will also need to get the face landmarking model file as well as " << endl;
  56. cout << "the face recognition model file. Download and then decompress these files from: " << endl;
  57. cout << "http://dlib.net/files/shape_predictor_5_face_landmarks.dat.bz2" << endl;
  58. cout << "http://dlib.net/files/dlib_face_recognition_resnet_model_v1.dat.bz2" << endl;
  59. cout << endl;
  60. return 1;
  61. }
  62. // The first thing we are going to do is load all our models. First, since we need to
  63. // find faces in the image we will need a face detector:
  64. frontal_face_detector detector = get_frontal_face_detector();
  65. // We will also use a face landmarking model to align faces to a standard pose: (see face_landmark_detection_ex.cpp for an introduction)
  66. shape_predictor sp;
  67. deserialize("shape_predictor_5_face_landmarks.dat") >> sp;
  68. // And finally we load the DNN responsible for face recognition.
  69. anet_type net;
  70. deserialize("dlib_face_recognition_resnet_model_v1.dat") >> net;
  71. matrix<rgb_pixel> img;
  72. load_image(img, argv[1]);
  73. // Display the raw image on the screen
  74. image_window win(img);
  75. // Run the face detector on the image of our action heroes, and for each face extract a
  76. // copy that has been normalized to 150x150 pixels in size and appropriately rotated
  77. // and centered.
  78. std::vector<matrix<rgb_pixel>> faces;
  79. for (auto face : detector(img))
  80. {
  81. auto shape = sp(img, face);
  82. matrix<rgb_pixel> face_chip;
  83. extract_image_chip(img, get_face_chip_details(shape,150,0.25), face_chip);
  84. faces.push_back(move(face_chip));
  85. // Also put some boxes on the faces so we can see that the detector is finding
  86. // them.
  87. win.add_overlay(face);
  88. }
  89. if (faces.size() == 0)
  90. {
  91. cout << "No faces found in image!" << endl;
  92. return 1;
  93. }
  94. // This call asks the DNN to convert each face image in faces into a 128D vector.
  95. // In this 128D vector space, images from the same person will be close to each other
  96. // but vectors from different people will be far apart. So we can use these vectors to
  97. // identify if a pair of images are from the same person or from different people.
  98. std::vector<matrix<float,0,1>> face_descriptors = net(faces);
  99. // In particular, one simple thing we can do is face clustering. This next bit of code
  100. // creates a graph of connected faces and then uses the Chinese whispers graph clustering
  101. // algorithm to identify how many people there are and which faces belong to whom.
  102. std::vector<sample_pair> edges;
  103. for (size_t i = 0; i < face_descriptors.size(); ++i)
  104. {
  105. for (size_t j = i; j < face_descriptors.size(); ++j)
  106. {
  107. // Faces are connected in the graph if they are close enough. Here we check if
  108. // the distance between two face descriptors is less than 0.6, which is the
  109. // decision threshold the network was trained to use. Although you can
  110. // certainly use any other threshold you find useful.
  111. if (length(face_descriptors[i]-face_descriptors[j]) < 0.6)
  112. edges.push_back(sample_pair(i,j));
  113. }
  114. }
  115. std::vector<unsigned long> labels;
  116. const auto num_clusters = chinese_whispers(edges, labels);
  117. // This will correctly indicate that there are 4 people in the image.
  118. cout << "number of people found in the image: "<< num_clusters << endl;
  119. // Now let's display the face clustering results on the screen. You will see that it
  120. // correctly grouped all the faces.
  121. std::vector<image_window> win_clusters(num_clusters);
  122. for (size_t cluster_id = 0; cluster_id < num_clusters; ++cluster_id)
  123. {
  124. std::vector<matrix<rgb_pixel>> temp;
  125. for (size_t j = 0; j < labels.size(); ++j)
  126. {
  127. if (cluster_id == labels[j])
  128. temp.push_back(faces[j]);
  129. }
  130. win_clusters[cluster_id].set_title("face cluster " + cast_to_string(cluster_id));
  131. win_clusters[cluster_id].set_image(tile_images(temp));
  132. }
  133. // Finally, let's print one of the face descriptors to the screen.
  134. cout << "face descriptor for one face: " << trans(face_descriptors[0]) << endl;
  135. // It should also be noted that face recognition accuracy can be improved if jittering
  136. // is used when creating face descriptors. In particular, to get 99.38% on the LFW
  137. // benchmark you need to use the jitter_image() routine to compute the descriptors,
  138. // like so:
  139. matrix<float,0,1> face_descriptor = mean(mat(net(jitter_image(faces[0]))));
  140. cout << "jittered face descriptor for one face: " << trans(face_descriptor) << endl;
  141. // If you use the model without jittering, as we did when clustering the bald guys, it
  142. // gets an accuracy of 99.13% on the LFW benchmark. So jittering makes the whole
  143. // procedure a little more accurate but makes face descriptor calculation slower.
  144. cout << "hit enter to terminate" << endl;
  145. cin.get();
  146. }
  147. catch (std::exception& e)
  148. {
  149. cout << e.what() << endl;
  150. }
  151. // ----------------------------------------------------------------------------------------
  152. std::vector<matrix<rgb_pixel>> jitter_image(
  153. const matrix<rgb_pixel>& img
  154. )
  155. {
  156. // All this function does is make 100 copies of img, all slightly jittered by being
  157. // zoomed, rotated, and translated a little bit differently. They are also randomly
  158. // mirrored left to right.
  159. thread_local dlib::rand rnd;
  160. std::vector<matrix<rgb_pixel>> crops;
  161. for (int i = 0; i < 100; ++i)
  162. crops.push_back(jitter_image(img,rnd));
  163. return crops;
  164. }

(2)测试结果

测试图:

结果

【人脸识别】Dlib 深度学习人脸识别_AI知识搬运工-CSDN博客_dlib人脸

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号