rs-face-dlib.cpp
Go to the documentation of this file.
1 // License: Apache 2.0. See LICENSE file in root directory.
2 // Copyright(c) 2019 Intel Corporation. All Rights Reserved.
3 
4 #include <librealsense2/rs.hpp> // Include RealSense Cross Platform API
5 #include <dlib/image_processing/frontal_face_detector.h>
6 #include <dlib/image_processing/render_face_detections.h>
7 #include <dlib/image_processing.h>
8 #include <dlib/gui_widgets.h> // image_window, etc.
9 #include "../rs_frame_image.h"
10 #include "validate_face.h"
11 #include "render_face.h"
12 
13 
14 /*
15  The data pointed to by 'frame.get_data()' is a uint16_t 'depth unit' that needs to be scaled.
16 
17  We return the scaling factor to convert these pixels to meters. This can differ depending
18  on different cameras.
19 */
21 {
22  // Go over the device's sensors
23  for( rs2::sensor& sensor : dev.query_sensors() )
24  {
25  // Check if the sensor if a depth sensor
27  {
28  return dpt.get_depth_scale();
29  }
30  }
31  throw std::runtime_error( "Device does not have a depth sensor" );
32 }
33 
34 
35 int main(int argc, char * argv[]) try
36 {
37  // Declare RealSense pipeline, encapsulating the actual device and sensors
39  // Start streaming with default recommended configuration
41  // Each depth camera might have different units for depth pixels, so we get it here
42  // Using the pipeline's profile, we can retrieve the device that the pipeline uses
43  float const DEVICE_DEPTH_SCALE = get_depth_scale( profile.get_device() );
44 
45 
46  /*
47  The face detector we use is made using the classic Histogram of Oriented
48  Gradients (HOG) feature combined with a linear classifier, an image pyramid,
49  and sliding window detection scheme, using dlib's implementation of:
50  One Millisecond Face Alignment with an Ensemble of Regression Trees by
51  Vahid Kazemi and Josephine Sullivan, CVPR 2014
52  and was trained on the iBUG 300-W face landmark dataset (see
53  https://ibug.doc.ic.ac.uk/resources/facial-point-annotations/):
54  C. Sagonas, E. Antonakos, G, Tzimiropoulos, S. Zafeiriou, M. Pantic.
55  300 faces In-the-wild challenge: Database and results.
56  Image and Vision Computing (IMAVIS), Special Issue on Facial Landmark Localisation "In-The-Wild". 2016.
57 
58  You can get the trained model file from:
59  http://dlib.net/files/shape_predictor_68_face_landmarks.dat.bz2
60 
61  Note that the license for the iBUG 300-W dataset excludes commercial use.
62  So you should contact Imperial College London to find out if it's OK for
63  you to use this model file in a commercial product.
64  */
65  dlib::frontal_face_detector face_bbox_detector = dlib::get_frontal_face_detector();
66  dlib::shape_predictor face_landmark_annotator;
67  dlib::deserialize( "shape_predictor_68_face_landmarks.dat" ) >> face_landmark_annotator;
68  /*
69  The 5-point landmarks model file can be used, instead. It's 10 times smaller and runs
70  faster, from:
71  http://dlib.net/files/shape_predictor_5_face_landmarks.dat.bz2
72  But the validate_face() and render_face() functions will then need to be changed
73  to handle 5 points.
74  */
75 
76  /*
77  We need to map pixels on the color frame to a depth frame, so we can
78  determine their depth. The problem is that the frames may (and probably
79  will!) be of different resolutions, and so alignment is necessary.
80 
81  See the rs-align example for a better understanding.
82 
83  We align the depth frame so it fits in resolution with the color frame
84  since we go from color to depth.
85  */
86  rs2::align align_to_color( RS2_STREAM_COLOR );
87 
88  // Display annotations in one of two colors: if the face is determined to be that of a real
89  // person, it is "good". Otherwise, "bad".
90  dlib::rgb_pixel bad_color( 255, 0, 0 );
91  dlib::rgb_pixel good_color( 0, 255, 0 );
92 
93  dlib::image_window win;
94  while( ! win.is_closed() )
95  {
96  rs2::frameset data = pipe.wait_for_frames(); // Wait for next set of frames from the camera
97  data = align_to_color.process( data ); // Replace with aligned frames
98  auto depth_frame = data.get_depth_frame();
99  auto color_frame = data.get_color_frame();
100 
101  // Create a dlib image for face detection
103 
104  // Detect faces: find bounding boxes around all faces, then annotate each to find its landmarks
105  std::vector< dlib::rectangle > face_bboxes = face_bbox_detector( image );
106  std::vector< dlib::full_object_detection > faces;
107  for( auto const & bbox : face_bboxes )
108  faces.push_back( face_landmark_annotator( image, bbox ));
109 
110  // Display it all on the screen
111  win.clear_overlay();
112  win.set_image( image );
113  for( auto const & face : faces )
114  {
115  dlib::rgb_pixel & color =
116  validate_face( depth_frame, DEVICE_DEPTH_SCALE, face )
117  ? good_color : bad_color;
118  win.add_overlay( render_face( face, color ));
119  }
120  }
121 
122  return EXIT_SUCCESS;
123 }
124 catch( dlib::serialization_error const & e )
125 {
126  std::cerr << "You need dlib's default face landmarking model file to run this example." << std::endl;
127  std::cerr << "You can get it from the following URL: " << std::endl;
128  std::cerr << " http://dlib.net/files/shape_predictor_68_face_landmarks.dat.bz2" << std::endl;
129  std::cerr << std::endl << e.what() << std::endl;
130  return EXIT_FAILURE;
131 }
132 catch (const rs2::error & e)
133 {
134  std::cerr << "RealSense error calling " << e.get_failed_function() << "(" << e.get_failed_args() << "):\n " << e.what() << std::endl;
135  return EXIT_FAILURE;
136 }
137 catch (const std::exception& e)
138 {
139  std::cerr << e.what() << std::endl;
140  return EXIT_FAILURE;
141 }
142 
frameset wait_for_frames(unsigned int timeout_ms=RS2_DEFAULT_TIMEOUT) const
std::vector< dlib::image_window::overlay_line > render_face(dlib::full_object_detection const &face, dlib::rgb_pixel const &color)
Definition: render_face.h:18
std::vector< sensor > query_sensors() const
Definition: rs_device.hpp:25
GLuint color
float get_depth_scale(rs2::device dev)
e
Definition: rmse.py:177
GLenum GLenum GLsizei void * image
depth_frame get_depth_frame() const
Definition: rs_frame.hpp:1006
video_frame get_color_frame() const
Definition: rs_frame.hpp:1015
const std::string & get_failed_args() const
Definition: rs_types.hpp:117
void deserialize(Stream &stream, T &t)
Deserialize an object. Stream here should normally be a rs2rosinternal::serialization::IStream.
frameset process(frameset frames)
int main(int argc, char *argv[])
device get_device() const
Definition: rs_pipeline.hpp:83
bool validate_face(rs2::depth_frame const &frame, float const depth_scale, dlib::full_object_detection const &face)
Definition: validate_face.h:57
std::ostream & cerr()
pipeline_profile start()
const std::string & get_failed_function() const
Definition: rs_types.hpp:112
Definition: parser.hpp:150
GLenum GLuint GLint GLenum face
Definition: glext.h:3377


librealsense2
Author(s): Sergey Dorodnicov , Doron Hirshberg , Mark Horn , Reagan Lopez , Itay Carpis
autogenerated on Mon May 3 2021 02:47:40