25 #include "eos/morphablemodel/MorphableModel.hpp" 27 #include "opencv2/core/core.hpp" 29 #include "boost/filesystem/path.hpp" 35 namespace morphablemodel {
38 std::vector<cv::Vec2f>
load_isomap(boost::filesystem::path isomap_file);
62 if (
sizeof(
unsigned int) != 4) {
63 std::cout <<
"Warning: We're reading 4 Bytes from the file but sizeof(unsigned int) != 4. Check the code/behaviour." << std::endl;
65 if (
sizeof(
double) != 8) {
66 std::cout <<
"Warning: We're reading 8 Bytes from the file but sizeof(double) != 8. Check the code/behaviour." << std::endl;
69 std::ifstream modelFile(model_filename.string(), std::ios::binary);
70 if (!modelFile.is_open()) {
71 std::string msg(
"Unable to open model file: " + model_filename.string());
72 std::cout << msg << std::endl;
73 throw std::runtime_error(msg);
78 unsigned int numVertices = 0;
79 unsigned int numTriangles = 0;
80 modelFile.read(reinterpret_cast<char*>(&numVertices), 4);
81 modelFile.read(reinterpret_cast<char*>(&numTriangles), 4);
84 std::vector<std::array<int, 3>> triangleList;
86 triangleList.resize(numTriangles);
87 unsigned int v0, v1, v2;
88 for (
unsigned int i = 0; i < numTriangles; ++i) {
90 modelFile.read(reinterpret_cast<char*>(&v0), 4);
91 modelFile.read(reinterpret_cast<char*>(&v1), 4);
92 modelFile.read(reinterpret_cast<char*>(&v2), 4);
93 triangleList[i][0] = v0;
94 triangleList[i][1] = v1;
95 triangleList[i][2] = v2;
99 unsigned int numShapePcaCoeffs = 0;
100 unsigned int numShapeDims = 0;
101 modelFile.read(reinterpret_cast<char*>(&numShapePcaCoeffs), 4);
102 modelFile.read(reinterpret_cast<char*>(&numShapeDims), 4);
104 if (3 * numVertices != numShapeDims) {
105 std::cout <<
"Warning: Number of shape dimensions is not equal to three times the number of vertices. Something will probably go wrong during the loading." << std::endl;
109 Mat unnormalisedPcaBasisShape(numShapeDims, numShapePcaCoeffs, CV_32FC1);
110 std::cout <<
"Loading shape PCA basis matrix with " << unnormalisedPcaBasisShape.rows <<
" rows and " << unnormalisedPcaBasisShape.cols <<
" cols." << std::endl;
111 for (
unsigned int col = 0; col < numShapePcaCoeffs; ++col) {
112 for (
unsigned int row = 0; row < numShapeDims; ++row) {
114 modelFile.read(reinterpret_cast<char*>(&var), 8);
115 unnormalisedPcaBasisShape.at<
float>(row, col) = static_cast<float>(var);
120 unsigned int numMean = 0;
121 modelFile.read(reinterpret_cast<char*>(&numMean), 4);
122 if (numMean != numShapeDims) {
123 std::cout <<
"Warning: Number of shape dimensions is not equal to the number of dimensions of the mean. Something will probably go wrong during the loading." << std::endl;
125 Mat meanShape(numMean, 1, CV_32FC1);
126 unsigned int counter = 0;
127 double vd0, vd1, vd2;
128 for (
unsigned int i = 0; i < numMean / 3; ++i) {
129 vd0 = vd1 = vd2 = 0.0;
130 modelFile.read(reinterpret_cast<char*>(&vd0), 8);
131 modelFile.read(reinterpret_cast<char*>(&vd1), 8);
132 modelFile.read(reinterpret_cast<char*>(&vd2), 8);
133 meanShape.at<
float>(counter, 0) = static_cast<float>(vd0);
135 meanShape.at<
float>(counter, 0) = static_cast<float>(vd1);
137 meanShape.at<
float>(counter, 0) = static_cast<float>(vd2);
142 unsigned int numEigenValsShape = 0;
143 modelFile.read(reinterpret_cast<char*>(&numEigenValsShape), 4);
144 if (numEigenValsShape != numShapePcaCoeffs) {
145 std::cout <<
"Warning: Number of coefficients in the PCA basis matrix is not equal to the number of eigenvalues. Something will probably go wrong during the loading." << std::endl;
147 Mat eigenvaluesShape(numEigenValsShape, 1, CV_32FC1);
148 for (
unsigned int i = 0; i < numEigenValsShape; ++i) {
150 modelFile.read(reinterpret_cast<char*>(&var), 8);
151 eigenvaluesShape.at<
float>(i, 0) = static_cast<float>(var);
155 Mat normalisedPcaBasisShape =
normalise_pca_basis(unnormalisedPcaBasisShape, eigenvaluesShape);
156 PcaModel shapeModel(meanShape, normalisedPcaBasisShape, eigenvaluesShape, triangleList);
160 unsigned int numTexturePcaCoeffs = 0;
161 unsigned int numTextureDims = 0;
162 modelFile.read(reinterpret_cast<char*>(&numTexturePcaCoeffs), 4);
163 modelFile.read(reinterpret_cast<char*>(&numTextureDims), 4);
165 Mat unnormalisedPcaBasisColor(numTextureDims, numTexturePcaCoeffs, CV_32FC1);
166 std::cout <<
"Loading color PCA basis matrix with " << unnormalisedPcaBasisColor.rows <<
" rows and " << unnormalisedPcaBasisColor.cols <<
" cols." << std::endl;
167 for (
unsigned int col = 0; col < numTexturePcaCoeffs; ++col) {
168 for (
unsigned int row = 0; row < numTextureDims; ++row) {
170 modelFile.read(reinterpret_cast<char*>(&var), 8);
171 unnormalisedPcaBasisColor.at<
float>(row, col) = static_cast<float>(var);
176 unsigned int numMeanColor = 0;
177 modelFile.read(reinterpret_cast<char*>(&numMeanColor), 4);
178 Mat meanColor(numMeanColor, 1, CV_32FC1);
180 for (
unsigned int i = 0; i < numMeanColor / 3; ++i) {
181 vd0 = vd1 = vd2 = 0.0;
182 modelFile.read(reinterpret_cast<char*>(&vd0), 8);
183 modelFile.read(reinterpret_cast<char*>(&vd1), 8);
184 modelFile.read(reinterpret_cast<char*>(&vd2), 8);
185 meanColor.at<
float>(counter, 0) = static_cast<float>(vd0);
187 meanColor.at<
float>(counter, 0) = static_cast<float>(vd1);
189 meanColor.at<
float>(counter, 0) = static_cast<float>(vd2);
194 unsigned int numEigenValsColor = 0;
195 modelFile.read(reinterpret_cast<char*>(&numEigenValsColor), 4);
196 Mat eigenvaluesColor(numEigenValsColor, 1, CV_32FC1);
197 for (
unsigned int i = 0; i < numEigenValsColor; ++i) {
199 modelFile.read(reinterpret_cast<char*>(&var), 8);
200 eigenvaluesColor.at<
float>(i, 0) = static_cast<float>(var);
204 Mat normalisedPcaBasisColor =
normalise_pca_basis(unnormalisedPcaBasisColor, eigenvaluesColor);
205 PcaModel colorModel(meanColor, normalisedPcaBasisColor, eigenvaluesColor, triangleList);
210 std::vector<cv::Vec2f> texCoords;
211 if (!isomap_file.empty()) {
214 std::string errorMessage(
"Error, wrong number of texture coordinates. Don't have the same number of texcoords than the shape model has vertices.");
215 std::cout << errorMessage << std::endl;
216 throw std::runtime_error(errorMessage);
231 std::vector<cv::Vec2f>
load_isomap(boost::filesystem::path isomapFile)
234 std::vector<float> xCoords, yCoords;
236 std::ifstream myfile(isomapFile.string());
237 if (!myfile.is_open()) {
238 string logMessage(
"The isomap file could not be opened. Did you specify a correct filename? " + isomapFile.string());
239 throw std::runtime_error(logMessage);
242 while (getline(myfile, line))
244 std::istringstream iss(line);
247 xCoords.push_back(std::stof(x));
248 yCoords.push_back(std::stof(y));
253 auto minMaxX = std::minmax_element(begin(xCoords), end(xCoords));
254 auto minMaxY = std::minmax_element(begin(yCoords), end(yCoords));
256 std::vector<cv::Vec2f> texCoords;
257 float divisorX = *minMaxX.second - *minMaxX.first;
258 float divisorY = *minMaxY.second - *minMaxY.first;
259 for (
int i = 0; i < xCoords.size(); ++i) {
260 texCoords.push_back(cv::Vec2f((xCoords[i] - *minMaxX.first) / divisorX, 1.0f - (yCoords[i] - *minMaxY.first) / divisorY));
This class represents a PCA-model that consists of:
Definition: PcaModel.hpp:55
int get_data_dimension() const
Definition: PcaModel.hpp:98
Namespace containing all of eos's 3D model fitting functionality.
MorphableModel load_scm_model(boost::filesystem::path model_filename, boost::filesystem::path isomap_file=boost::filesystem::path())
Definition: cvssp.hpp:59
cv::Mat normalise_pca_basis(cv::Mat unnormalised_basis, cv::Mat eigenvalues)
Definition: PcaModel.hpp:285
std::vector< cv::Vec2f > load_isomap(boost::filesystem::path isomap_file)
Definition: cvssp.hpp:231
A class representing a 3D Morphable Model, consisting of a shape- and colour (albedo) PCA model...
Definition: MorphableModel.hpp:54