22#ifndef EOS_CLOSEST_EDGE_FITTING_HPP
23#define EOS_CLOSEST_EDGE_FITTING_HPP
25#include "eos/core/Mesh.hpp"
26#include "eos/morphablemodel/EdgeTopology.hpp"
27#include "eos/fitting/RenderingParameters.hpp"
28#include "eos/render/normals.hpp"
29#include "eos/render/vertex_visibility.hpp"
30#include "eos/render/ProjectionType.hpp"
31#include "eos/render/matrix_projection.hpp"
33#include "nanoflann.hpp"
63 bool perform_self_occlusion_check =
true)
66 std::vector<Eigen::Vector3f> rotated_vertices;
67 std::for_each(begin(mesh.
vertices), end(mesh.
vertices), [&rotated_vertices, &R](
const auto& v) {
68 rotated_vertices.push_back(R * v);
72 std::vector<Eigen::Vector3f> facenormals;
73 for (
const auto& f : mesh.
tvi)
76 rotated_vertices[f[2]]);
77 facenormals.push_back(n);
81 std::vector<int> occluding_edges_indices;
82 for (
int edge_idx = 0; edge_idx < edge_topology.
adjacent_faces.size();
98 occluding_edges_indices.push_back(edge_idx);
103 std::vector<int> occluding_vertices;
104 for (
auto edge_idx : occluding_edges_indices)
111 std::sort(begin(occluding_vertices), end(occluding_vertices));
112 occluding_vertices.erase(std::unique(begin(occluding_vertices), end(occluding_vertices)),
113 end(occluding_vertices));
115 if (perform_self_occlusion_check)
120 using render::detail::RayDirection;
121 RayDirection ray_direction_type;
122 if (projection_type == render::ProjectionType::Orthographic)
124 ray_direction_type = RayDirection::Parallel;
127 ray_direction_type = RayDirection::TowardsOrigin;
129 std::vector<bool> visibility;
130 for (
auto vertex_idx : occluding_vertices)
133 mesh.
tvi, ray_direction_type);
134 visibility.push_back(visible);
138 std::vector<int> final_vertex_ids;
139 for (
int i = 0; i < occluding_vertices.size(); ++i)
141 if (visibility[i] ==
true)
143 final_vertex_ids.push_back(occluding_vertices[i]);
146 return final_vertex_ids;
149 return occluding_vertices;
170template <
class VectorOfVectorsType,
typename num_t = double,
int DIM = -1,
171 class Distance = nanoflann::metric_L2,
typename IndexType =
size_t>
175 typedef typename Distance::template traits<num_t, self_t>::distance_t metric_t;
176 typedef nanoflann::KDTreeSingleIndexAdaptor<metric_t, self_t, DIM, IndexType> index_t;
183 const int leaf_max_size = 10)
186 assert(mat.size() != 0 && mat[0].size() != 0);
187 const size_t dims = mat[0].size();
188 if (DIM > 0 &&
static_cast<int>(dims) != DIM)
189 throw std::runtime_error(
"Data set dimensionality does not match the 'DIM' template argument");
190 index =
new index_t(dims, *
this , nanoflann::KDTreeSingleIndexAdaptorParams(leaf_max_size));
196 const VectorOfVectorsType& m_data;
203 inline void query(
const num_t* query_point,
const size_t num_closest, IndexType* out_indices,
204 num_t* out_distances_sq,
const int nChecks_IGNORED = 10)
const
206 nanoflann::KNNResultSet<num_t, IndexType> resultSet(num_closest);
207 resultSet.init(out_indices, out_distances_sq);
208 index->findNeighbors(resultSet, query_point, nanoflann::SearchParams());
214 const self_t& derived()
const {
return *
this; }
215 self_t& derived() {
return *
this; }
218 inline size_t kdtree_get_point_count()
const {
return m_data.size(); }
222 inline num_t kdtree_distance(
const num_t* p1,
const size_t idx_p2,
size_t size)
const
225 for (
size_t i = 0; i < size; i++)
227 const num_t d = p1[i] - m_data[idx_p2][i];
234 inline num_t kdtree_get_pt(
const size_t idx,
int dim)
const
236 return m_data[idx][dim];
242 template <
class BBOX>
243 bool kdtree_get_bbox(BBOX& )
const
281 float distance_threshold = 64.0f,
bool perform_self_occlusion_check =
true)
283 assert(rendering_parameters.get_camera_type() == fitting::CameraType::Orthographic);
284 using Eigen::Vector2f;
288 if (image_edges.empty())
295 if (rendering_parameters.get_camera_type() == CameraType::Orthographic)
297 return render::ProjectionType::Orthographic;
300 return render::ProjectionType::Perspective;
304 mesh, edge_topology, rendering_parameters.get_rotation().normalized().toRotationMatrix(),
305 projection_type, perform_self_occlusion_check);
308 vector<Vector2f> model_edges_projected;
309 for (
const auto& v : occluding_vertices)
314 rendering_parameters.get_screen_height()));
315 model_edges_projected.push_back({p.x(), p.y()});
321 kd_tree_t tree(2, image_edges);
322 tree.index->buildIndex();
324 vector<std::pair<std::size_t, double>>
326 for (
const auto& e : model_edges_projected)
330 nanoflann::KNNResultSet<double> resultSet(1);
331 resultSet.init(&idx, &dist_sq);
332 tree.index->findNeighbors(resultSet, e.data(), nanoflann::SearchParams(10));
333 idx_d.push_back({idx, dist_sq});
340 vector<int> vertex_indices;
341 vector<Vector2f> image_points;
342 assert(occluding_vertices.size() == idx_d.size());
343 for (
int i = 0; i < occluding_vertices.size(); ++i)
345 const auto ortho_scale =
346 rendering_parameters.get_screen_width() /
347 rendering_parameters.get_frustum().r;
349 if (idx_d[i].second <= distance_threshold * ortho_scale)
353 const auto edge_point = image_edges[idx_d[i].first];
355 vertex_indices.push_back(occluding_vertices[i]);
356 image_points.push_back(edge_point);
359 return {image_points, vertex_indices};
Represents a set of estimated model parameters (rotation, translation) and camera parameters (viewing...
Definition: RenderingParameters.hpp:102
Eigen::Matrix4f get_modelview() const
Construct a model-view matrix from the RenderingParameters' rotation and translation,...
Definition: RenderingParameters.hpp:220
Eigen::Matrix4f get_projection() const
Construct an orthographic or perspective projection matrix from the RenderingParameters' frustum (ort...
Definition: RenderingParameters.hpp:245
std::enable_if< std::is_unsigned< T >::value, int >::type constexpr sign(T const x)
Returns the sign of the given number (-1, 0 or +1).
Definition: math.hpp:66
Eigen::Vector4f get_opencv_viewport(int width, int height)
Returns a glm/OpenGL compatible viewport vector that flips y and has the origin on the top-left,...
Definition: RenderingParameters.hpp:325
std::vector< int > occluding_boundary_vertices(const core::Mesh &mesh, const morphablemodel::EdgeTopology &edge_topology, Eigen::Matrix3f R, render::ProjectionType projection_type, bool perform_self_occlusion_check=true)
Computes the vertices that lie on occluding boundaries, given a particular pose.
Definition: closest_edge_fitting.hpp:60
std::pair< std::vector< Eigen::Vector2f >, std::vector< int > > find_occluding_edge_correspondences(const core::Mesh &mesh, const morphablemodel::EdgeTopology &edge_topology, const fitting::RenderingParameters &rendering_parameters, const std::vector< Eigen::Vector2f > &image_edges, float distance_threshold=64.0f, bool perform_self_occlusion_check=true)
For a given list of 2D edge points, find corresponding 3D vertex IDs.
Definition: closest_edge_fitting.hpp:278
bool is_vertex_visible(const Eigen::Vector3f &probe_vertex, const std::vector< Eigen::Vector3f > &mesh_vertices, const std::vector< std::array< int, 3 > > &mesh_triangle_vertex_indices, detail::RayDirection ray_direction_type)
Definition: vertex_visibility.hpp:52
Eigen::Vector3f compute_face_normal(const Eigen::Vector3f &v0, const Eigen::Vector3f &v1, const Eigen::Vector3f &v2)
Definition: normals.hpp:43
ProjectionType
Definition: ProjectionType.hpp:31
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
std::vector< std::array< int, 3 > > tvi
Triangle vertex indices.
Definition: Mesh.hpp:50
Definition: closest_edge_fitting.hpp:173
void query(const num_t *query_point, const size_t num_closest, IndexType *out_indices, num_t *out_distances_sq, const int nChecks_IGNORED=10) const
Definition: closest_edge_fitting.hpp:203
KDTreeVectorOfVectorsAdaptor(const int dimensionality, const VectorOfVectorsType &mat, const int leaf_max_size=10)
The kd-tree index for the user to call its methods as usual with any other FLANN index.
Definition: closest_edge_fitting.hpp:182
A struct containing a 3D shape model's edge topology.
Definition: EdgeTopology.hpp:54
std::vector< std::array< int, 2 > > adjacent_faces
num_edges x 2 matrix storing faces adjacent to each edge
Definition: EdgeTopology.hpp:56
std::vector< std::array< int, 2 > > adjacent_vertices
num_edges x 2 matrix storing vertices adjacent to each edge
Definition: EdgeTopology.hpp:58