Skip to content

Commit

Permalink
Added (optional) landmark definitions to the MorphableModel class
Browse files Browse the repository at this point in the history
Also:
* Added the landmark definitions to the serialize() function, and incremented CEREAL_CLASS_VERSION to 3
* Updated the python binding's MorphableModel constructors.
  • Loading branch information
patrikhuber committed May 22, 2018
1 parent 91dd6a9 commit 8fcc2bf
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 9 deletions.
32 changes: 25 additions & 7 deletions include/eos/morphablemodel/MorphableModel.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "cereal/cereal.hpp"
#include "cereal/types/array.hpp"
#include "cereal/types/vector.hpp"
#include "cereal/types/unordered_map.hpp"
#include "eos/cpp17/optional_serialization.hpp"
#include "eos/cpp17/variant_serialization.hpp"
#include "eos/morphablemodel/io/eigen_cerealisation.hpp"
Expand All @@ -46,6 +47,8 @@
#include <vector>
#include <fstream>
#include <algorithm>
#include <string>
#include <unordered_map>
#include <cassert>
#include <stdexcept>

Expand Down Expand Up @@ -76,12 +79,15 @@ class MorphableModel
*
* @param[in] shape_model A PCA model over the shape.
* @param[in] color_model A PCA model over the colour (albedo).
* @param[in] landmark_definitions A set of landmark definitions, mapping from identifiers to vertex numbers.
* @param[in] texture_coordinates Optional texture coordinates for every vertex.
*/
MorphableModel(
PcaModel shape_model, PcaModel color_model,
cpp17::optional<std::unordered_map<std::string, int>> landmark_definitions = cpp17::nullopt,
std::vector<std::array<double, 2>> texture_coordinates = std::vector<std::array<double, 2>>())
: shape_model(shape_model), color_model(color_model), texture_coordinates(texture_coordinates){};
: shape_model(shape_model), color_model(color_model), landmark_definitions(landmark_definitions),
texture_coordinates(texture_coordinates){};

/**
* Create a Morphable Model from a shape and a colour PCA model, an expression PCA model or blendshapes,
Expand All @@ -90,12 +96,15 @@ class MorphableModel
* @param[in] shape_model A PCA model over the shape.
* @param[in] expression_model A PCA model over expressions, or a set of blendshapes.
* @param[in] color_model A PCA model over the colour (albedo).
* @param[in] landmark_definitions A set of landmark definitions, mapping from identifiers to vertex numbers.
* @param[in] texture_coordinates Optional texture coordinates for every vertex.
*/
MorphableModel(
PcaModel shape_model, ExpressionModel expression_model, PcaModel color_model,
cpp17::optional<std::unordered_map<std::string, int>> landmark_definitions = cpp17::nullopt,
std::vector<std::array<double, 2>> texture_coordinates = std::vector<std::array<double, 2>>())
: shape_model(shape_model), color_model(color_model), texture_coordinates(texture_coordinates)
: shape_model(shape_model), color_model(color_model), landmark_definitions(landmark_definitions),
texture_coordinates(texture_coordinates)
{
// Note: We may want to check/assert that the dimensions all match?
this->expression_model = expression_model;
Expand Down Expand Up @@ -406,8 +415,13 @@ class MorphableModel
private:
PcaModel shape_model; ///< A PCA model of the shape
PcaModel color_model; ///< A PCA model of vertex colour information
std::vector<std::array<double, 2>> texture_coordinates; ///< uv-coordinates for every vertex
cpp17::optional<ExpressionModel> expression_model; ///< Blendshapes or PcaModel
cpp17::optional<std::unordered_map<std::string, int>> landmark_definitions; ///< A set of landmark
///< definitions for the
///< model, mapping from
///< identifiers to vertex
///< numbers
std::vector<std::array<double, 2>> texture_coordinates; ///< uv-coordinates for every vertex

/**
* Returns whether the model has texture mapping coordinates, i.e.
Expand Down Expand Up @@ -439,10 +453,14 @@ class MorphableModel
if (version == 1)
{
archive(CEREAL_NVP(shape_model), CEREAL_NVP(color_model), CEREAL_NVP(texture_coordinates));
}
else
} else if (version == 2)
{
archive(CEREAL_NVP(shape_model), CEREAL_NVP(color_model), CEREAL_NVP(expression_model),
CEREAL_NVP(texture_coordinates));
} else
{
archive(CEREAL_NVP(shape_model), CEREAL_NVP(color_model), CEREAL_NVP(expression_model), CEREAL_NVP(texture_coordinates));
archive(CEREAL_NVP(shape_model), CEREAL_NVP(color_model), CEREAL_NVP(expression_model),
CEREAL_NVP(landmark_definitions), CEREAL_NVP(texture_coordinates));
}
};
};
Expand Down Expand Up @@ -563,6 +581,6 @@ inline core::Mesh sample_to_mesh(const Eigen::VectorXf& shape_instance, const Ei
} /* namespace morphablemodel */
} /* namespace eos */

