use of boofcv.abst.geo.bundle.ScaleSceneStructure in project BoofCV by lessthanoptimal.
the class ExampleBundleAdjustment method main.
public static void main(String[] args) throws IOException {
// Because the Bundle Adjustment in the Large data set is popular, a file reader and writer is included
// with BoofCV. BoofCV uses two data types to describe the parameters in a bundle adjustment problem
// BundleAdjustmentSceneStructure is used for camera parameters, camera locations, and 3D points
// BundleAdjustmentObservations for image observations of 3D points
// ExampleMultiViewSceneReconstruction gives a better feel for these data structures or you can look
// at the source code of CodecBundleAdjustmentInTheLarge
var parser = new CodecBundleAdjustmentInTheLarge();
parser.parse(new File(UtilIO.pathExample("sfm/problem-16-22106-pre.txt")));
// Print information which gives you an idea of the problem's scale
System.out.println("Optimizing " + parser.scene.getParameterCount() + " parameters with " + parser.observations.getObservationCount() + " observations\n\n");
// Configure the sparse Levenberg-Marquardt solver
var configLM = new ConfigLevenbergMarquardt();
// Important tuning parameter. Won't converge to a good solution if picked improperly. Small changes
// to this problem and speed up or slow down convergence and change the final result. This is true for
// basically all solvers.
configLM.dampeningInitial = 1e-3;
// Improves Jacobian matrix's condition. Recommended in general but not important in this problem
configLM.hessianScaling = true;
var configSBA = new ConfigBundleAdjustment();
configSBA.configOptimizer = configLM;
// Create and configure the bundle adjustment solver
BundleAdjustment<SceneStructureMetric> bundleAdjustment = FactoryMultiView.bundleSparseMetric(configSBA);
// prints out useful debugging information that lets you know how well it's converging
bundleAdjustment.setVerbose(System.out, null);
// Specifies convergence criteria
bundleAdjustment.configure(1e-6, 1e-6, 50);
// Scaling each variable type so that it takes on a similar numerical value. This aids in optimization
// Not important for this problem but is for others
var bundleScale = new ScaleSceneStructure();
bundleScale.applyScale(parser.scene, parser.observations);
bundleAdjustment.setParameters(parser.scene, parser.observations);
// Runs the solver. This will take a few minutes. 7 iterations takes about 3 minutes on my computer
long startTime = System.currentTimeMillis();
double errorBefore = bundleAdjustment.getFitScore();
if (!bundleAdjustment.optimize(parser.scene)) {
throw new RuntimeException("Bundle adjustment failed?!?");
}
// Print out how much it improved the model
System.out.println();
System.out.printf("Error reduced by %.1f%%\n", (100.0 * (errorBefore / bundleAdjustment.getFitScore() - 1.0)));
System.out.println(BoofMiscOps.milliToHuman(System.currentTimeMillis() - startTime));
// Return parameters to their original scaling. Can probably skip this step.
bundleScale.undoScale(parser.scene, parser.observations);
// Visualize the results using a point cloud viewer
visualizeInPointCloud(parser.scene);
}
Aggregations