// Copyright (c) 2012-2017 VideoStitch SAS // Copyright (c) 2018 stitchEm #pragma once #include "libvideostitch/panoDef.hpp" #include "libvideostitch/logging.hpp" #include <Eigen/Dense> #include <random> namespace VideoStitch { namespace Calibration { class Camera; /** @brief This class is used to filter outlier control points. @details Given two inputs and the control points between them, it finds the best model to align two images in the panorama @details Returns the optimal relative position of the images and a list of control points containing only the inlier control points */ class ControlPointFilter { public: ControlPointFilter(double cellFactor, double angleThreshold, double minRatioInliers, int minSamplesForFit, double ratioOutliers, double probaDrawOutlierFreeSample); /** * @brief Uses the control points to align inputs. * @param filteredControlPoints the returned list of filtered control points * @param camera1 the first camera object * @param camera2 the second camera object * @param currentControlPoints the list of control points extracted from the current input pictures * @param formerControlPoints the list of control points coming from the PanoDefinition (extracted during a former * calibration) * @param syntheticControlPoints the list of synthetic control points generated to cover the input areas where no * control point has been extracted * @param gen the random number generator * @note currentControlPoints take precedence over formerControlPoints, which take precedence over * syntheticControlPoints * @return true on success * @return false on failure */ bool filterFromExtrinsics(Core::ControlPointList& filteredControlPoints, const std::shared_ptr<Camera>& camera1, const std::shared_ptr<Camera>& camera2, const Core::ControlPointList& currentControlPoints, const Core::ControlPointList& formerControlPoints, const Core::ControlPointList& syntheticControlPoints, std::default_random_engine& gen); /** * @brief Uses the estimated rotation to project the control points. * @return true on success * @return false on failure */ Status projectFromEstimatedRotation(Core::ControlPointList& filteredControlPoints, const std::shared_ptr<Camera>& camera1, const std::shared_ptr<Camera>& camera2); Eigen::Matrix3d getEstimatedRotation() { return estimatedR; } /** * @brief Get rotation score * @return sum of angular distances between rotated inliers */ double getScore() { return score; } /** * @brief gets the number of inliers with found rotation * @return number of inliers with found rotation */ size_t getConsensus() { return consensus; } private: Eigen::Matrix3d estimatedR; double score; size_t consensus; private: double cellFactor; // Cell for homogeneous distribution double angleThreshold; // max angular distance between two reprojected CPs to be considered as inliers, in degrees double minRatioInliers; // minimum ratio of inliers that need to be found to validate a model int minSamplesForFit; // minimum number of control points needed to estimate a model int numIters; // number of RANSAC iterations }; } // namespace Calibration } // namespace VideoStitch