boofcv.alg.geo.structure.DecomposeAbsoluteDualQuadratic 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) 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.structure;
import org.ejml.data.DMatrix3;
import org.ejml.data.DMatrix3x3;
import org.ejml.data.DMatrix4x4;
import org.ejml.data.DMatrixRMaj;
import org.ejml.dense.fixed.CommonOps_DDF3;
import org.ejml.dense.fixed.CommonOps_DDF4;
/**
* Decomposes the absolute quadratic to extract the rectifying homogrpahy H. This is used to go from
* a projective to metric (calibrated) geometry. See pg 464 in [1].
*
* Q = H*diag([1 1 1 0])*HT and H = [K 0; -p'*K 1]
*
* - R. Hartley, and A. Zisserman, "Multiple View Geometry in Computer Vision", 2nd Ed, Cambridge 2003
*
*
* @author Peter Abeles
*/
public class DecomposeAbsoluteDualQuadratic {
// work space variables
DMatrix3x3 k = new DMatrix3x3();
DMatrix3x3 w = new DMatrix3x3();
DMatrix3x3 w_inv = new DMatrix3x3();
DMatrix3 t = new DMatrix3();
// coordinate of plane at infinity [p,1]
DMatrix3 p = new DMatrix3();
/**
* Decomposes the passed in absolute quadratic
* @param Q Absolute quadratic
* @return true if successful or false if it failed
*/
public boolean decompose( DMatrix4x4 Q ) {
// scale Q so that Q(3,3) = 1 to provide a uniform scaling
CommonOps_DDF4.scale(1.0/Q.a33,Q);
// TODO consider using eigen decomposition like it was suggested
// Directly extract from the definition of Q
// Q = [w -w*p;-p'*w p'*w*p]
// w = k*k'
k.a11 = Q.a11;k.a12 = Q.a12;k.a13 = Q.a13;
k.a21 = Q.a21;k.a22 = Q.a22;k.a23 = Q.a23;
k.a31 = Q.a31;k.a32 = Q.a32;k.a33 = Q.a33;
if( !CommonOps_DDF3.invert(k,w_inv) )
return false;
// force it to be positive definite. Solution will be of dubious value if this condition is triggered, but it
// seems to help much more often than it hurts
// I'm not sure if I flip these variables if others along the same row/col should be flipped too or not
k.set(w_inv);
k.a11 = Math.abs(k.a11);
k.a22 = Math.abs(k.a22);
k.a33 = Math.abs(k.a33);
if( !CommonOps_DDF3.cholU(k) )
return false;
if( !CommonOps_DDF3.invert(k,k) )
return false;
CommonOps_DDF3.divide(k,k.a33);
t.a1 = Q.a14; t.a2 = Q.a24; t.a3 = Q.a34;
CommonOps_DDF3.mult(w_inv, t, p);
CommonOps_DDF3.scale(-1,p);
CommonOps_DDF3.multTransB(k,k,w);
return true;
}
/**
* Recomputes Q from w and p.
*
* @param Q Storage for the recomputed Q
*/
public void recomputeQ( DMatrix4x4 Q ) {
CommonOps_DDF3.multTransB(k,k,w);
Q.a11 = w.a11;Q.a12 = w.a12;Q.a13 = w.a13;
Q.a21 = w.a21;Q.a22 = w.a22;Q.a23 = w.a23;
Q.a31 = w.a31;Q.a32 = w.a32;Q.a33 = w.a33;
CommonOps_DDF3.mult(w,p,t);
CommonOps_DDF3.scale(-1,t);
Q.a14 = t.a1;Q.a24 = t.a2;Q.a34 = t.a3;
Q.a41 = t.a1;Q.a42 = t.a2;Q.a43 = t.a3;
Q.a44 = -CommonOps_DDF3.dot(t,p);
}
/**
* Computes the rectifying homography from the decomposed Q
*
* H = [K 0; -p'*K 1] see Pg 460
*/
public boolean computeRectifyingHomography( DMatrixRMaj H ) {
H.reshape(4,4);
// insert the results into H
// H = [K 0;-p'*K 1 ]
H.zero();
for (int i = 0; i < 3; i++) {
for (int j = i; j < 3; j++) {
H.set(i,j,k.get(i,j));
}
}
// p and k have different scales, fix that
H.set(3,0, -(p.a1*k.a11 + p.a2*k.a21 + p.a3*k.a31));
H.set(3,1, -(p.a1*k.a12 + p.a2*k.a22 + p.a3*k.a32));
H.set(3,2, -(p.a1*k.a13 + p.a2*k.a23 + p.a3*k.a33));
H.set(3,3,1);
return true;
}
public DMatrix3x3 getW() {
return w;
}
public DMatrix3x3 getK() {
return k;
}
/**
* Coordinate of plane at infinity = pi_inf = (p,1)
* @return Coordinate of plane at infinity
*/
public DMatrix3 getP() {
return p;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy