boofcv.alg.geo.bundle.BundleAdjustmentMetricResidualFunction Maven / Gradle / Ivy
/*
* Copyright (c) 2011-2018, Peter Abeles. All Rights Reserved.
*
* This file is part of BoofCV (http://boofcv.org).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package boofcv.alg.geo.bundle;
import boofcv.abst.geo.bundle.BundleAdjustmentSchur_DSCC;
import boofcv.abst.geo.bundle.SceneObservations;
import boofcv.abst.geo.bundle.SceneStructureMetric;
import boofcv.struct.geo.PointIndex2D_F64;
import georegression.struct.point.Point2D_F64;
import georegression.struct.point.Point3D_F64;
import georegression.transform.se.SePointOps_F64;
/**
*
* Computes observations errors/residuals for metric bundle adjustment as implemented using
* {@link org.ddogleg.optimization.UnconstrainedLeastSquares}. Parameterization is done using
* the format in {@link CodecSceneStructureMetric}.
*
*
*
* cost(P) = (1/(m*n))*∑i ∑j ||xj - (1/z)*[Ri|Ti]*Xj||2
*
*
* @see SceneStructureMetric
* @see SceneObservations
*
* @author Peter Abeles
*/
public class BundleAdjustmentMetricResidualFunction
implements BundleAdjustmentSchur_DSCC.FunctionResiduals
{
private SceneStructureMetric structure;
private SceneObservations observations;
// feature location in world coordinates
private Point3D_F64 worldPt = new Point3D_F64();
// number of parameters being optimised
private int numParameters;
// number of observations. 2 for each point in each view
private int numObservations;
// local variable which stores the predicted location of the feature in the camera frame
private Point3D_F64 cameraPt = new Point3D_F64();
// Storage for rendered output
private Point2D_F64 predictedPixel = new Point2D_F64();
private PointIndex2D_F64 observedPixel = new PointIndex2D_F64();
// Used to write the "unknown" paramters into the scene
CodecSceneStructureMetric codec = new CodecSceneStructureMetric();
Point3D_F64 p3 = new Point3D_F64();
/**
* Specifies the scenes structure and observed feature locations
*/
@Override
public void configure(SceneStructureMetric structure ,
SceneObservations observations )
{
this.structure = structure;
this.observations = observations;
numObservations = observations.getObservationCount();
numParameters = structure.getParameterCount();
}
@Override
public int getNumOfInputsN() {
return numParameters;
}
@Override
public int getNumOfOutputsM() {
return numObservations*2;
}
@Override
public void process(double[] input, double[] output) {
// write the current parameters into the scene's structure
codec.decode(input,structure);
int observationIndex = 0;
for( int viewIndex = 0; viewIndex < structure.views.length; viewIndex++ ) {
SceneStructureMetric.View view = structure.views[viewIndex];
SceneStructureMetric.Camera camera = structure.cameras[view.camera];
SceneObservations.View obsView = observations.views[viewIndex];
for (int i = 0; i < obsView.size(); i++) {
obsView.get(i,observedPixel);
SceneStructureMetric.Point worldPt = structure.points[observedPixel.index];
worldPt.get(p3);
SePointOps_F64.transform(view.worldToView,p3,cameraPt);
camera.model.project(cameraPt.x,cameraPt.y,cameraPt.z, predictedPixel);
int outputIndex = observationIndex*2;
output[outputIndex ] = predictedPixel.x - observedPixel.x;
output[outputIndex+1] = predictedPixel.y - observedPixel.y;
observationIndex++;
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy