Add PLY file logger before and after BA in order to ease visual comparison.
Change-Id: Ib14e8f4b2de686ab6494de270458392f81a0b946
diff --git a/examples/bal_problem.cc b/examples/bal_problem.cc
index 46fba4f..fa1d82a 100644
--- a/examples/bal_problem.cc
+++ b/examples/bal_problem.cc
@@ -32,6 +32,7 @@
#include <cstdio>
#include <cstdlib>
+#include <fstream>
#include <string>
#include <vector>
#include "Eigen/Core"
@@ -176,9 +177,46 @@
fclose(fptr);
}
+// Write the problem to a PLY file for inspection in Matlab or CloudCompare.
+void BALProblem::WriteToPLYFile(const std::string& filename) const {
+ std::ofstream of(filename.c_str());
+
+ of << "ply"
+ << '\n' << "format ascii 1.0"
+ << '\n' << "element vertex " << num_cameras_ + num_points_
+ << '\n' << "property float x"
+ << '\n' << "property float y"
+ << '\n' << "property float z"
+ << '\n' << "property uchar red"
+ << '\n' << "property uchar green"
+ << '\n' << "property uchar blue"
+ << '\n' << "end_header" << std::endl;
+
+ // Export extrinsic data (i.e. camera centers) as green points.
+ double angle_axis[3];
+ double center[3];
+ for (int i = 0; i < num_cameras(); ++i) {
+ const double* camera = cameras() + camera_block_size() * i;
+ CameraToAngleAxisAndCenter(camera, angle_axis, center);
+ of << center[0] << ' ' << center[1] << ' ' << center[2]
+ << " 0 255 0" << '\n';
+ }
+
+ // Export the structure (i.e. 3D Points) as white points.
+ const double* points = parameters_ + camera_block_size() * num_cameras_;
+ for (int i = 0; i < num_points(); ++i) {
+ const double* point = points + i * point_block_size();
+ for (int j = 0; j < point_block_size(); ++j) {
+ of << point[j] << ' ';
+ }
+ of << "255 255 255\n";
+ }
+ of.close();
+}
+
void BALProblem::CameraToAngleAxisAndCenter(const double* camera,
double* angle_axis,
- double* center) {
+ double* center) const {
VectorRef angle_axis_ref(angle_axis, 3);
if (use_quaternions_) {
QuaternionToAngleAxis(camera, angle_axis);
@@ -196,7 +234,7 @@
void BALProblem::AngleAxisAndCenterToCamera(const double* angle_axis,
const double* center,
- double* camera) {
+ double* camera) const {
ConstVectorRef angle_axis_ref(angle_axis, 3);
if (use_quaternions_) {
AngleAxisToQuaternion(angle_axis, camera);
diff --git a/examples/bal_problem.h b/examples/bal_problem.h
index d3b2aff..e9a348e 100644
--- a/examples/bal_problem.h
+++ b/examples/bal_problem.h
@@ -48,6 +48,7 @@
~BALProblem();
void WriteToFile(const std::string& filename) const;
+ void WriteToPLYFile(const std::string& filename) const;
// Move the "center" of the reconstruction to the origin, where the
// center is determined by computing the marginal median of the
@@ -74,6 +75,7 @@
const int* camera_index() const { return camera_index_; }
const double* observations() const { return observations_; }
const double* parameters() const { return parameters_; }
+ const double* cameras() const { return parameters_; }
double* mutable_cameras() { return parameters_; }
double* mutable_points() {
return parameters_ + camera_block_size() * num_cameras_;
@@ -82,11 +84,11 @@
private:
void CameraToAngleAxisAndCenter(const double* camera,
double* angle_axis,
- double* center);
+ double* center) const;
void AngleAxisAndCenterToCamera(const double* angle_axis,
const double* center,
- double* camera);
+ double* camera) const;
int num_cameras_;
int num_points_;
int num_observations_;
diff --git a/examples/bundle_adjuster.cc b/examples/bundle_adjuster.cc
index 495094b..e64fdb5 100644
--- a/examples/bundle_adjuster.cc
+++ b/examples/bundle_adjuster.cc
@@ -120,6 +120,9 @@
"the pertubations.");
DEFINE_bool(line_search, false, "Use a line search instead of trust region "
"algorithm.");
+DEFINE_string(initial_ply, "", "Export the BAL file data as a PLY file.");
+DEFINE_string(final_ply, "", "Export the refined BAL file data as a PLY "
+ "file.");
namespace ceres {
namespace examples {
@@ -311,6 +314,11 @@
void SolveProblem(const char* filename) {
BALProblem bal_problem(filename, FLAGS_use_quaternions);
+
+ if (!FLAGS_initial_ply.empty()) {
+ bal_problem.WriteToPLYFile(FLAGS_initial_ply);
+ }
+
Problem problem;
srand(FLAGS_random_seed);
@@ -327,6 +335,10 @@
Solver::Summary summary;
Solve(options, &problem, &summary);
std::cout << summary.FullReport() << "\n";
+
+ if (!FLAGS_final_ply.empty()) {
+ bal_problem.WriteToPLYFile(FLAGS_final_ply);
+ }
}
} // namespace examples