Skip to content
This repository has been archived by the owner on Sep 25, 2023. It is now read-only.

minor fixes to make code compilable with Xcode #2

Open
wants to merge 1 commit into
base: ceres_nonlinear_refactor_no_rebase
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 49 additions & 72 deletions include/eos/fitting/ceres_nonlinear.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,56 @@ template<std::size_t N> using darray = std::array<double, N>;
namespace eos {
namespace fitting {

// Forward declarations:
/**
* Returns the 3D position of a single point of the 3D shape generated by the parameters given.
*
* @param[in] shape_model A PCA 3D shape model.
* @param[in] blendshapes A set of 3D blendshapes.
* @param[in] vertex_id Vertex id of the 3D model that should be projected.
* @param[in] shape_coeffs A set of PCA shape coefficients used to generate the point.
* @param[in] blendshape_coeffs A set of blendshape coefficients used to generate the point.
* @return The 3D point.
*/
template <typename T>
std::array<T, 3> get_shape_point(const morphablemodel::PcaModel& shape_model,
const morphablemodel::Blendshapes& blendshapes, int vertex_id,
const T* const shape_coeffs, const T* const blendshape_coeffs,
std::size_t num_coeffs_fitting);
std::size_t num_coeffs_fitting)
{
auto mean = shape_model.get_mean_at_point(vertex_id);
auto basis = shape_model.get_rescaled_pca_basis_at_point(vertex_id);
// Computing Shape = mean + basis * coeffs:
// Note: Could use an Eigen matrix with type T to see if it gives a speedup.
std::array<T, 3> point {static_cast<T>(mean[0]), static_cast<T>(mean[1]), static_cast<T>(mean[2])};
for (int i = 0; i < num_coeffs_fitting; ++i)
{
point[0] += static_cast<T>(basis.row(0).col(i)(0)) * shape_coeffs[i];
}
for (int i = 0; i < num_coeffs_fitting; ++i)
{
point[1] += static_cast<T>(basis.row(1).col(i)(0)) * shape_coeffs[i];
}
for (int i = 0; i < num_coeffs_fitting; ++i)
{
point[2] += static_cast<T>(basis.row(2).col(i)(0)) * shape_coeffs[i];
}
// Adding the blendshape offsets:
// Shape = mean + basis * coeffs + blendshapes * bs_coeffs:
auto num_blendshapes = blendshapes.size();
for (int i = 0; i < num_blendshapes; ++i)
{
point[0] += static_cast<T>(blendshapes[i].deformation(3 * vertex_id + 0)) * blendshape_coeffs[i];
}
for (int i = 0; i < num_blendshapes; ++i)
{
point[1] += static_cast<T>(blendshapes[i].deformation(3 * vertex_id + 1)) * blendshape_coeffs[i];
}
for (int i = 0; i < num_blendshapes; ++i)
{
point[2] += static_cast<T>(blendshapes[i].deformation(3 * vertex_id + 2)) * blendshape_coeffs[i];
}
return point;
};

template <typename T>
std::array<T, 3> get_vertex_colour(const morphablemodel::PcaModel& colour_model, int vertex_id,
Expand Down Expand Up @@ -383,58 +427,6 @@ struct ImageCost
const bool use_perspective;
};


/**
* Returns the 3D position of a single point of the 3D shape generated by the parameters given.
*
* @param[in] shape_model A PCA 3D shape model.
* @param[in] blendshapes A set of 3D blendshapes.
* @param[in] vertex_id Vertex id of the 3D model that should be projected.
* @param[in] shape_coeffs A set of PCA shape coefficients used to generate the point.
* @param[in] blendshape_coeffs A set of blendshape coefficients used to generate the point.
* @return The 3D point.
*/
template <typename T>
std::array<T, 3> get_shape_point(const morphablemodel::PcaModel& shape_model,
const morphablemodel::Blendshapes& blendshapes, int vertex_id,
const T* const shape_coeffs, const T* const blendshape_coeffs,
std::size_t num_coeffs_fitting)
{
auto mean = shape_model.get_mean_at_point(vertex_id);
auto basis = shape_model.get_rescaled_pca_basis_at_point(vertex_id);
// Computing Shape = mean + basis * coeffs:
// Note: Could use an Eigen matrix with type T to see if it gives a speedup.
std::array<T, 3> point {static_cast<T>(mean[0]), static_cast<T>(mean[1]), static_cast<T>(mean[2])};
for (int i = 0; i < num_coeffs_fitting; ++i)
{
point[0] += static_cast<T>(basis.row(0).col(i)(0)) * shape_coeffs[i];
}
for (int i = 0; i < num_coeffs_fitting; ++i)
{
point[1] += static_cast<T>(basis.row(1).col(i)(0)) * shape_coeffs[i];
}
for (int i = 0; i < num_coeffs_fitting; ++i)
{
point[2] += static_cast<T>(basis.row(2).col(i)(0)) * shape_coeffs[i];
}
// Adding the blendshape offsets:
// Shape = mean + basis * coeffs + blendshapes * bs_coeffs:
auto num_blendshapes = blendshapes.size();
for (int i = 0; i < num_blendshapes; ++i)
{
point[0] += static_cast<T>(blendshapes[i].deformation(3 * vertex_id + 0)) * blendshape_coeffs[i];
}
for (int i = 0; i < num_blendshapes; ++i)
{
point[1] += static_cast<T>(blendshapes[i].deformation(3 * vertex_id + 1)) * blendshape_coeffs[i];
}
for (int i = 0; i < num_blendshapes; ++i)
{
point[2] += static_cast<T>(blendshapes[i].deformation(3 * vertex_id + 2)) * blendshape_coeffs[i];
}
return point;
};

/**
* Returns the colour value of a single point of the 3D model generated by the parameters given.
*
Expand Down Expand Up @@ -469,21 +461,6 @@ std::array<T, 3> get_vertex_colour(const morphablemodel::PcaModel& color_model,

#endif /* EOS_CERES_USE_OPENCV */


ceres::Solver::Options get_default_solver_options() {
ceres::Solver::Options solver_options;
solver_options.linear_solver_type = ceres::ITERATIVE_SCHUR;
solver_options.num_threads = 8;
solver_options.num_linear_solver_threads = 8; // only SPARSE_SCHUR can use this
solver_options.minimizer_progress_to_stdout = true;
solver_options.max_num_iterations = 50;

return solver_options;
}

const auto default_solver_options = get_default_solver_options();


/*
* Parameters of camera
*
Expand Down Expand Up @@ -597,9 +574,9 @@ struct OrtogonalCameraParameters: CameraParameters<false>{
* @tparam color_coeffs_num number of color coefficients of model
* @tparam use_perspective will fitting use perspective projection
*/
template<std::size_t shapes_num, std::size_t blendshapes_num,
template<std::size_t shapes_num, std::size_t blendshapes_num
#if EOS_CERES_USE_OPENCV == true
std::size_t color_coeffs_num
, std::size_t color_coeffs_num
#endif
>
class ModelFitter {
Expand All @@ -618,7 +595,7 @@ class ModelFitter {
*
* @param[in] solver_options ceres solver options
*/
ceres::Solver::Summary solve(const ceres::Solver::Options& solver_options = default_solver_options) {
ceres::Solver::Summary solve(const ceres::Solver::Options& solver_options) {
// Fit position
ceres::Solver::Summary solver_summary;
ceres::Solve(solver_options, problem.get(), &solver_summary);
Expand Down