// Copyright (c) 2012-2017 VideoStitch SAS // Copyright (c) 2018 stitchEm #pragma once #include "autoCropConfig.hpp" #include namespace VideoStitch { namespace AutoCrop { /** * @brief Auto-crop for circular fisheye camera */ class VS_EXPORT AutoCrop { public: class DistanceFromCircleCost { public: DistanceFromCircleCost(const double xx, const double yy, const double ww) : xx_(xx), yy_(yy), ww_(ww) {} template bool operator()(const T* const x, const T* const y, const T* const m, // r = m^2 T* residual) const; private: // The measured x,y coordinate that should be on the circle. double xx_, yy_; // The weight of this measure double ww_; }; explicit AutoCrop(const AutoCropConfig& config); ~AutoCrop(); /** * @brief Find the circle in the inputImage, return the status */ Status findCropCircle(const cv::Mat& inputImage, cv::Point3i& circle); /** * @brief Draw a circle on top of the inputImage and save the result to a file */ Status dumpCircleFile(const cv::Point3i circle, const std::string& inputFilename) const; /** * @brief Dump the original image to a file */ Status dumpOriginalFile(const std::string& inputFilename) const; private: /** * @brief Get the initial approximated circle for optimization */ cv::Point3d getInitialCircle(const std::vector& points) const; /** * @brief Perform pre-processing of the input image */ Status setupImage(const cv::Mat& inputImage); /** * @brief Find the inscribed circle that pass set of points which minizizes a cost function (using ceres) * @Note: circle should be initialized before putting into this function */ Status findInscribedCircleCeres(const std::vector& convexHullPoints, const std::vector& convexHullPointWeights, cv::Point3d& circle, const int num_iterations = 1000) const; /** * @brief Find the convex hull of the input "points" */ Status findConvexHullBorder(const cv::Mat& image, const std::vector& points, std::vector& convexHullPoints, std::vector& convexHullPointWeights, const std::vector* borderPoints = nullptr) const; /** * @brief Perform outliers removal */ Status removeOutliers(std::vector& points) const; /** * @brief Find the circle border at full resolution */ void findFineScalePoints(const std::vector& circlePoints, std::vector& fineTuneCirclePoints, const cv::Vec2f& direction = cv::Vec2f(1, 0)) const; /** * @brief Find the set of border pixels in "binaryLabels" */ Status findBorderPixels(std::vector& points) const; /** * @brief Find the set of valid pixels, put the result into "binaryLabels" */ void findValidPixel(const int moveThreshold, const int differenceThreshold); /** * @brief Remove all small disconnected components from "binaryLabels" */ void removeSmallDisconnectedComponent(); /** * @brief Find the refined circle after an initial circle was computed */ Status findRefinedCircle(const cv::Point3d& inputCircle, cv::Point3d& refinedCircle); /** * @brief Connected component labeling */ template static int findConnectedComponent(const T& notVisitedValue, const T& componentLabel, const int& moveThreshold, const int& differenceThreshold, const cv::Point& pt, const cv::Size& size, const std::vector& colors, std::vector& outputComponents); private: cv::Size inputSize; cv::Size2f ratio; cv::Mat inputCvImage; cv::Mat inputLabImage; cv::Mat downLabImage; std::vector binaryLabels; std::vector inputColors; const AutoCropConfig& autoCropConfig; }; } // namespace AutoCrop } // namespace VideoStitch