boofcv.alg.geo.pose.PositionFromPairLinear2 Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of boofcv-geo Show documentation
Show all versions of boofcv-geo Show documentation
BoofCV is an open source Java library for real-time computer vision and robotics applications.
/*
* Copyright (c) 2021, 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.pose;
import georegression.geometry.GeometryMath_F64;
import georegression.struct.point.Point2D_F64;
import georegression.struct.point.Point3D_F64;
import georegression.struct.point.Vector3D_F64;
import org.ejml.data.DMatrixRMaj;
import org.ejml.dense.row.factory.LinearSolverFactory_DDRM;
import org.ejml.interfaces.linsol.LinearSolverDense;
import java.util.List;
/**
*
* Given two views of N objects and the known rotation, estimate the translation. A linear system
* is constructed from the equations below and solved for. A minimum of two point observations is required
* since rotation is already known. This high level characteristics of this algorithm was
* stated in [1], but the mathematics were not described or sketched.
*
*
*
* Derivation:
*
* λx = R*X + T
* 0 = hat(x)*R*X + hat(x)*T
* hat(x)*T = -hat(x)*R*X
*
* where hat(x) is the cross product matrix of the homogeneous (x,y,1) vector, R is a rotation
* matrix, T is the known translation, and X is the known point in 3D.
*
*
*
* [1] Tardif, J.-P., Pavlidis, Y., and Daniilidis, K. "Monocular visual odometry in urban
* environments using an omnidirectional camera," IROS 2008
*
*
* @author Peter Abeles
*/
public class PositionFromPairLinear2 {
LinearSolverDense solver = LinearSolverFactory_DDRM.leastSquares(300, 3);
// storage for system of equations
DMatrixRMaj A = new DMatrixRMaj(3, 3);
DMatrixRMaj x = new DMatrixRMaj(3, 1);
DMatrixRMaj b = new DMatrixRMaj(3, 1);
Point3D_F64 RX = new Point3D_F64();
// found translation
Vector3D_F64 T = new Vector3D_F64();
/**
* Computes the translation given two or more feature observations and the known rotation
*
* @param R Rotation matrix. World to view.
* @param worldPts Location of features in world coordinates.
* @param observed Observations of point in current view. Normalized coordinates.
* @return true if it succeeded.
*/
public boolean process( DMatrixRMaj R, List worldPts, List observed ) {
if (worldPts.size() != observed.size())
throw new IllegalArgumentException("Number of worldPts and observed must be the same");
if (worldPts.size() < 2)
throw new IllegalArgumentException("A minimum of two points are required");
int N = worldPts.size();
A.reshape(3*N, 3);
b.reshape(A.numRows, 1);
for (int i = 0; i < N; i++) {
Point3D_F64 X = worldPts.get(i);
Point2D_F64 o = observed.get(i);
int indexA = i*3*3;
int indexB = i*3;
// @formatter:off
A.data[indexA + 1] = -1;
A.data[indexA + 2] = o.y;
A.data[indexA + 3] = 1;
A.data[indexA + 5] = -o.x;
A.data[indexA + 6] = -o.y;
A.data[indexA + 7] = o.x;
GeometryMath_F64.mult(R, X, RX);
b.data[indexB++] = 1*RX.y - o.y*RX.z;
b.data[indexB++] = -1*RX.x + o.x*RX.z;
b.data[indexB ] = o.y*RX.x - o.x*RX.y;
// @formatter:on
}
if (!solver.setA(A))
return false;
solver.solve(b, x);
T.x = x.data[0];
T.y = x.data[1];
T.z = x.data[2];
return true;
}
public Vector3D_F64 getT() {
return T;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy