22#ifndef EOS_CONTOUR_CORRESPONDENCE_HPP
23#define EOS_CONTOUR_CORRESPONDENCE_HPP
25#include "eos/core/Landmark.hpp"
26#include "eos/core/Mesh.hpp"
27#include "eos/render/matrix_projection.hpp"
29#include "cereal/types/vector.hpp"
30#include "cereal/archives/json.hpp"
47struct ContourLandmarks;
48std::pair<std::vector<std::string>, std::vector<int>>
49select_contour(
float yaw_angle,
const ContourLandmarks& contour_landmarks,
const ModelContour& model_contour,
50 float frontal_range_threshold = 7.5f);
51std::tuple<std::vector<Eigen::Vector2f>, std::vector<Eigen::Vector4f>, std::vector<int>>
53 const std::vector<std::string>& landmark_contour_identifiers,
54 const std::vector<int>& model_contour_indices,
const core::Mesh& mesh,
55 const Eigen::Matrix4f& view_model,
56 const Eigen::Matrix4f& ortho_projection,
const Eigen::Vector4f& viewport);
73 std::vector<int> right_contour;
76 std::vector<int> left_contour;
98 std::ifstream file(filename);
101 throw std::runtime_error(
"Error opening given file: " + filename);
103 cereal::JSONInputArchive input_archive(file);
104 input_archive(contour);
109 friend class cereal::access;
115 template <
class Archive>
118 archive(cereal::make_nvp(
"right_contour", right_contour),
119 cereal::make_nvp(
"left_contour", left_contour));
142 std::vector<std::string> right_contour;
145 std::vector<std::string> left_contour;
162 const auto data = toml::parse(filename);
166 const auto& contour_table = toml::get<toml::table>(data.at(
"contour_landmarks"));
172 const auto& right_contour = toml::get<std::vector<toml::value>>(contour_table.at(
"right"));
173 for (
const auto& landmark : right_contour)
176 switch (landmark.type())
178 case toml::value_t::integer:
179 value = std::to_string(toml::get<int>(landmark));
181 case toml::value_t::string:
182 value = toml::get<std::string>(landmark);
185 throw std::runtime_error(
"unexpected type : " + toml::stringize(landmark.type()));
187 contour.right_contour.push_back(value);
190 const auto& left_contour = toml::get<std::vector<toml::value>>(contour_table.at(
"left"));
191 for (
const auto& landmark : left_contour)
194 switch (landmark.type())
196 case toml::value_t::integer:
197 value = std::to_string(toml::get<int>(landmark));
199 case toml::value_t::string:
200 value = toml::get<std::string>(landmark);
203 throw std::runtime_error(
"unexpected type : " + toml::stringize(landmark.type()));
205 contour.left_contour.push_back(value);
236inline std::tuple<std::vector<Eigen::Vector2f>, std::vector<Eigen::Vector4f>, std::vector<int>>
239 float yaw_angle,
const core::Mesh& mesh,
const Eigen::Matrix4f& view_model,
240 const Eigen::Matrix4f& ortho_projection,
const Eigen::Vector4f& viewport,
241 float frontal_range_threshold = 7.5f)
244 std::vector<int> model_contour_indices;
245 std::vector<std::string> landmark_contour_identifiers;
246 std::tie(landmark_contour_identifiers, model_contour_indices) =
247 select_contour(yaw_angle, contour_landmarks, model_contour, frontal_range_threshold);
253 mesh, view_model, ortho_projection, viewport);
272inline std::pair<std::vector<std::string>, std::vector<int>>
277 std::vector<int> model_contour_indices;
278 std::vector<std::string> contour_landmark_identifiers;
279 if (yaw_angle >= -frontal_range_threshold)
282 model_contour_indices.insert(end(model_contour_indices), begin(model_contour.right_contour),
283 end(model_contour.right_contour));
284 contour_landmark_identifiers.insert(end(contour_landmark_identifiers),
285 begin(contour_landmarks.right_contour),
286 end(contour_landmarks.right_contour));
288 if (yaw_angle <= frontal_range_threshold)
291 model_contour_indices.insert(end(model_contour_indices), begin(model_contour.left_contour),
292 end(model_contour.left_contour));
293 contour_landmark_identifiers.insert(end(contour_landmark_identifiers),
294 begin(contour_landmarks.left_contour),
295 end(contour_landmarks.left_contour));
298 return std::make_pair(contour_landmark_identifiers, model_contour_indices);
321inline std::tuple<std::vector<Eigen::Vector2f>, std::vector<Eigen::Vector4f>, std::vector<int>>
323 const std::vector<std::string>& landmark_contour_identifiers,
324 const std::vector<int>& model_contour_indices,
const core::Mesh& mesh,
325 const Eigen::Matrix4f& view_model,
326 const Eigen::Matrix4f& ortho_projection,
const Eigen::Vector4f& viewport)
329 std::vector<Eigen::Vector4f> model_points_cnt;
330 std::vector<int> vertex_indices_cnt;
331 std::vector<Eigen::Vector2f> image_points_cnt;
336 for (
const auto& ibug_idx : landmark_contour_identifiers)
341 const auto result = std::find_if(begin(landmarks), end(landmarks), [&ibug_idx](
auto&& e) {
342 return e.name == ibug_idx;
344 if (result == std::end(landmarks))
350 const auto screen_point_2d_contour_landmark = result->coordinates;
352 std::vector<float> distances_2d;
353 for (
auto model_contour_vertex_idx : model_contour_indices)
358 mesh.
vertices[model_contour_vertex_idx], view_model, ortho_projection, viewport);
360 (screen_point_model_contour.head<2>() - screen_point_2d_contour_landmark).norm();
361 distances_2d.emplace_back(dist);
363 const auto min_ele = std::min_element(begin(distances_2d), end(distances_2d));
365 const auto min_ele_idx = std::distance(begin(distances_2d), min_ele);
366 const auto the_3dmm_vertex_id_that_is_closest = model_contour_indices[min_ele_idx];
368 model_points_cnt.emplace_back(mesh.
vertices[the_3dmm_vertex_id_that_is_closest].homogeneous());
369 vertex_indices_cnt.emplace_back(the_3dmm_vertex_id_that_is_closest);
370 image_points_cnt.emplace_back(screen_point_2d_contour_landmark);
373 return std::make_tuple(image_points_cnt, model_points_cnt, vertex_indices_cnt);
388inline auto concat(
const std::vector<T>& vec_a,
const std::vector<T>& vec_b)
390 std::vector<T> concatenated_vec;
391 concatenated_vec.reserve(vec_a.size() + vec_b.size());
392 concatenated_vec.insert(std::end(concatenated_vec), std::begin(vec_a), std::end(vec_a));
393 concatenated_vec.insert(std::end(concatenated_vec), std::begin(vec_b), std::end(vec_b));
394 return concatenated_vec;
std::vector< Landmark< LandmarkType > > LandmarkCollection
A trivial collection of landmarks that belong together.
Definition: Landmark.hpp:47
std::pair< std::vector< std::string >, std::vector< int > > select_contour(float yaw_angle, const ContourLandmarks &contour_landmarks, const ModelContour &model_contour, float frontal_range_threshold=7.5f)
Definition: contour_correspondence.hpp:273
std::tuple< std::vector< Eigen::Vector2f >, std::vector< Eigen::Vector4f >, std::vector< int > > get_nearest_contour_correspondences(const core::LandmarkCollection< Eigen::Vector2f > &landmarks, const std::vector< std::string > &landmark_contour_identifiers, const std::vector< int > &model_contour_indices, const core::Mesh &mesh, const Eigen::Matrix4f &view_model, const Eigen::Matrix4f &ortho_projection, const Eigen::Vector4f &viewport)
Definition: contour_correspondence.hpp:322
auto concat(const std::vector< T > &vec_a, const std::vector< T > &vec_b)
Concatenates two std::vector's of the same type and returns the concatenated vector....
Definition: contour_correspondence.hpp:388
std::tuple< std::vector< Eigen::Vector2f >, std::vector< Eigen::Vector4f >, std::vector< int > > get_contour_correspondences(const core::LandmarkCollection< Eigen::Vector2f > &landmarks, const ContourLandmarks &contour_landmarks, const ModelContour &model_contour, float yaw_angle, const core::Mesh &mesh, const Eigen::Matrix4f &view_model, const Eigen::Matrix4f &ortho_projection, const Eigen::Vector4f &viewport, float frontal_range_threshold=7.5f)
Definition: contour_correspondence.hpp:237
Eigen::Vector3< T > project(const Eigen::Vector3< T > &point_3d, const Eigen::Matrix4< T > &modelview_matrix, const Eigen::Matrix4< T > &projection_matrix, const Eigen::Vector4< T > &viewport)
Definition: matrix_projection.hpp:148
Namespace containing all of eos's 3D model fitting functionality.
This class represents a 3D mesh consisting of vertices, vertex colour information and texture coordin...
Definition: Mesh.hpp:45
std::vector< Eigen::Vector3f > vertices
3D vertex positions.
Definition: Mesh.hpp:46
Defines which 2D landmarks comprise the right and left face contour.
Definition: contour_correspondence.hpp:140
static ContourLandmarks load(std::string filename)
Definition: contour_correspondence.hpp:158
Definition of the vertex indices that define the right and left model contour.
Definition: contour_correspondence.hpp:71
void serialize(Archive &archive)
Definition: contour_correspondence.hpp:116
static ModelContour load(std::string filename)
Definition: contour_correspondence.hpp:94