Commit 4662c59c authored by Patrik Huber's avatar Patrik Huber

Changed PcaModel c'tor to take an orthonormal basis

Adjusted all files that use it (hopefully).

This is a breaking change: If you're currently using the PcaModel constructor and giving it a PCA basis matrix, your code will (probably silently) break: The function now expects an orthonormal basis matrix, whereas before, it expected a rescaled basis matrix. However it makes more sense for the function to take an orthonormal basis matrix.
parent f0c698b1
...@@ -66,13 +66,13 @@ public: ...@@ -66,13 +66,13 @@ public:
* be arranged. * be arranged.
* *
* @param[in] mean The mean used to build the PCA model. * @param[in] mean The mean used to build the PCA model.
* @param[in] pca_basis The PCA basis (eigenvectors), normalised (multiplied by the eigenvalues). * @param[in] orthonormal_pca_basis An orthonormal PCA basis (eigenvectors).
* @param[in] eigenvalues The eigenvalues used to build the PCA model. * @param[in] eigenvalues The eigenvalues used to build the PCA model.
* @param[in] triangle_list An index list of how to assemble the mesh. * @param[in] triangle_list An index list of how to assemble the mesh.
*/ */
PcaModel(Eigen::VectorXf mean, Eigen::MatrixXf pca_basis, Eigen::VectorXf eigenvalues, std::vector<std::array<int, 3>> triangle_list) : mean(mean), rescaled_pca_basis(pca_basis), eigenvalues(eigenvalues), triangle_list(triangle_list) PcaModel(Eigen::VectorXf mean, Eigen::MatrixXf orthonormal_pca_basis, Eigen::VectorXf eigenvalues, std::vector<std::array<int, 3>> triangle_list) : mean(mean), orthonormal_pca_basis(orthonormal_pca_basis), eigenvalues(eigenvalues), triangle_list(triangle_list)
{ {
orthonormal_pca_basis = normalise_pca_basis(rescaled_pca_basis, eigenvalues); rescaled_pca_basis = rescale_pca_basis(orthonormal_pca_basis, eigenvalues);
}; };
/** /**
......
...@@ -151,14 +151,12 @@ inline MorphableModel load_scm_model(boost::filesystem::path model_filename, boo ...@@ -151,14 +151,12 @@ inline MorphableModel load_scm_model(boost::filesystem::path model_filename, boo
eigenvalues_shape.at<float>(i, 0) = static_cast<float>(var); eigenvalues_shape.at<float>(i, 0) = static_cast<float>(var);
} }
// We read the unnormalised basis from the file. Now let's normalise it and store the normalised basis separately.
// Todo: We should change these to read into an Eigen matrix directly, and not into a cv::Mat first. // Todo: We should change these to read into an Eigen matrix directly, and not into a cv::Mat first.
using RowMajorMatrixXf = Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>; using RowMajorMatrixXf = Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>;
Eigen::Map<RowMajorMatrixXf> orthonormal_pca_basis_shape_(orthonormal_pca_basis_shape.ptr<float>(), orthonormal_pca_basis_shape.rows, orthonormal_pca_basis_shape.cols); Eigen::Map<RowMajorMatrixXf> orthonormal_pca_basis_shape_(orthonormal_pca_basis_shape.ptr<float>(), orthonormal_pca_basis_shape.rows, orthonormal_pca_basis_shape.cols);
Eigen::Map<RowMajorMatrixXf> eigenvalues_shape_(eigenvalues_shape.ptr<float>(), eigenvalues_shape.rows, eigenvalues_shape.cols); Eigen::Map<RowMajorMatrixXf> eigenvalues_shape_(eigenvalues_shape.ptr<float>(), eigenvalues_shape.rows, eigenvalues_shape.cols);
Eigen::Map<RowMajorMatrixXf> mean_shape_(mean_shape.ptr<float>(), mean_shape.rows, mean_shape.cols); Eigen::Map<RowMajorMatrixXf> mean_shape_(mean_shape.ptr<float>(), mean_shape.rows, mean_shape.cols);
Eigen::MatrixXf rescaled_pca_basis_shape_ = rescale_pca_basis(orthonormal_pca_basis_shape_, eigenvalues_shape_); PcaModel shape_model(mean_shape_, orthonormal_pca_basis_shape_, eigenvalues_shape_, triangle_list);
PcaModel shape_model(mean_shape_, rescaled_pca_basis_shape_, eigenvalues_shape_, triangle_list);
// Reading the color model // Reading the color model
// Read number of rows and columns of projection matrix // Read number of rows and columns of projection matrix
...@@ -205,12 +203,11 @@ inline MorphableModel load_scm_model(boost::filesystem::path model_filename, boo ...@@ -205,12 +203,11 @@ inline MorphableModel load_scm_model(boost::filesystem::path model_filename, boo
eigenvalues_color.at<float>(i, 0) = static_cast<float>(var); eigenvalues_color.at<float>(i, 0) = static_cast<float>(var);
} }
// We read the unnormalised basis from the file. Now let's normalise it and store the normalised basis separately. // Todo: We should change these to read into an Eigen matrix directly, and not into a cv::Mat first.
Eigen::Map<RowMajorMatrixXf> orthonormal_pca_basis_color_(orthonormal_pca_basis_color.ptr<float>(), orthonormal_pca_basis_color.rows, orthonormal_pca_basis_color.cols); Eigen::Map<RowMajorMatrixXf> orthonormal_pca_basis_color_(orthonormal_pca_basis_color.ptr<float>(), orthonormal_pca_basis_color.rows, orthonormal_pca_basis_color.cols);
Eigen::Map<RowMajorMatrixXf> eigenvalues_color_(eigenvalues_color.ptr<float>(), eigenvalues_color.rows, eigenvalues_color.cols); Eigen::Map<RowMajorMatrixXf> eigenvalues_color_(eigenvalues_color.ptr<float>(), eigenvalues_color.rows, eigenvalues_color.cols);
Eigen::Map<RowMajorMatrixXf> mean_color_(mean_color.ptr<float>(), mean_color.rows, mean_color.cols); Eigen::Map<RowMajorMatrixXf> mean_color_(mean_color.ptr<float>(), mean_color.rows, mean_color.cols);
Eigen::MatrixXf rescaled_pca_basis_color_ = rescale_pca_basis(orthonormal_pca_basis_color_, eigenvalues_color_); PcaModel color_model(mean_color_, orthonormal_pca_basis_color_, eigenvalues_color_, triangle_list);
PcaModel color_model(mean_color_, rescaled_pca_basis_color_, eigenvalues_color_, triangle_list);
model_file.close(); model_file.close();
......
...@@ -88,7 +88,7 @@ PYBIND11_PLUGIN(eos) { ...@@ -88,7 +88,7 @@ PYBIND11_PLUGIN(eos) {
py::class_<morphablemodel::PcaModel>(morphablemodel_module, "PcaModel", "Class representing a PcaModel with a mean, eigenvectors and eigenvalues, as well as a list of triangles to build a mesh.") py::class_<morphablemodel::PcaModel>(morphablemodel_module, "PcaModel", "Class representing a PcaModel with a mean, eigenvectors and eigenvalues, as well as a list of triangles to build a mesh.")
.def(py::init<>(), "Creates an empty model.") .def(py::init<>(), "Creates an empty model.")
.def(py::init<Eigen::VectorXf, Eigen::MatrixXf, Eigen::VectorXf, std::vector<std::array<int, 3>>>(), "Construct a PCA model from given mean, normalised PCA basis, eigenvalues and triangle list.", py::arg("mean"), py::arg("pca_basis"), py::arg("eigenvalues"), py::arg("triangle_list")) .def(py::init<Eigen::VectorXf, Eigen::MatrixXf, Eigen::VectorXf, std::vector<std::array<int, 3>>>(), "Construct a PCA model from given mean, orthonormal PCA basis, eigenvalues and triangle list.", py::arg("mean"), py::arg("orthonormal_pca_basis"), py::arg("eigenvalues"), py::arg("triangle_list"))
.def("get_num_principal_components", &morphablemodel::PcaModel::get_num_principal_components, "Returns the number of principal components in the model.") .def("get_num_principal_components", &morphablemodel::PcaModel::get_num_principal_components, "Returns the number of principal components in the model.")
.def("get_data_dimension", &morphablemodel::PcaModel::get_data_dimension, "Returns the dimension of the data, i.e. the number of shape dimensions.") .def("get_data_dimension", &morphablemodel::PcaModel::get_data_dimension, "Returns the dimension of the data, i.e. the number of shape dimensions.")
.def("get_triangle_list", &morphablemodel::PcaModel::get_triangle_list, "Returns a list of triangles on how to assemble the vertices into a mesh.") .def("get_triangle_list", &morphablemodel::PcaModel::get_triangle_list, "Returns a list of triangles on how to assemble the vertices into a mesh.")
......
...@@ -177,9 +177,7 @@ int main(int argc, char *argv[]) ...@@ -177,9 +177,7 @@ int main(int argc, char *argv[])
triangle_list[i][2] = v2 - 1; triangle_list[i][2] = v2 - 1;
} }
// We read the orthonormal basis from the file. Now let's rescale it and store the rescaled basis separately. morphablemodel::PcaModel shape_model(mean_shape, orthonormal_pca_basis_shape, eigenvalues_shape, triangle_list);
const auto rescaled_pca_basis_shape = morphablemodel::rescale_pca_basis(orthonormal_pca_basis_shape, eigenvalues_shape);
morphablemodel::PcaModel shape_model(mean_shape, rescaled_pca_basis_shape, eigenvalues_shape, triangle_list);
// Reading the colour (albedo) model: // Reading the colour (albedo) model:
int num_vertices_color = 0; int num_vertices_color = 0;
...@@ -225,9 +223,7 @@ int main(int argc, char *argv[]) ...@@ -225,9 +223,7 @@ int main(int argc, char *argv[])
eigenvalues_color(i) = value; eigenvalues_color(i) = value;
} }
// We read the orthonormal basis from the file. Now let's rescale it and store the rescaled basis separately. morphablemodel::PcaModel color_model(mean_color, orthonormal_pca_basis_color, eigenvalues_color, triangle_list);
const auto rescaled_pca_basis_color = morphablemodel::rescale_pca_basis(orthonormal_pca_basis_color, eigenvalues_color);
morphablemodel::PcaModel color_model(mean_color, rescaled_pca_basis_color, eigenvalues_color, triangle_list);
file.close(); file.close();
......
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