Commit 00e0f8c1 authored by Patrik Huber's avatar Patrik Huber

Updated bfm-binary-to-cereal to use Eigen

Also removed division by 1000 of the mean. I don't think it makes sense to make this modification. Leave it as it is in the original.
parent 78f18db5
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
*/ */
#include "eos/morphablemodel/MorphableModel.hpp" #include "eos/morphablemodel/MorphableModel.hpp"
#include "opencv2/core/core.hpp" #include "Eigen/Core"
#include "boost/program_options.hpp" #include "boost/program_options.hpp"
#include "boost/filesystem.hpp" #include "boost/filesystem.hpp"
...@@ -35,11 +35,10 @@ namespace fs = boost::filesystem; ...@@ -35,11 +35,10 @@ namespace fs = boost::filesystem;
using std::cout; using std::cout;
using std::endl; using std::endl;
using std::vector; using std::vector;
using cv::Mat;
std::vector<cv::Vec2f> read_texcoords_from_obj(std::string obj_file) std::vector<std::array<double, 2>> read_texcoords_from_obj(std::string obj_file)
{ {
std::vector<cv::Vec2f> texcoords; std::vector<std::array<double, 2>> texcoords;
std::ifstream file(obj_file); std::ifstream file(obj_file);
if (!file.is_open()) { if (!file.is_open()) {
...@@ -55,7 +54,7 @@ std::vector<cv::Vec2f> read_texcoords_from_obj(std::string obj_file) ...@@ -55,7 +54,7 @@ std::vector<cv::Vec2f> read_texcoords_from_obj(std::string obj_file)
} }
std::stringstream lineStream(line); std::stringstream lineStream(line);
cv::Vec2f tc; std::array<double, 2> tc;
std::string throw_away; std::string throw_away;
if (!(lineStream >> throw_away >> tc[0] >> tc[1])) { if (!(lineStream >> throw_away >> tc[0] >> tc[1])) {
throw std::runtime_error(std::string("Texture coordinates format error while parsing the line: " + line)); throw std::runtime_error(std::string("Texture coordinates format error while parsing the line: " + line));
...@@ -99,7 +98,7 @@ int main(int argc, char *argv[]) ...@@ -99,7 +98,7 @@ int main(int argc, char *argv[])
catch (const po::error& e) { catch (const po::error& e) {
cout << "Error while parsing command-line arguments: " << e.what() << endl; cout << "Error while parsing command-line arguments: " << e.what() << endl;
cout << "Use --help to display a list of options." << endl; cout << "Use --help to display a list of options." << endl;
return EXIT_SUCCESS; return EXIT_FAILURE;
} }
std::ifstream file(bfm_file.string(), std::ios::binary); std::ifstream file(bfm_file.string(), std::ios::binary);
...@@ -109,7 +108,7 @@ int main(int argc, char *argv[]) ...@@ -109,7 +108,7 @@ int main(int argc, char *argv[])
} }
// We process the texcoords first, as reading the model takes longer // We process the texcoords first, as reading the model takes longer
std::vector<cv::Vec2f> texture_coordinates; std::vector<std::array<double, 2>> texture_coordinates;
if (!obj_file.empty()) if (!obj_file.empty())
{ {
texture_coordinates = read_texcoords_from_obj(obj_file.string()); texture_coordinates = read_texcoords_from_obj(obj_file.string());
...@@ -130,33 +129,34 @@ int main(int argc, char *argv[]) ...@@ -130,33 +129,34 @@ int main(int argc, char *argv[])
int num_shape_basis_vectors = 0; int num_shape_basis_vectors = 0;
file.read(reinterpret_cast<char*>(&num_shape_basis_vectors), 4); file.read(reinterpret_cast<char*>(&num_shape_basis_vectors), 4);
using Eigen::VectorXf;
using Eigen::MatrixXf;
// Read the mean: // Read the mean:
// We additionally divide each coordinate by 1000 to get from the domain VectorXf mean_shape(num_vertices * 3);
// of values in the BFM (e.g. -57000) to the BFM (values around e.g. -57).
Mat mean_shape(num_vertices * 3, 1, CV_32FC1);
for (int i = 0; i < num_vertices * 3; ++i) { for (int i = 0; i < num_vertices * 3; ++i) {
float value = 0.0f; float value = 0.0f;
file.read(reinterpret_cast<char*>(&value), 4); file.read(reinterpret_cast<char*>(&value), 4);
mean_shape.at<float>(i) = value / 1000.0f; mean_shape(i) = value;
} }
// Read the unnormalised shape basis matrix: // Read the unnormalised shape basis matrix:
Mat unnormalised_pca_basis_shape(num_vertices * 3, num_shape_basis_vectors, CV_32FC1); // m x n (rows x cols) = numShapeDims x numShapePcaCoeffs MatrixXf unnormalised_pca_basis_shape(num_vertices * 3, num_shape_basis_vectors); // m x n (rows x cols) = numShapeDims x numShapePcaCoeffs
std::cout << "Loading shape PCA basis matrix with " << unnormalised_pca_basis_shape.rows << " rows and " << unnormalised_pca_basis_shape.cols << " cols." << std::endl; std::cout << "Loading shape PCA basis matrix with " << unnormalised_pca_basis_shape.rows() << " rows and " << unnormalised_pca_basis_shape.cols() << " cols." << std::endl;
for (int col = 0; col < num_shape_basis_vectors; ++col) { for (int col = 0; col < num_shape_basis_vectors; ++col) {
for (int row = 0; row < num_vertices * 3; ++row) { for (int row = 0; row < num_vertices * 3; ++row) {
float value = 0.0f; float value = 0.0f;
file.read(reinterpret_cast<char*>(&value), 4); file.read(reinterpret_cast<char*>(&value), 4);
unnormalised_pca_basis_shape.at<float>(row, col) = value; unnormalised_pca_basis_shape(row, col) = value;
} }
} }
// Read the shape eigenvalues: // Read the shape eigenvalues:
Mat eigenvalues_shape(num_shape_basis_vectors, 1, CV_32FC1); VectorXf eigenvalues_shape(num_shape_basis_vectors);
for (int i = 0; i < num_shape_basis_vectors; ++i) { for (int i = 0; i < num_shape_basis_vectors; ++i) {
float value = 0.0f; float value = 0.0f;
file.read(reinterpret_cast<char*>(&value), 4); file.read(reinterpret_cast<char*>(&value), 4);
eigenvalues_shape.at<float>(i, 0) = value; eigenvalues_shape(i) = value;
} }
// Read number of triangles and then the triangle list: // Read number of triangles and then the triangle list:
...@@ -178,7 +178,7 @@ int main(int argc, char *argv[]) ...@@ -178,7 +178,7 @@ int main(int argc, char *argv[])
} }
// We read the unnormalised basis from the file. Now let's normalise it and store the normalised basis separately. // We read the unnormalised basis from the file. Now let's normalise it and store the normalised basis separately.
Mat normalised_pca_basis_shape = morphablemodel::normalise_pca_basis(unnormalised_pca_basis_shape, eigenvalues_shape); auto normalised_pca_basis_shape = morphablemodel::normalise_pca_basis(unnormalised_pca_basis_shape, eigenvalues_shape);
morphablemodel::PcaModel shape_model(mean_shape, normalised_pca_basis_shape, eigenvalues_shape, triangle_list); morphablemodel::PcaModel shape_model(mean_shape, normalised_pca_basis_shape, eigenvalues_shape, triangle_list);
// Reading the colour (albedo) model: // Reading the colour (albedo) model:
...@@ -198,42 +198,42 @@ int main(int argc, char *argv[]) ...@@ -198,42 +198,42 @@ int main(int argc, char *argv[])
// Read the mean: // Read the mean:
// We additionally divide each value by 255 to get from the domain // We additionally divide each value by 255 to get from the domain
// of values in the BFM ([0, 255]) to the BFM ([0, 1]). // of values in the BFM ([0, 255]) to the SFM ([0, 1]).
Mat mean_color(num_vertices_color * 3, 1, CV_32FC1); VectorXf mean_color(num_vertices_color * 3);
for (int i = 0; i < num_vertices_color * 3; ++i) { for (int i = 0; i < num_vertices_color * 3; ++i) {
float value = 0.0f; float value = 0.0f;
file.read(reinterpret_cast<char*>(&value), 4); file.read(reinterpret_cast<char*>(&value), 4);
mean_color.at<float>(i) = value / 255.0f; mean_color(i) = value / 255.0f;
} }
// Read the unnormalised colour basis matrix: // Read the unnormalised colour basis matrix:
Mat unnormalised_pca_basis_color(num_vertices_color * 3, num_color_basis_vectors, CV_32FC1); // m x n (rows x cols) = num_colour_dims x num_colour_bases MatrixXf unnormalised_pca_basis_color(num_vertices_color * 3, num_color_basis_vectors); // m x n (rows x cols) = num_colour_dims x num_colour_bases
std::cout << "Loading colour PCA basis matrix with " << unnormalised_pca_basis_color.rows << " rows and " << unnormalised_pca_basis_color.cols << " cols." << std::endl; std::cout << "Loading colour PCA basis matrix with " << unnormalised_pca_basis_color.rows() << " rows and " << unnormalised_pca_basis_color.cols() << " cols." << std::endl;
for (int col = 0; col < num_color_basis_vectors; ++col) { for (int col = 0; col < num_color_basis_vectors; ++col) {
for (int row = 0; row < num_vertices_color * 3; ++row) { for (int row = 0; row < num_vertices_color * 3; ++row) {
float value = 0.0f; float value = 0.0f;
file.read(reinterpret_cast<char*>(&value), 4); file.read(reinterpret_cast<char*>(&value), 4);
unnormalised_pca_basis_color.at<float>(row, col) = value; unnormalised_pca_basis_color(row, col) = value;
} }
} }
// Read the colour eigenvalues: // Read the colour eigenvalues:
Mat eigenvalues_color(num_color_basis_vectors, 1, CV_32FC1); VectorXf eigenvalues_color(num_color_basis_vectors);
for (int i = 0; i < num_color_basis_vectors; ++i) { for (int i = 0; i < num_color_basis_vectors; ++i) {
float value = 0.0f; float value = 0.0f;
file.read(reinterpret_cast<char*>(&value), 4); file.read(reinterpret_cast<char*>(&value), 4);
eigenvalues_color.at<float>(i, 0) = value; eigenvalues_color(i) = value;
} }
// We read the unnormalised basis from the file. Now let's normalise it and store the normalised basis separately. // We read the unnormalised basis from the file. Now let's normalise it and store the normalised basis separately.
Mat normalised_pca_basis_color = morphablemodel::normalise_pca_basis(unnormalised_pca_basis_color, eigenvalues_color); auto normalised_pca_basis_color = morphablemodel::normalise_pca_basis(unnormalised_pca_basis_color, eigenvalues_color);
morphablemodel::PcaModel color_model(mean_color, normalised_pca_basis_color, eigenvalues_color, triangle_list); morphablemodel::PcaModel color_model(mean_color, normalised_pca_basis_color, eigenvalues_color, triangle_list);
file.close(); file.close();
if (shape_model.get_data_dimension() / 3 != texture_coordinates.size()) if (shape_model.get_data_dimension() / 3 != texture_coordinates.size())
{ {
std::cout << "Warning: PCA shape model's data dimension is different from the number of texture coordinates given. The converted model is still saved, but most likely not work correctly for texturing." << std::endl; std::cout << "Warning: PCA shape model's data dimension is different from the number of texture coordinates given. The converted model is still saved, but does most likely not work correctly for texturing." << std::endl;
} }
morphablemodel::MorphableModel morphable_model(shape_model, color_model, texture_coordinates); morphablemodel::MorphableModel morphable_model(shape_model, color_model, texture_coordinates);
......
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