/*
 * Copyright (c) 2011-2015, 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.factory.geo;

import boofcv.abst.geo.Estimate1ofEpipolar;
import boofcv.abst.geo.Estimate1ofPnP;
import boofcv.abst.geo.TriangulateTwoViewsCalibrated;
import boofcv.alg.geo.DistanceModelMonoPixels;
import boofcv.alg.geo.pose.PnPDistanceReprojectionSq;
import boofcv.alg.geo.robust.DistanceHomographySq;
import boofcv.alg.geo.robust.DistanceSe3SymmetricSq;
import boofcv.alg.geo.robust.GenerateHomographyLinear;
import boofcv.alg.geo.robust.Se3FromEssentialGenerator;
import boofcv.struct.calib.IntrinsicParameters;
import boofcv.struct.geo.AssociatedPair;
import boofcv.struct.geo.Point2D3D;
import georegression.fitting.homography.ModelManagerHomography2D_F64;
import georegression.fitting.se.ModelManagerSe3_F64;
import georegression.struct.homography.Homography2D_F64;
import georegression.struct.se.Se3_F64;
import org.ddogleg.fitting.modelset.DistanceFromModel;
import org.ddogleg.fitting.modelset.ModelGenerator;
import org.ddogleg.fitting.modelset.ModelManager;
import org.ddogleg.fitting.modelset.lmeds.LeastMedianOfSquares;
import org.ddogleg.fitting.modelset.ransac.Ransac;

/**
 * Factory for creating robust false-positive tolerant estimation algorithms in multi-view geometry.  These
 * algorithms tend to have a lot of boilerplate associated with them and the goal of this factory
 * is to make their use much easier and less error prone.
 *
 * @author Peter Abeles
 */
public class FactoryMultiViewRobust {

	/**
	 * Robust solution to PnP problem using {@link LeastMedianOfSquares LMedS}.  Input observations are
	 * in normalized image coordinates.
	 *
	 * 
	 *
	 * 

See code for all the details.

* * @param pnp PnP parameters. Can't be null. * @param lmeds Parameters for LMedS. Can't be null. * @return Robust Se3_F64 estimator */ public static LeastMedianOfSquares pnpLMedS( ConfigPnP pnp, ConfigLMedS lmeds) { Estimate1ofPnP estimatorPnP = FactoryMultiView.computePnP_1(EnumPNP.P3P_FINSTERWALDER, -1, 1); DistanceModelMonoPixels distance = new PnPDistanceReprojectionSq(); distance.setIntrinsic(pnp.intrinsic.fx,pnp.intrinsic.fy,pnp.intrinsic.skew); ModelManagerSe3_F64 manager = new ModelManagerSe3_F64(); EstimatorToGenerator generator = new EstimatorToGenerator(estimatorPnP); return new LeastMedianOfSquares(lmeds.randSeed, lmeds.totalCycles, manager, generator, distance); } /** * Robust solution to PnP problem using {@link Ransac}. Input observations are in normalized * image coordinates. * *

See code for all the details.

* * @param pnp PnP parameters. Can't be null. * @param ransac Parameters for RANSAC. Can't be null. * @return Robust Se3_F64 estimator */ public static Ransac pnpRansac( ConfigPnP pnp, ConfigRansac ransac) { Estimate1ofPnP estimatorPnP = FactoryMultiView.computePnP_1(pnp.which, -1, pnp.numResolve); DistanceModelMonoPixels distance = new PnPDistanceReprojectionSq(); distance.setIntrinsic(pnp.intrinsic.fx,pnp.intrinsic.fy,pnp.intrinsic.skew); ModelManagerSe3_F64 manager = new ModelManagerSe3_F64(); EstimatorToGenerator generator = new EstimatorToGenerator(estimatorPnP); // convert from pixels to pixels squared double threshold = ransac.inlierThreshold*ransac.inlierThreshold; return new Ransac(ransac.randSeed, manager, generator, distance,ransac.maxIterations,threshold); } /** * Robust solution for estimating {@link Se3_F64} using epipolar geometry from two views with * {@link LeastMedianOfSquares LMedS}. Input observations are in normalized image coordinates. * *
    *
  • Error units is pixels squared times two
  • *
* *

See code for all the details.

* * @param essential Essential matrix estimation parameters. Can't be null. * @param lmeds Parameters for RANSAC. Can't be null. * @return Robust Se3_F64 estimator */ public static LeastMedianOfSquares essentialLMedS( ConfigEssential essential, ConfigLMedS lmeds ) { essential.checkValidity(); Estimate1ofEpipolar essentialAlg = FactoryMultiView. computeFundamental_1(essential.which, essential.numResolve); TriangulateTwoViewsCalibrated triangulate = FactoryMultiView.triangulateTwoGeometric(); ModelManager manager = new ModelManagerSe3_F64(); ModelGenerator generateEpipolarMotion = new Se3FromEssentialGenerator(essentialAlg, triangulate); IntrinsicParameters intrinsic = essential.intrinsic; DistanceFromModel distanceSe3 = new DistanceSe3SymmetricSq(triangulate, intrinsic.fx, intrinsic.fy, intrinsic.skew, intrinsic.fx, intrinsic.fy, intrinsic.skew); return new LeastMedianOfSquares (lmeds.randSeed, lmeds.totalCycles, manager, generateEpipolarMotion, distanceSe3); } /** * Robust solution for estimating {@link Se3_F64} using epipolar geometry from two views with * {@link Ransac}. Input observations are in normalized image coordinates. * *

See code for all the details.

* * @param essential Essential matrix estimation parameters. Can't be null. * @param ransac Parameters for RANSAC. Can't be null. * @return Robust Se3_F64 estimator */ public static Ransac essentialRansac( ConfigEssential essential, ConfigRansac ransac ) { essential.checkValidity(); Estimate1ofEpipolar essentialAlg = FactoryMultiView. computeFundamental_1(essential.which, essential.numResolve); TriangulateTwoViewsCalibrated triangulate = FactoryMultiView.triangulateTwoGeometric(); ModelManager manager = new ModelManagerSe3_F64(); ModelGenerator generateEpipolarMotion = new Se3FromEssentialGenerator(essentialAlg, triangulate); IntrinsicParameters intrinsic = essential.intrinsic; DistanceFromModel distanceSe3 = new DistanceSe3SymmetricSq(triangulate, intrinsic.fx, intrinsic.fy, intrinsic.skew, intrinsic.fx, intrinsic.fy, intrinsic.skew); double ransacTOL = ransac.inlierThreshold * ransac.inlierThreshold * 2.0; return new Ransac(ransac.randSeed, manager, generateEpipolarMotion, distanceSe3, ransac.maxIterations, ransacTOL); } /** * Robust solution for estimating {@link Homography2D_F64} with {@link LeastMedianOfSquares LMedS}. Input * observations are in pixel coordinates. * *
    *
  • Four point linear is used internally

    *
  • inlierThreshold is in pixels

    *
* *

See code for all the details.

* * @param homography Homography estimation parameters. If null default is used. * @param lmeds Parameters for LMedS. Can't be null. * @return Homography estimator */ public static LeastMedianOfSquares homographyLMedS( ConfigHomography homography , ConfigLMedS lmeds ) { if( homography == null ) homography = new ConfigHomography(); ModelManager manager = new ModelManagerHomography2D_F64(); GenerateHomographyLinear modelFitter = new GenerateHomographyLinear(homography.normalize); DistanceHomographySq distance = new DistanceHomographySq(); return new LeastMedianOfSquares (lmeds.randSeed,lmeds.totalCycles,manager,modelFitter,distance); } /** * Robust solution for estimating {@link Homography2D_F64} with {@link Ransac}. Input * observations are in pixel coordinates. * *
    *
  • Four point linear is used internally

    *
  • inlierThreshold is in pixels

    *
* *

See code for all the details.

* * @param homography Homography estimation parameters. If null default is used. * @param ransac Parameters for RANSAC. Can't be null. * @return Homography estimator */ public static Ransac homographyRansac( ConfigHomography homography , ConfigRansac ransac ) { if( homography == null ) homography = new ConfigHomography(); ModelManager manager = new ModelManagerHomography2D_F64(); GenerateHomographyLinear modelFitter = new GenerateHomographyLinear(homography.normalize); DistanceHomographySq distance = new DistanceHomographySq(); double ransacTol = ransac.inlierThreshold*ransac.inlierThreshold; return new Ransac (ransac.randSeed,manager,modelFitter,distance,ransac.maxIterations,ransacTol); } }

Ads help maintain this website.