gaze  0.1.0
Perform gaze tracking with common webcams.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Groups Pages
gaze_capture.cpp
1 #include "gaze/pipeline_steps/gaze_capture.h"
2 
3 #include <string>
4 
5 #include "dlib/image_processing.h"
6 #include "dlib/image_transforms.h"
7 #include "dlib/opencv.h"
8 #include "opencv2/opencv.hpp"
9 #include "yaml-cpp/yaml.h"
10 
11 #ifdef HAS_CAFFE
12 #include "itracker/itracker.h"
13 #endif
14 
15 #include "gaze/gui/visualizeable.h"
16 #include "gaze/pipeline_step.h"
17 #include "gaze/util/config.h"
18 #include "gaze/util/data.h"
19 #include "gaze/util/pipeline_utils.h"
20 
21 
22 namespace gaze {
23 
24 namespace pipeline {
25 
26 GazeCapture::GazeCapture() {
27  YAML::Node config = util::get_config(this->number);
28  this->name = config["name"] ?
29  config["name"].as<std::string>() : "iTracker";
30 
31  // Read caffe model configurations
32  std::string model_file = config["model"] ?
33  config["model"].as<std::string>() : "models/itracker_deploy.prototxt";
34  std::string weights_file = config["weights"] ?
35  config["weights"].as<std::string>() :
36  "models/snapshots/itracker25x_iter_92000.caffemodel";
37  std::string mean_left_file = config["mean_left"] ?
38  config["mean_left"].as<std::string>() :
39  "models/mean_images/mean_left_224_new.binaryproto";
40  std::string mean_right_file = config["mean_right"] ?
41  config["mean_right"].as<std::string>() :
42  "models/mean_images/mean_right_224.binaryproto";
43  std::string mean_face_file = config["mean_face"] ?
44  config["mean_face"].as<std::string>() :
45  "models/mean_images/mean_face_224.binaryproto";
46 
47 #ifdef HAS_CAFFE
48  YAML::Node meta_config = util::get_config()["meta"];
49  YAML::Node camera_config = meta_config["camera"];
50  this->camera_offset = cv::Vec2d(camera_config["position"]["x"].as<double>(),
51  camera_config["position"]["y"].as<double>());
52 
53  YAML::Node screen_config = meta_config["screen"];
54  this->screen_size_m =
55  cv::Vec2d(screen_config["measurements"]["width"].as<double>(),
56  screen_config["measurements"]["height"].as<double>());
57  this->target_size =
58  cv::Vec2d(screen_config["resolution"]["width"].as<double>(),
59  screen_config["resolution"]["height"].as<double>());
60  // Init network
61  this->itracker = std::unique_ptr<itracker::ITracker>(
62  new itracker::ITracker(model_file, weights_file,
63  mean_left_file, mean_right_file, mean_face_file));
64 
65  if (meta_config["target"]) {
66  this->target_size =
67  cv::Vec2d(meta_config["target"]["width"].as<int>(),
68  meta_config["target"]["height"].as<int>());
69  }
70 #endif
71 }
72 
74  if (data.landmarks.num_parts() < 5) {
75  return;
76  }
77 
78 #ifdef HAS_CAFFE
79  // Gather input
82 
83  auto right_dlib = dlib::sub_image(data.image, chips[0].rect);
84  auto left_dlib = dlib::sub_image(data.image, chips[1].rect);
85  auto face_dlib = dlib::sub_image(data.image, data.landmarks.get_rect());
86  cv::Mat right = dlib::toMat(right_dlib);
87  cv::Mat left = dlib::toMat(left_dlib);
88  cv::Mat face = dlib::toMat(face_dlib);
89 
90  dlib::matrix<unsigned char> mask_in =
91  dlib::zeros_matrix<unsigned char>(data.image.nr(), data.image.nc());
92  dlib::set_subm(mask_in, data.landmarks.get_rect()) = 1;
93  dlib::matrix<unsigned char, 25, 25> mask_out;
94  dlib::resize_image(mask_in, mask_out, dlib::interpolate_nearest_neighbor());
95  cv::Mat mask = dlib::toMat(mask_out);
96 
97  cv::Vec2d prediction_cam = this->itracker->predict(left, right, face, mask);
98  // Note that the prediction is in cm, thus DIV100 is needed
99  double x = (prediction_cam[0] / 100 + this->camera_offset[0])
100  / this->screen_size_m[0] * this->target_size[0];
101  double y = (-prediction_cam[1] / 100 + this->camera_offset[1])
102  / this->screen_size_m[1] * this->target_size[1];
103  data.estimated_gaze_point = cv::Vec2d(x, y);
104 #endif
105 }
106 
108 #ifdef HAS_CAFFE
110 #endif
111 }
112 
113 } // namespace pipeline
114 
115 } // namespace gaze
ios_base & left(ios_base &__base)
void process(util::Data &data) override
std::vector< dlib::chip_details > get_eyes_chip_details(const dlib::full_object_detection object_detection)
void visualize(util::Data &data) override
dlib::array2d< dlib::bgr_pixel > image
Definition: data.h:52
Implements a wrapper around the pre-trained caffe model by .
Definition: itracker.h:31
cv::Vec2d estimated_gaze_point
Definition: data.h:105
ostream cout
dlib::full_object_detection landmarks
Definition: data.h:64
Vec< double, 2 > Vec2d
std::string name
Definition: pipeline_step.h:31
Wraps the data acquired per frame into a single instance.
Definition: data.h:27
basic_ostream< _CharT, _Traits > & endl(basic_ostream< _CharT, _Traits > &__os)
cv::Mat toMat() const
ios_base & right(ios_base &__base)
YAML::Node get_config()
Definition: config.in.cpp:12