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 @@
*/
#include "eos/morphablemodel/MorphableModel.hpp"
#include "opencv2/core/core.hpp"
#include "Eigen/Core"
#include "boost/program_options.hpp"
#include "boost/filesystem.hpp"
......@@ -35,11 +35,10 @@ namespace fs = boost::filesystem;
using std::cout;
using std::endl;
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);
if (!file.is_open()) {
......@@ -55,7 +54,7 @@ std::vector<cv::Vec2f> read_texcoords_from_obj(std::string obj_file)
}
std::stringstream lineStream(line);
cv::Vec2f tc;
std::array<double, 2> tc;
std::string throw_away;
if (!(lineStream >> throw_away >> tc[0] >> tc[1])) {
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[])
catch (const po::error& e) {
cout << "Error while parsing command-line arguments: " << e.what() << 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);
......@@ -109,7 +108,7 @@ int main(int argc, char *argv[])
}
// 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())
{
texture_coordinates = read_texcoords_from_obj(obj_file.string());
......@@ -130,33 +129,34 @@ int main(int argc, char *argv[])
int num_shape_basis_vectors = 0;
file.read(reinterpret_cast<char*>(&num_shape_basis_vectors), 4);
using Eigen::VectorXf;
using Eigen::MatrixXf;
// Read the mean:
// We additionally divide each coordinate by 1000 to get from the domain
// 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);
VectorXf mean_shape(num_vertices * 3);
for (int i = 0; i < num_vertices * 3; ++i) {
float value = 0.0f;
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:
Mat unnormalised_pca_basis_shape(num_vertices * 3, num_shape_basis_vectors, CV_32FC1); // 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;
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;
for (int col = 0; col < num_shape_basis_vectors; ++col) {
for (int row = 0; row < num_vertices * 3; ++row) {
float value = 0.0f;
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:
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) {
float value = 0.0f;
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:
......@@ -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.
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);
// Reading the colour (albedo) model:
......@@ -198,42 +198,42 @@ int main(int argc, char *argv[])
// Read the mean:
// We additionally divide each value by 255 to get from the domain
// of values in the BFM ([0, 255]) to the BFM ([0, 1]).
Mat mean_color(num_vertices_color * 3, 1, CV_32FC1);
// of values in the BFM ([0, 255]) to the SFM ([0, 1]).
VectorXf mean_color(num_vertices_color * 3);
for (int i = 0; i < num_vertices_color * 3; ++i) {
float value = 0.0f;
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:
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
std::cout << "Loading colour PCA basis matrix with " << unnormalised_pca_basis_color.rows << " rows and " << unnormalised_pca_basis_color.cols << " cols." << std::endl;
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;
for (int col = 0; col < num_color_basis_vectors; ++col) {
for (int row = 0; row < num_vertices_color * 3; ++row) {
float value = 0.0f;
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:
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) {
float value = 0.0f;
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.
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);
file.close();
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);
......
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