1 #include "gaze/pipeline_steps/pupil_localization.h" 
    8 #include "dlib/image_processing.h" 
    9 #include "dlib/image_transforms.h" 
   10 #include "dlib/matrix.h" 
   11 #include "dlib/opencv.h" 
   12 #include "yaml-cpp/yaml.h" 
   14 #include "gaze/util/config.h" 
   15 #include "gaze/util/data.h" 
   16 #include "gaze/util/pipeline_utils.h" 
   24     dlib::matrix<double>& table_x,  
 
   25     dlib::matrix<double>& table_y,  
 
   29   if (size <= table_x.nr()) {
 
   34   size += (1 - size & 1);
 
   35   int half_size = (size - 1) / 2;
 
   38   table_x.set_size(size, size);
 
   39   table_y.set_size(size, size);
 
   42   for (
int row = 0; row < table_x.nr(); ++row) {
 
   43     dlib::set_rowm(table_x, row) = dlib::range(-half_size, half_size);
 
   45   table_y = dlib::trans(table_x);
 
   49   for (
int row = 0; row < table_x.nr(); ++row) {
 
   50     for (
int col = 0; col < table_x.nc(); ++col) {
 
   51       table_x(row, col) = table_x(row, col) /
 
   52         (
std::sqrt(table_x(row, col) * table_x(row, col)
 
   53                    + table_y(row, col) * table_y(row, col))
 
   58   table_y = dlib::trans(table_x);
 
   65 PupilLocalization::PupilLocalization()
 
   69     : relative_threshold_factor(0.3),
 
   72   this->name = config[
"name"] ?
 
   73     config[
"name"].as<
std::string>() : 
"PupilLocalization";
 
   75   if (config[
"relative_threshold"]) {
 
   76     this->relative_threshold_factor =
 
   77       config[
"relative_threshold"]
 
   78         .as<decltype(this->relative_threshold_factor)>();
 
   83       this->displacement_table_x,
 
   84       this->displacement_table_y,
 
   85       config[
"table_size"] ? config[
"table_size"].as<int>() : 131);
 
   96   dlib::extract_image_chips(data.
image, details, data.
eyes);
 
  100                            data.
eyes[1].nr(), data.
eyes[1].nc()});
 
  101   if (2 * max_size > this->displacement_table_x.nr()) {
 
  103         this->displacement_table_x,
 
  104         this->displacement_table_y,
 
  108   for (
int i = 0; i < 2; ++i) {
 
  109     dlib::matrix<double> eye_in;
 
  110     dlib::assign_image(eye_in, data.
eyes[i]);
 
  113     dlib::matrix<double> eye_horizontal;
 
  114     dlib::matrix<double> eye_vertical;
 
  115     dlib::sobel_edge_detector(eye_in, eye_horizontal, eye_vertical);
 
  118         this->relative_threshold_factor);
 
  121     int boundary_offset = 6;
 
  122     dlib::matrix<double> eye_gaussian;
 
  123     dlib::gaussian_blur(eye_in, eye_gaussian, this->sigma, boundary_offset);
 
  124     eye_gaussian = 255 - eye_gaussian;
 
  131     int center = (this->displacement_table_x.nr() - 1) / 2;
 
  132     auto nr = eye_in.nr();
 
  133     auto nc = eye_in.nc();
 
  134     dlib::matrix<double> 
zero = dlib::zeros_matrix<double>(nr, nc);
 
  135     dlib::matrix<double> ts = dlib::zeros_matrix<double>(nr, nc);
 
  136     for (
auto row = decltype(nr){boundary_offset};
 
  137          row < nr - boundary_offset; ++row) {
 
  138       for (
auto col = decltype(nc){boundary_offset};
 
  139            col < nc - boundary_offset; ++col) {
 
  140         dlib::matrix<double> d_x = dlib::subm(this->displacement_table_x,
 
  141             center - row, center - col, nr, nc);
 
  142         dlib::matrix<double> d_y = dlib::subm(this->displacement_table_y,
 
  143             center - row, center - col, nr, nc);
 
  147               dlib::squared(dlib::max_pointwise(
 
  148                 dlib::pointwise_multiply(d_x, eye_horizontal) +
 
  149                 dlib::pointwise_multiply(d_y, eye_vertical), zero))) *
 
  150           eye_gaussian(row, col);
 
  158     data.
centers[i] = dlib::point(argmax_c, argmax_r);
 
  170   dlib::point offset_x(5, 0);
 
  171   dlib::point offset_y(0, 5);
 
  176   dlib::array<dlib::array2d<dlib::bgr_pixel>> eyes(3);
 
  177   dlib::assign_image(eyes[2], data.
image);
 
  178   for (
auto i = decltype(data.
eyes.size()){0};
 
  179        i < data.
eyes.size(); ++i) {
 
  180     dlib::assign_image(eyes[i], data.
eyes[i]);
 
  182     dlib::draw_line(eyes[i],
 
  185                     dlib::rgb_pixel(255, 0, 0));
 
  186     dlib::draw_line(eyes[i],
 
  189                     dlib::rgb_pixel(255, 0, 0));
 
  191     dlib::draw_line(eyes[2],
 
  192                     data.
centers[i] + offset_x + chips[i].rect.tl_corner(),
 
  193                     data.
centers[i] - offset_x + chips[i].rect.tl_corner(),
 
  194                     dlib::rgb_pixel(255, 0, 0));
 
  195     dlib::draw_line(eyes[2],
 
  196                     data.
centers[i] + offset_y + chips[i].rect.tl_corner(),
 
  197                     data.
centers[i] - offset_y + chips[i].rect.tl_corner(),
 
  198                     dlib::rgb_pixel(255, 0, 0));
 
  200   dlib::resize_image(0.5, eyes[2]);
 
  202   this->widget->set_image(dlib::tile_images(eyes));
 
std::vector< dlib::chip_details > get_eyes_chip_details(const dlib::full_object_detection object_detection)
 
dlib::array< dlib::array2d< double > > eyes
 
dlib::array< dlib::point > centers
 
dlib::array2d< dlib::bgr_pixel > image
 
void fill_displacement_tables(dlib::matrix< double > &table_x, dlib::matrix< double > &table_y, int size)
 
_GLIBCXX14_CONSTEXPR const _Tp & max(const _Tp &__a, const _Tp &__b)
 
static constexpr _Tp min() noexcept
 
dlib::full_object_detection landmarks
 
Wraps the data acquired per frame into a single instance. 
 
complex< _Tp > sqrt(const complex< _Tp > &)
 
void normalize_and_threshold_gradients(dlib::matrix< T > &horizontal, dlib::matrix< T > &vertical, double relative_threshold=-1)