22#ifndef EOS_CERES_NONLINEAR_HPP
23#define EOS_CERES_NONLINEAR_HPP
25#include "eos/core/Image.hpp"
26#include "eos/morphablemodel/MorphableModel.hpp"
27#include "eos/morphablemodel/Blendshape.hpp"
28#include "eos/render/matrix_projection.hpp"
32#include "ceres/ceres.h"
33#include "ceres/cubic_interpolation.h"
44 Eigen::Map<
const Eigen::VectorX<T>> shape_coeffs,
45 Eigen::Map<
const Eigen::VectorX<T>> blendshape_coeffs);
49 Eigen::Map<
const Eigen::VectorX<T>> color_coeffs);
65 NormCost(
int num_parameters) : num_parameters(num_parameters){};
77 for (
int i = 0; i < num_parameters; ++i)
90 template <
int num_parameters>
93 return (
new ceres::AutoDiffCostFunction<
NormCost, num_parameters ,
128 const std::vector<morphablemodel::Blendshape>& blendshapes,
129 int num_shape_coeffs,
int num_blendshape_coeffs,
130 Eigen::Vector2f observed_landmark,
int vertex_id,
int image_width,
132 : shape_model(shape_model), blendshapes(blendshapes), num_shape_coeffs(num_shape_coeffs),
133 num_blendshape_coeffs(num_blendshape_coeffs), observed_landmark(observed_landmark),
134 vertex_id(vertex_id), image_width(image_width), image_height(image_height),
135 aspect_ratio(static_cast<double>(image_width) / image_height){};
151 template <
typename T>
152 bool operator()(
const T*
const camera_rotation,
const T*
const camera_translation,
153 const T*
const camera_intrinsics,
const T*
const shape_coeffs,
154 const T*
const blendshape_coeffs, T* residual)
const
157 Eigen::Map<const Eigen::VectorX<T>> shape_coeffs_mapped(shape_coeffs, num_shape_coeffs);
158 Eigen::Map<const Eigen::VectorX<T>> blendshape_coeffs_mapped(blendshape_coeffs,
159 num_blendshape_coeffs);
161 const Eigen::Vector3<T> point_3d =
get_shape_at_point(shape_model, blendshapes, vertex_id,
162 shape_coeffs_mapped, blendshape_coeffs_mapped);
167 Eigen::Map<const Eigen::Quaternion<T>> rotation(camera_rotation);
168 Eigen::Map<const Eigen::Vector3<T>> translation(camera_translation);
170 Eigen::Matrix4<T> model_view_mtx = Eigen::Matrix4<T>::Identity();
171 model_view_mtx.template block<3, 3>(0, 0) = rotation.toRotationMatrix();
172 model_view_mtx.col(3).template head<3>() = translation;
175 const Eigen::Vector4<T> viewport(T(0), T(image_height), T(image_width),
178 const T& fov = camera_intrinsics[0];
181 Eigen::Vector3<T> projected_point =
185 residual[0] = projected_point.x() - T(observed_landmark[0]);
186 residual[1] = projected_point.y() - T(observed_landmark[1]);
196 template <
int num_shape_coeffs,
int num_blendshape_coeffs>
199 Eigen::Vector2f observed_landmark,
int vertex_id,
int image_width,
205 num_shape_coeffs, num_blendshape_coeffs>(
207 num_blendshape_coeffs, observed_landmark, vertex_id,
208 image_width, image_height)));
214 const std::vector<morphablemodel::Blendshape>& blendshapes;
215 const int num_shape_coeffs;
216 const int num_blendshape_coeffs;
217 const Eigen::Vector2f observed_landmark;
219 const int image_width;
220 const int image_height;
221 const double aspect_ratio;
254 int num_blendshape_coeffs,
int num_color_coeffs,
int vertex_id,
256 : shape_model(shape_model), blendshapes(blendshapes), color_model(color_model),
257 num_shape_coeffs(num_shape_coeffs), num_blendshape_coeffs(num_blendshape_coeffs),
258 num_color_coeffs(num_color_coeffs), vertex_id(vertex_id), image(image){};
277 template <
typename T>
278 bool operator()(
const T*
const camera_rotation,
const T*
const camera_translation,
279 const T*
const camera_intrinsics,
const T*
const shape_coeffs,
280 const T*
const blendshape_coeffs,
const T*
const color_coeffs, T* residual)
const
285 Eigen::Map<const Eigen::VectorX<T>> shape_coeffs_mapped(shape_coeffs, num_shape_coeffs);
286 Eigen::Map<const Eigen::VectorX<T>> blendshape_coeffs_mapped(blendshape_coeffs,
287 num_blendshape_coeffs);
289 const Eigen::Vector3<T> point_3d =
get_shape_at_point(shape_model, blendshapes, vertex_id,
290 shape_coeffs_mapped, blendshape_coeffs_mapped);
295 Eigen::Map<const Eigen::Quaternion<T>> rotation(camera_rotation);
296 Eigen::Map<const Eigen::Vector3<T>> translation(camera_translation);
298 Eigen::Matrix4<T> model_view_mtx = Eigen::Matrix4<T>::Identity();
299 model_view_mtx.template block<3, 3>(0, 0) = rotation.toRotationMatrix();
300 model_view_mtx.col(3).template head<3>() = translation;
303 const Eigen::Vector4<T> viewport(T(0), T(image.height()), T(image.width()),
306 const T& fov = camera_intrinsics[0];
307 const double aspect_ratio =
static_cast<double>(image.width()) / image.height();
310 Eigen::Vector3<T> projected_point =
319 ceres::Grid2D<unsigned char, 3> grid(&image(0, 0).data()[0], 0, image.height(), 0, image.width());
320 ceres::BiCubicInterpolator<ceres::Grid2D<unsigned char, 3>> interpolator(grid);
321 T observed_colour[3];
322 interpolator.Evaluate(projected_point.y(), projected_point.x(), &observed_colour[0]);
325 Eigen::Map<const Eigen::VectorX<T>> color_coeffs_mapped(color_coeffs, num_color_coeffs);
331 residual[0] = model_color[0] * 255.0 - T(observed_colour[0]);
332 residual[1] = model_color[1] * 255.0 - T(observed_colour[1]);
333 residual[2] = model_color[2] * 255.0 - T(observed_colour[2]);
344 template <
int num_shape_coeffs,
int num_blendshape_coeffs,
int num_color_coeffs>
352 return (
new ceres::AutoDiffCostFunction<
VertexColorCost, 3, 4, 3, 1, num_shape_coeffs,
353 num_blendshape_coeffs, num_color_coeffs>(
354 new VertexColorCost(shape_model, blendshapes, color_model, num_shape_coeffs,
355 num_blendshape_coeffs, num_color_coeffs, vertex_id, image)));
363 const int num_shape_coeffs;
364 const int num_blendshape_coeffs;
365 const int num_color_coeffs;
383 Eigen::Map<
const Eigen::VectorX<T>> shape_coeffs,
384 Eigen::Map<
const Eigen::VectorX<T>> blendshape_coeffs)
391 .leftCols(shape_coeffs.size())
392 .template cast<T>() *
394 Eigen::Vector3<T> expression_vector(T(0.0), T(0.0), T(0.0));
395 for (std::size_t i = 0; i < blendshape_coeffs.size(); i++)
397 expression_vector.x() += T(blendshapes[i].deformation(vertex_id * 3 + 0)) * blendshape_coeffs(i);
398 expression_vector.y() += T(blendshapes[i].deformation(vertex_id * 3 + 1)) * blendshape_coeffs(i);
399 expression_vector.z() += T(blendshapes[i].deformation(vertex_id * 3 + 2)) * blendshape_coeffs(i);
402 return Eigen::Vector3<T>(mean.cast<T>() + shape_vector + expression_vector);
415 Eigen::Map<
const Eigen::VectorX<T>> color_coeffs)
421 .leftCols(color_coeffs.size())
422 .template cast<T>() *
425 return Eigen::Vector3<T>(mean.cast<T>() + color_vector);
Class to represent images.
Definition: Image.hpp:44
This class represents a PCA-model that consists of:
Definition: PcaModel.hpp:59
Eigen::Vector3f get_mean_at_point(int vertex_index) const
Definition: PcaModel.hpp:134
Eigen::MatrixXf get_rescaled_pca_basis_at_point(int vertex_id) const
Definition: PcaModel.hpp:223
Eigen::Vector3< T > get_shape_at_point(const eos::morphablemodel::PcaModel &shape_model, const eos::morphablemodel::Blendshapes &blendshapes, int vertex_id, Eigen::Map< const Eigen::VectorX< T > > shape_coeffs, Eigen::Map< const Eigen::VectorX< T > > blendshape_coeffs)
Definition: ceres_nonlinear.hpp:381
Eigen::Vector3< T > get_vertex_color_at_point(const eos::morphablemodel::PcaModel &color_model, int vertex_id, Eigen::Map< const Eigen::VectorX< T > > color_coeffs)
Definition: ceres_nonlinear.hpp:414
std::vector< Blendshape > Blendshapes
Definition: Blendshape.hpp:68
Eigen::Matrix4< T > perspective(T fov_y, T aspect, T z_near, T z_far)
Definition: matrix_projection.hpp:52
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.
Definition: ceres_nonlinear.hpp:58
static ceres::CostFunction * Create()
Definition: ceres_nonlinear.hpp:91
NormCost(int num_parameters)
Definition: ceres_nonlinear.hpp:65
bool operator()(const T *const x, T *residual) const
Definition: ceres_nonlinear.hpp:75
Definition: ceres_nonlinear.hpp:109
bool operator()(const T *const camera_rotation, const T *const camera_translation, const T *const camera_intrinsics, const T *const shape_coeffs, const T *const blendshape_coeffs, T *residual) const
Definition: ceres_nonlinear.hpp:152
PerspectiveProjectionLandmarkCost(const morphablemodel::PcaModel &shape_model, const std::vector< morphablemodel::Blendshape > &blendshapes, int num_shape_coeffs, int num_blendshape_coeffs, Eigen::Vector2f observed_landmark, int vertex_id, int image_width, int image_height)
Definition: ceres_nonlinear.hpp:127
static ceres::CostFunction * Create(const eos::morphablemodel::PcaModel &shape_model, const eos::morphablemodel::Blendshapes &blendshapes, Eigen::Vector2f observed_landmark, int vertex_id, int image_width, int image_height)
Definition: ceres_nonlinear.hpp:197
Definition: ceres_nonlinear.hpp:234
static ceres::CostFunction * Create(const eos::morphablemodel::PcaModel &shape_model, const eos::morphablemodel::Blendshapes &blendshapes, const eos::morphablemodel::PcaModel &color_model, int vertex_id, const eos::core::Image3u &image)
Definition: ceres_nonlinear.hpp:345
VertexColorCost(const eos::morphablemodel::PcaModel &shape_model, const eos::morphablemodel::Blendshapes &blendshapes, const eos::morphablemodel::PcaModel &color_model, int num_shape_coeffs, int num_blendshape_coeffs, int num_color_coeffs, int vertex_id, const eos::core::Image3u &image)
Definition: ceres_nonlinear.hpp:251
bool operator()(const T *const camera_rotation, const T *const camera_translation, const T *const camera_intrinsics, const T *const shape_coeffs, const T *const blendshape_coeffs, const T *const color_coeffs, T *residual) const
Definition: ceres_nonlinear.hpp:278