CEREAL_CLASS_VERSION(eos::morphablemodel::MorphableModel, 2);
CEREAL_CLASS_VERSION(eos::morphablemodel::MorphableModel, 3);

#endif /* EOS_MORPHABLEMODEL_HPP */
4 changes: 2 additions & 2 deletions python/generate-python-bindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,8 @@ PYBIND11_MODULE(eos, eos_module)
.value("PcaModel", morphablemodel::MorphableModel::ExpressionModelType::PcaModel);

morphable_model
.def(py::init<morphablemodel::PcaModel, morphablemodel::PcaModel, std::vector<std::array<double, 2>>>(), "Create a Morphable Model from a shape and a colour PCA model, and optional texture coordinates.", py::arg("shape_model"), py::arg("color_model"), py::arg("texture_coordinates") = std::vector<std::array<double, 2>>())
.def(py::init<morphablemodel::PcaModel, morphablemodel::ExpressionModel, morphablemodel::PcaModel, std::vector<std::array<double, 2>>>(), "Create a Morphable Model from a shape and a colour PCA model, an expression PCA model or blendshapes, and optional texture coordinates.", py::arg("shape_model"), py::arg("expression_model"), py::arg("color_model"), py::arg("texture_coordinates") = std::vector<std::array<double, 2>>())
.def(py::init<morphablemodel::PcaModel, morphablemodel::PcaModel, cpp17::optional<std::unordered_map<std::string, int>>, std::vector<std::array<double, 2>>>(), "Create a Morphable Model from a shape and a colour PCA model, and optional texture coordinates.", py::arg("shape_model"), py::arg("color_model"), py::arg("landmark_definitions") = cpp17::nullopt, py::arg("texture_coordinates") = std::vector<std::array<double, 2>>())
.def(py::init<morphablemodel::PcaModel, morphablemodel::ExpressionModel, morphablemodel::PcaModel, cpp17::optional<std::unordered_map<std::string, int>>, std::vector<std::array<double, 2>>>(), "Create a Morphable Model from a shape and a colour PCA model, an expression PCA model or blendshapes, and optional texture coordinates.", py::arg("shape_model"), py::arg("expression_model"), py::arg("color_model"), py::arg("landmark_definitions") = cpp17::nullopt, py::arg("texture_coordinates") = std::vector<std::array<double, 2>>())
.def("get_shape_model", &morphablemodel::MorphableModel::get_shape_model, "Returns the PCA shape model of this Morphable Model.") // Not sure if that'll really be const in Python? I think Python does a copy each time this gets called?
.def("get_color_model", &morphablemodel::MorphableModel::get_color_model, "Returns the PCA colour (albedo) model of this Morphable Model.")
.def("get_expression_model", &morphablemodel::MorphableModel::get_expression_model, "Returns the shape expression model or an empty optional if the Morphable Model does not have a separate expression model.")
Expand Down

0 comments on commit 8fcc2bf

Please sign in to comment.