22#ifndef EOS_IO_CVSSP_HPP
23#define EOS_IO_CVSSP_HPP
25#include "eos/morphablemodel/MorphableModel.hpp"
26#include "eos/cpp17/optional.hpp"
38namespace morphablemodel {
41std::vector<std::array<double, 2>>
load_isomap(std::string isomap_file);
65 cpp17::optional<std::string> isomap_file = cpp17::nullopt)
67 using Eigen::MatrixXf;
68 using Eigen::VectorXf;
70 if (
sizeof(
unsigned int) != 4)
73 std::cout <<
"Warning: We're reading 4 Bytes from the file but sizeof(unsigned int) != 4. Check the "
77 if (
sizeof(
double) != 8)
79 std::cout <<
"Warning: We're reading 8 Bytes from the file but sizeof(double) != 8. Check the "
84 std::ifstream model_file(model_filename, std::ios::binary);
87 const std::string msg(
"Unable to open model file: " + model_filename);
88 std::cout << msg << std::endl;
89 throw std::runtime_error(msg);
94 unsigned int num_vertices = 0;
95 unsigned int num_triangles = 0;
96 model_file.read(
reinterpret_cast<char*
>(&num_vertices),
98 model_file.read(
reinterpret_cast<char*
>(&num_triangles), 4);
101 std::vector<std::array<int, 3>> triangle_list;
103 triangle_list.resize(num_triangles);
104 unsigned int v0, v1, v2;
105 for (
unsigned int i = 0; i < num_triangles; ++i)
108 model_file.read(
reinterpret_cast<char*
>(&v0), 4);
109 model_file.read(
reinterpret_cast<char*
>(&v1), 4);
110 model_file.read(
reinterpret_cast<char*
>(&v2), 4);
111 triangle_list[i][0] = v0;
112 triangle_list[i][1] = v1;
113 triangle_list[i][2] = v2;
117 unsigned int num_shape_pca_coeffs = 0;
118 unsigned int num_shape_dims = 0;
119 model_file.read(
reinterpret_cast<char*
>(&num_shape_pca_coeffs), 4);
120 model_file.read(
reinterpret_cast<char*
>(&num_shape_dims), 4);
122 if (3 * num_vertices != num_shape_dims)
124 std::cout <<
"Warning: Number of shape dimensions is not equal to three times the number of "
125 "vertices. Something will probably go wrong during the loading."
130 MatrixXf orthonormal_pca_basis_shape(
131 num_shape_dims, num_shape_pca_coeffs);
132 std::cout <<
"Loading shape PCA basis matrix with " << orthonormal_pca_basis_shape.rows() <<
" rows and "
133 << orthonormal_pca_basis_shape.cols() <<
" cols." << std::endl;
134 for (
unsigned int col = 0; col < num_shape_pca_coeffs; ++col)
136 for (
unsigned int row = 0; row < num_shape_dims; ++row)
139 model_file.read(
reinterpret_cast<char*
>(&var), 8);
140 orthonormal_pca_basis_shape(row, col) =
static_cast<float>(var);
145 unsigned int mean_dims = 0;
146 model_file.read(
reinterpret_cast<char*
>(&mean_dims), 4);
147 if (mean_dims != num_shape_dims)
149 std::cout <<
"Warning: Number of shape dimensions is not equal to the number of dimensions of the "
150 "mean. Something will probably go wrong during the loading."
153 VectorXf mean_shape(mean_dims);
154 unsigned int counter = 0;
155 double vd0, vd1, vd2;
156 for (
unsigned int i = 0; i < mean_dims / 3; ++i)
158 vd0 = vd1 = vd2 = 0.0;
159 model_file.read(
reinterpret_cast<char*
>(&vd0), 8);
160 model_file.read(
reinterpret_cast<char*
>(&vd1), 8);
161 model_file.read(
reinterpret_cast<char*
>(&vd2), 8);
162 mean_shape(counter) =
static_cast<float>(vd0);
164 mean_shape(counter) =
static_cast<float>(vd1);
166 mean_shape(counter) =
static_cast<float>(vd2);
171 unsigned int num_eigenvals_shape = 0;
172 model_file.read(
reinterpret_cast<char*
>(&num_eigenvals_shape), 4);
173 if (num_eigenvals_shape != num_shape_pca_coeffs)
175 std::cout <<
"Warning: Number of coefficients in the PCA basis matrix is not equal to the number of "
176 "eigenvalues. Something will probably go wrong during the loading."
179 VectorXf eigenvalues_shape(num_eigenvals_shape);
180 for (
unsigned int i = 0; i < num_eigenvals_shape; ++i)
183 model_file.read(
reinterpret_cast<char*
>(&var), 8);
184 eigenvalues_shape(i) =
static_cast<float>(var);
187 const PcaModel shape_model(mean_shape, orthonormal_pca_basis_shape, eigenvalues_shape, triangle_list);
191 unsigned int num_color_pca_coeffs = 0;
192 unsigned int num_color_dims = 0;
193 model_file.read(
reinterpret_cast<char*
>(&num_color_pca_coeffs), 4);
194 model_file.read(
reinterpret_cast<char*
>(&num_color_dims), 4);
196 MatrixXf orthonormal_pca_basis_color(num_color_dims, num_color_pca_coeffs);
197 std::cout <<
"Loading color PCA basis matrix with " << orthonormal_pca_basis_color.rows() <<
" rows and "
198 << orthonormal_pca_basis_color.cols() <<
" cols." << std::endl;
199 for (
unsigned int col = 0; col < num_color_pca_coeffs; ++col)
201 for (
unsigned int row = 0; row < num_color_dims; ++row)
204 model_file.read(
reinterpret_cast<char*
>(&var), 8);
205 orthonormal_pca_basis_color(row, col) =
static_cast<float>(var);
210 unsigned int color_mean_dims = 0;
211 model_file.read(
reinterpret_cast<char*
>(&color_mean_dims), 4);
212 VectorXf mean_color(color_mean_dims);
214 for (
unsigned int i = 0; i < color_mean_dims / 3; ++i)
216 vd0 = vd1 = vd2 = 0.0;
217 model_file.read(
reinterpret_cast<char*
>(&vd0),
219 model_file.read(
reinterpret_cast<char*
>(&vd1), 8);
220 model_file.read(
reinterpret_cast<char*
>(&vd2), 8);
221 mean_color(counter) =
static_cast<float>(vd0);
223 mean_color(counter) =
static_cast<float>(vd1);
225 mean_color(counter) =
static_cast<float>(vd2);
230 unsigned int num_eigenvals_color = 0;
231 model_file.read(
reinterpret_cast<char*
>(&num_eigenvals_color), 4);
232 VectorXf eigenvalues_color(num_eigenvals_color);
233 for (
unsigned int i = 0; i < num_eigenvals_color; ++i)
236 model_file.read(
reinterpret_cast<char*
>(&var), 8);
237 eigenvalues_color(i) =
static_cast<float>(var);
240 const PcaModel color_model(mean_color, orthonormal_pca_basis_color, eigenvalues_color, triangle_list);
245 std::vector<std::array<double, 2>> tex_coords;
251 const std::string error_msg(
"Error, wrong number of texture coordinates. Don't have the same "
252 "number of texcoords than the shape model has vertices.");
253 std::cout << error_msg << std::endl;
254 throw std::runtime_error(error_msg);
258 return MorphableModel(shape_model, color_model, cpp17::nullopt, tex_coords);
269inline std::vector<std::array<double, 2>>
load_isomap(std::string isomap_file)
272 std::vector<float> x_coords, y_coords;
274 std::ifstream file(isomap_file);
277 const string error_msg(
"The isomap file could not be opened. Did you specify a correct filename? " +
279 throw std::runtime_error(error_msg);
282 while (getline(file, line))
284 std::istringstream iss(line);
287 x_coords.push_back(std::stof(x));
288 y_coords.push_back(std::stof(y));
293 const auto min_max_x =
294 std::minmax_element(begin(x_coords), end(x_coords));
295 const auto min_max_y = std::minmax_element(begin(y_coords), end(y_coords));
297 std::vector<std::array<double, 2>> tex_coords;
298 const float divisor_x = *min_max_x.second - *min_max_x.first;
299 const float divisor_y = *min_max_y.second - *min_max_y.first;
300 for (
int i = 0; i < x_coords.size(); ++i)
302 tex_coords.push_back(std::array<double, 2>{
303 (x_coords[i] - *min_max_x.first) / divisor_x,
304 1.0f - (y_coords[i] - *min_max_y.first) /
A class representing a 3D Morphable Model, consisting of a shape- and colour (albedo) PCA model.
Definition: MorphableModel.hpp:73
This class represents a PCA-model that consists of:
Definition: PcaModel.hpp:59
int get_data_dimension() const
Definition: PcaModel.hpp:102
std::vector< std::array< double, 2 > > load_isomap(std::string isomap_file)
Definition: cvssp.hpp:269
MorphableModel load_scm_model(std::string model_filename, cpp17::optional< std::string > isomap_file=cpp17::nullopt)
Definition: cvssp.hpp:64
Namespace containing all of eos's 3D model fitting functionality.