All Downloads are FREE. Search and download functionalities are using the official Maven repository.

boofcv.alg.geo.h.HomographyDirectLinearTransform Maven / Gradle / Ivy

Go to download

BoofCV is an open source Java library for real-time computer vision and robotics applications.

There is a newer version: 1.1.7
Show newest version
/*
 * 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.h;


import boofcv.alg.geo.LowLevelMultiViewOps;
import boofcv.alg.geo.NormalizationPoint2D;
import boofcv.struct.geo.AssociatedPair;
import georegression.struct.point.Point2D_F64;
import org.ejml.data.DMatrixRMaj;
import org.ejml.dense.row.linsol.svd.SolveNullSpaceSvd_DDRM;
import org.ejml.interfaces.SolveNullSpace;
import org.ejml.simple.SimpleMatrix;

import java.util.List;

/**
 * 

* Using linear algebra it computes a planar homography matrix using for or more points. Typically used * as an initial estimate for a non-linear optimization. *

* *

* The algorithm works by solving the equation below:
* hat(x2)*H*x1 = 0
* where hat(x) is the skew symmetric cross product matrix. To solve this equation is is reformatted into * A*Hs=0 using the Kronecker product and the null space solved for. *

* *

* Primarily based on chapter 4 in, "Multiple View Geometry in Computer Vision" 2nd Ed. but uses normalization * from "An Invitation to 3-D Vision" 2004. *

* * @author Peter Abeles */ public class HomographyDirectLinearTransform { // contains the set of equations that are solved protected DMatrixRMaj A = new DMatrixRMaj(1,9); protected SolveNullSpace solverNullspace = new SolveNullSpaceSvd_DDRM(); // Used to normalize input points protected NormalizationPoint2D N1 = new NormalizationPoint2D(); protected NormalizationPoint2D N2 = new NormalizationPoint2D(); // pick a reasonable scale and sign private AdjustHomographyMatrix adjust = new AdjustHomographyMatrix(); // normalize image coordinates to avoid numerical errors? boolean normalize; /** * Configure homography calculation * * @param normalizeInput Should image coordinate be normalized? Needed when coordinates are in units of pixels. */ public HomographyDirectLinearTransform(boolean normalizeInput) { this.normalize = normalizeInput; } /** *

* Computes the homography matrix given a set of observed points in two images. A set of {@link AssociatedPair} * is passed in. The computed homography 'H' is found such that the attributes 'p1' and 'p2' in {@link AssociatedPair} * refers to x1 and x2, respectively, in the equation below:
* x2 = H*x1 *

* * @param points A set of observed image points that are generated from a planar object. Minimum of 4 pairs required. * @param foundH Output: Storage for the found solution. 3x3 matrix. * @return true if the calculation was a success. */ public boolean process( List points , DMatrixRMaj foundH ) { if( points.size() < 4 ) throw new IllegalArgumentException("Must be at least 4 points."); if( normalize ) { LowLevelMultiViewOps.computeNormalization(points, N1, N2); createANormalized(points, A); } else { createA(points,A); } // compute the homograph matrix up to a scale factor if (computeH(A,foundH)) return false; if( normalize ) undoNormalizationH(foundH,N1,N2); // pick a good scale and sign for H adjust.adjust(foundH,points.get(0)); return true; } /** * Computes the SVD of A and extracts the homography matrix from its null space */ protected boolean computeH(DMatrixRMaj A, DMatrixRMaj H) { if( !solverNullspace.process(A.copy(),1,H) ) return true; H.numRows = 3; H.numCols = 3; return false; } /** * Undoes normalization for a homography matrix. */ public static void undoNormalizationH(DMatrixRMaj M, NormalizationPoint2D N1, NormalizationPoint2D N2) { SimpleMatrix a = SimpleMatrix.wrap(M); SimpleMatrix b = SimpleMatrix.wrap(N1.matrix()); SimpleMatrix c_inv = SimpleMatrix.wrap(N2.matrixInv()); SimpleMatrix result = c_inv.mult(a).mult(b); M.set(result.getDDRM()); } /** * Compute the 'A' matrix used to solve for H from normalized points. */ protected void createANormalized(List points, DMatrixRMaj A) { A.reshape(points.size()*2,9, false); A.zero(); Point2D_F64 f_norm = new Point2D_F64(); Point2D_F64 s_norm = new Point2D_F64(); final int size = points.size(); for( int i = 0; i < size; i++ ) { AssociatedPair p = points.get(i); // the first image Point2D_F64 f = p.p1; // the second image Point2D_F64 s = p.p2; // normalize the points N1.apply(f, f_norm); N2.apply(s, s_norm); A.set(i*2 , 3 , -f_norm.x); A.set(i*2 , 4 , -f_norm.y); A.set(i*2 , 5 , -1); A.set(i*2 , 6 , s_norm.y*f_norm.x); A.set(i*2 , 7 , s_norm.y*f_norm.y); A.set(i*2 , 8 , s_norm.y); A.set(i*2+1 , 0 , f_norm.x); A.set(i*2+1 , 1 , f_norm.y); A.set(i*2+1 , 2 , 1); A.set(i*2+1 , 6 , -s_norm.x*f_norm.x); A.set(i*2+1 , 7 , -s_norm.x*f_norm.y); A.set(i*2+1 , 8 , -s_norm.x); } } /** * Compute the 'A' matrix used to solve for H from un-normalized points. */ protected void createA(List points, DMatrixRMaj A) { A.reshape(points.size()*2,9, false); A.zero(); final int size = points.size(); for( int i = 0; i < size; i++ ) { AssociatedPair p = points.get(i); // the first image Point2D_F64 f = p.p1; // the second image Point2D_F64 s = p.p2; A.set(i*2 , 3 , -f.x); A.set(i*2 , 4 , -f.y); A.set(i*2 , 5 , -1); A.set(i*2 , 6 , s.y*f.x); A.set(i*2 , 7 , s.y*f.y); A.set(i*2 , 8 , s.y); A.set(i*2+1 , 0 , f.x); A.set(i*2+1 , 1 , f.y); A.set(i*2+1 , 2 , 1); A.set(i*2+1 , 6 , -s.x*f.x); A.set(i*2+1 , 7 , -s.x*f.y); A.set(i*2+1 , 8 , -s.x); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy