Commit 58b54cf1 authored by Philipp Kopp's avatar Philipp Kopp

Merge branch 'devel' into multi_image_fit_devel

parents d34e1793 a143f1d7
cmake_minimum_required(VERSION 3.1.3)
project(eos)
set(eos_VERSION_MAJOR 0)
set(eos_VERSION_MINOR 11)
set(eos_VERSION_PATCH 0)
set(eos_VERSION_MINOR 12)
set(eos_VERSION_PATCH 1)
set(eos_VERSION ${eos_VERSION_MAJOR}.${eos_VERSION_MINOR}.${eos_VERSION_PATCH})
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
......
include README.md LICENSE
global-include CMakeLists.txt *.cmake
recursive-include 3rdparty/cereal-1.1.1/include *
recursive-include 3rdparty/cereal/include *
recursive-include 3rdparty/eigen/Eigen *
recursive-include 3rdparty/eigen3-nnls/src *.h
recursive-include 3rdparty/glm/glm *
recursive-include 3rdparty/nanoflann/include *
recursive-include 3rdparty/pybind11 *
recursive-include cmake *
recursive-include include *
recursive-include python *
......@@ -32,9 +32,10 @@ At the moment, it mainly provides the following functionality:
To use the library in your own project, just add the following directories to your include path:
* `eos/include`
* `eos/3rdparty/cereal-1.1.1/include`
* `eos/3rdparty/cereal/include`
* `eos/3rdparty/glm`
* `eos/3rdparty/nanoflann/include`
* `eos/3rdparty/eigen/Eigen`
* `eos/3rdparty/eigen3-nnls/src`
**Make sure to clone with `--recursive` to download the required submodules!**
......@@ -84,9 +85,10 @@ The full model is available at [http://www.cvssp.org/facemodel](http://www.cvssp
## Python bindings
eos includes python bindings for some of its functionality (and more can be added!). Set `-DEOS_GENERATE_PYTHON_BINDINGS=on` when running `cmake` to build them (and optionally set `PYTHON_EXECUTABLE` to point to your python interpreter if it's not found automatically).
eos includes python bindings for some of its functionality (and more can be added!). An experimental package is on PyPI: Try `pip install eos-py`. You will still need the data files from this repository.
In case of issues, build the bindings manually: Clone the repository and set `-DEOS_GENERATE_PYTHON_BINDINGS=on` when running `cmake` (and optionally set `PYTHON_EXECUTABLE` to point to your python interpreter if it's not found automatically).
After building the bindings, they can be used like any python module:
After having obtained the bindings, they can be used like any python module:
```
import eos
......
......@@ -380,7 +380,7 @@ int main(int argc, char *argv[])
// Colour model fitting (this needs a Morphable Model with colour (albedo) model, see note above main()):
if (!morphable_model.has_color_model())
{
cout << "The MorphableModel used does not contain a colour (albedo) model. ImageCost requires a model that contains a colour PCA model. You may want to use the full Surrey Face Model or remove this section.";
cout << "Error: The MorphableModel used does not contain a colour (albedo) model. ImageCost requires a model that contains a colour PCA model. You may want to use the full Surrey Face Model or remove this section.";
return EXIT_FAILURE;
}
std::vector<double> colour_coefficients;
......
This diff is collapsed.
......@@ -538,7 +538,7 @@ inline std::pair<core::Mesh, fitting::RenderingParameters> fit_shape_and_pose(co
* @param[in] lambda Regularisation parameter of the PCA shape fitting.
* @return The fitted model shape instance and the final pose.
*/
inline std::pair<core::Mesh, fitting::RenderingParameters> fit_shape_and_pose(const morphablemodel::MorphableModel& morphable_model, const std::vector<morphablemodel::Blendshape>& blendshapes, const core::LandmarkCollection<cv::Vec2f>& landmarks, const core::LandmarkMapper& landmark_mapper, int image_width, int image_height, const morphablemodel::EdgeTopology& edge_topology, const fitting::ContourLandmarks& contour_landmarks, const fitting::ModelContour& model_contour, int num_iterations = 5, boost::optional<int> num_shape_coefficients_to_fit = boost::none, float lambda = 30.0f)
inline std::pair<core::Mesh, fitting::RenderingParameters> fit_shape_and_pose(const morphablemodel::MorphableModel& morphable_model, const std::vector<morphablemodel::Blendshape>& blendshapes, const core::LandmarkCollection<cv::Vec2f>& landmarks, const core::LandmarkMapper& landmark_mapper, int image_width, int image_height, const morphablemodel::EdgeTopology& edge_topology, const fitting::ContourLandmarks& contour_landmarks, const fitting::ModelContour& model_contour, int num_iterations = 5, boost::optional<int> num_shape_coefficients_to_fit = boost::none, float lambda = 50.0f)
{
std::vector<float> pca_coeffs;
std::vector<float> blendshape_coeffs;
......
......@@ -102,6 +102,20 @@ inline Eigen::MatrixXf to_matrix(const std::vector<Blendshape>& blendshapes)
return blendshapes_as_basis;
};
/**
* @brief Maps an std::vector of coefficients with Eigen::Map, so it can be multiplied
* with a blendshapes matrix.
*
* Note that the resulting Eigen::Map only lives as long as the data given lives and is in scope.
*
* @param[in] coefficients Vector of blendshape coefficients.
* @return An Eigen::Map pointing to the given coefficients data.
*/
inline Eigen::Map<const Eigen::VectorXf> to_vector(const std::vector<float>& coefficients)
{
return Eigen::Map<const Eigen::VectorXf>(coefficients.data(), coefficients.size());
};
} /* namespace morphablemodel */
} /* namespace eos */
......
......@@ -33,7 +33,7 @@ end
% We'll use default values to the following arguments, if they're not
% provided:
if (~exist('edge_topology', 'var')), edge_topology = '../share/sfm_3448_edge_topology.json'; end
if (~exist('contour_landmarks', 'var')), contour_landmarks = '../share/ibug2did.txt'; end
if (~exist('contour_landmarks', 'var')), contour_landmarks = '../share/ibug_to_sfm.txt'; end
if (~exist('model_contour', 'var')), model_contour = '../share/model_contours.json'; end
if (~exist('num_iterations', 'var')), num_iterations = 5; end
if (~exist('num_shape_coefficients_to_fit', 'var')), num_shape_coefficients_to_fit = -1; end
......
......@@ -3,7 +3,7 @@
%% Set up some required paths to files:
model_file = '../share/sfm_shape_3448.bin';
blendshapes_file = '../share/expression_blendshapes_3448.bin';
landmark_mappings = '../share/ibug2did.txt';
landmark_mappings = '../share/ibug_to_sfm.txt';
%% Load an image and its landmarks in ibug format:
image = imread('../bin/data/image_0010.png');
......
......@@ -10,9 +10,9 @@ def main():
model = eos.morphablemodel.load_model("../share/sfm_shape_3448.bin")
blendshapes = eos.morphablemodel.load_blendshapes("../share/expression_blendshapes_3448.bin")
landmark_mapper = eos.core.LandmarkMapper('../share/ibug2did.txt')
landmark_mapper = eos.core.LandmarkMapper('../share/ibug_to_sfm.txt')
edge_topology = eos.morphablemodel.load_edge_topology('../share/sfm_3448_edge_topology.json')
contour_landmarks = eos.fitting.ContourLandmarks.load('../share/ibug2did.txt')
contour_landmarks = eos.fitting.ContourLandmarks.load('../share/ibug_to_sfm.txt')
model_contour = eos.fitting.ModelContour.load('../share/model_contours.json')
(mesh, pose, shape_coeffs, blendshape_coeffs) = eos.fitting.fit_shape_and_pose(model, blendshapes,
......
......@@ -105,6 +105,8 @@ PYBIND11_PLUGIN(eos) {
.def("get_shape_model", [](const morphablemodel::MorphableModel& m) { return m.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", [](const morphablemodel::MorphableModel& m) { return m.get_color_model(); }, "Returns the PCA colour (albedo) model of this Morphable Model.") // (continued from above:) We may want to use py::overload, but in any case, we need to tell pybind11 if it should use the const or non-const overload.
.def("get_mean", &morphablemodel::MorphableModel::get_mean, "Returns the mean of the shape- and colour model as a Mesh.")
.def("draw_sample", (core::Mesh(morphablemodel::MorphableModel::*)(std::vector<float>, std::vector<float>) const)&morphablemodel::MorphableModel::draw_sample, "Returns a sample from the model with the given shape- and colour PCA coefficients.", py::arg("shape_coefficients"), py::arg("color_coefficients"))
.def("has_color_model", &morphablemodel::MorphableModel::has_color_model, "Returns true if this Morphable Model contains a colour model, and false if it is a shape-only model.")
;
morphablemodel_module.def("load_model", &morphablemodel::load_model, "Load a Morphable Model from a cereal::BinaryInputArchive (.bin) from the harddisk.", py::arg("filename"));
......
......@@ -88,7 +88,7 @@ class CMakeBuild(build_ext):
setup(
name='eos-py',
version='0.11.0',
version='0.12.1',
author='Patrik Huber',
author_email='patrikhuber@gmail.com',
description='Python bindings for eos - A lightweight 3D Morphable Face Model fitting library in modern C++11/14',
......
......@@ -10,7 +10,7 @@ Files in this directory:
- sfm_shape_3448.bin:
The public shape-only Surrey 3D Morphable Face Model.
To obtain a full 3DMM and higher resolution levels, follow the instructions
at <todo: add link to the page of the Uni>.
at cvssp.org/facemodel.
Details about the different models can be found in:
"A Multiresolution 3D Morphable Face Model and Fitting Framework",
P. Huber, G. Hu, R. Tena, P. Mortazavian, W. Koppen, W. Christmas, M. Rätsch, J. Kittler,
......@@ -22,7 +22,9 @@ Files in this directory:
- sfm_3448_edge_topology.json:
Contains a precomputed list of the model's edges, and the two faces and vertices that are
adjacent to each edge. Used in the edge-fitting.
adjacent to each edge. Uses 1-based indexing ("0" has a special meaning of "no adjacent
vertex/edge") - this may change to 0-based in the future to be consistent with the rest of
the library. The file is used in the edge-fitting.
- model_contours.json:
Definition of the model's contour vertices of the right and left side of the face.
......
......@@ -28,13 +28,11 @@ target_link_libraries(scm-to-cereal eos ${OpenCV_LIBS} ${Boost_LIBRARIES})
add_executable(bfm-binary-to-cereal bfm-binary-to-cereal.cpp)
target_link_libraries(bfm-binary-to-cereal eos ${OpenCV_LIBS} ${Boost_LIBRARIES})
# Reads an edgestruct CSV file created from Matlab, and converts it to json:
add_executable(edgestruct-csv-to-json edgestruct-csv-to-json.cpp)
target_link_libraries(edgestruct-csv-to-json eos ${Boost_LIBRARIES})
# install target:
# Install targets:
install(TARGETS scm-to-cereal DESTINATION bin)
install(TARGETS bfm-binary-to-cereal DESTINATION bin)
install(TARGETS edgestruct-csv-to-json DESTINATION bin)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment