/** * Robust solution to PnP problem using {@link Ransac}. Input observations are in normalized * image coordinates. Found transform is from world to camera. * * <p>NOTE: Observations are in normalized image coordinates NOT pixels.</p> * * <p>See code for all the details.</p> * * @see Estimate1ofPnP * * @param pnp PnP parameters. Can't be null. * @param ransac Parameters for RANSAC. Can't be null. * @return Robust Se3_F64 estimator */ public static ModelMatcherMultiview<Se3_F64, Point2D3D> pnpRansac( @Nullable ConfigPnP pnp, @Nonnull ConfigRansac ransac ) { if( pnp == null ) pnp = new ConfigPnP(); pnp.checkValidity(); ransac.checkValidity(); Estimate1ofPnP estimatorPnP = FactoryMultiView.pnp_1(pnp.which, pnp.epnpIterations, pnp.numResolve); DistanceFromModelMultiView<Se3_F64,Point2D3D> distance = new PnPDistanceReprojectionSq(); ModelManagerSe3_F64 manager = new ModelManagerSe3_F64(); EstimatorToGenerator<Se3_F64,Point2D3D> generator = new EstimatorToGenerator<>(estimatorPnP); // convert from pixels to pixels squared double threshold = ransac.inlierThreshold*ransac.inlierThreshold; return new RansacMultiView<>(ransac.randSeed, manager, generator, distance, ransac.maxIterations, threshold); }
ModelManager<Se3_F64> manager = new ModelManagerSe3_F64(); ModelGenerator<Se3_F64, AssociatedPair> generateEpipolarMotion = new Se3FromEssentialGenerator(epipolar, triangulate);
ModelManagerSe3_F64 manager = new ModelManagerSe3_F64(); EstimatorToGenerator<Se3_F64,Point2D3D> generator = new EstimatorToGenerator<>(estimatorPnP);
/** * Robust solution to PnP problem using {@link Ransac}. Input observations are in normalized * image coordinates. * * <p>See code for all the details.</p> * * @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<Se3_F64, Point2D3D> pnpRansac( ConfigPnP pnp, ConfigRansac ransac) { Estimate1ofPnP estimatorPnP = FactoryMultiView.computePnP_1(pnp.which, -1, pnp.numResolve); DistanceModelMonoPixels<Se3_F64,Point2D3D> distance = new PnPDistanceReprojectionSq(); distance.setIntrinsic(pnp.intrinsic.fx,pnp.intrinsic.fy,pnp.intrinsic.skew); ModelManagerSe3_F64 manager = new ModelManagerSe3_F64(); EstimatorToGenerator<Se3_F64,Point2D3D> 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 to PnP problem using {@link LeastMedianOfSquares LMedS}. Input observations are * in normalized image coordinates. * * <ul> * <li>Error units is pixels squared.</li> * </ul> * * <p>See code for all the details.</p> * * @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<Se3_F64, Point2D3D> pnpLMedS( ConfigPnP pnp, ConfigLMedS lmeds) { Estimate1ofPnP estimatorPnP = FactoryMultiView.computePnP_1(EnumPNP.P3P_FINSTERWALDER, -1, 1); DistanceModelMonoPixels<Se3_F64,Point2D3D> distance = new PnPDistanceReprojectionSq(); distance.setIntrinsic(pnp.intrinsic.fx,pnp.intrinsic.fy,pnp.intrinsic.skew); ModelManagerSe3_F64 manager = new ModelManagerSe3_F64(); EstimatorToGenerator<Se3_F64,Point2D3D> generator = new EstimatorToGenerator<>(estimatorPnP); return new LeastMedianOfSquares<>(lmeds.randSeed, lmeds.totalCycles, manager, generator, distance); }
distance.setIntrinsic(intrinsic.fx,intrinsic.fy,intrinsic.skew); ModelManagerSe3_F64 manager = new ModelManagerSe3_F64(); EstimatorToGenerator<Se3_F64,Point2D3D> generator = new EstimatorToGenerator<Se3_F64,Point2D3D>(estimator);
distance.setIntrinsic(intrinsic.fx,intrinsic.fy,intrinsic.skew); ModelManagerSe3_F64 manager = new ModelManagerSe3_F64(); EstimatorToGenerator<Se3_F64,Point2D3D> generator = new EstimatorToGenerator<Se3_F64,Point2D3D>(estimator);
distance.setIntrinsic(intrinsic.fx,intrinsic.fy,intrinsic.skew); ModelManagerSe3_F64 manager = new ModelManagerSe3_F64(); EstimatorToGenerator<Se3_F64,Point2D3D> generator = new EstimatorToGenerator<Se3_F64,Point2D3D>(estimator);
ModelManager<Se3_F64> manager = new ModelManagerSe3_F64(); ModelGenerator<Se3_F64, AssociatedPair> generateEpipolarMotion = new Se3FromEssentialGenerator(epipolar, triangulate);
/** * Robust solution for estimating {@link Se3_F64} using epipolar geometry from two views with * {@link Ransac}. Input observations are in normalized image coordinates. * * <p>See code for all the details.</p> * * @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<Se3_F64, AssociatedPair> essentialRansac( ConfigEssential essential, ConfigRansac ransac ) { essential.checkValidity(); Estimate1ofEpipolar essentialAlg = FactoryMultiView. computeFundamental_1(essential.which, essential.numResolve); TriangulateTwoViewsCalibrated triangulate = FactoryMultiView.triangulateTwoGeometric(); ModelManager<Se3_F64> manager = new ModelManagerSe3_F64(); ModelGenerator<Se3_F64, AssociatedPair> generateEpipolarMotion = new Se3FromEssentialGenerator(essentialAlg, triangulate); CameraPinholeRadial intrinsic = essential.intrinsic; DistanceFromModel<Se3_F64, AssociatedPair> 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); }
computeFundamental_1(essential.which, essential.numResolve); TriangulateTwoViewsCalibrated triangulate = FactoryMultiView.triangulateTwoGeometric(); ModelManager<Se3_F64> manager = new ModelManagerSe3_F64(); ModelGenerator<Se3_F64, AssociatedPair> generateEpipolarMotion = new Se3FromEssentialGenerator(essentialAlg, triangulate);