/*! * \file ContourDetector.h * \date 2019/03/28 * * \author Lin, Chi * Contact: lin.chi@hzleaper.com * * * \note */ #ifndef __ContourDetector_h_ #define __ContourDetector_h_ #include "StdUtils.h" #include "CVUtils.h" #include "CyclopsEnums.h" #include "CyclopsModules.h" struct PeakContourParamPack; /*! \brief Located single or multiple sub-pixel contours in the given image and ROI. * * * 1) If you are using Cyclops as static library, * 1.1) and you want global factory to manage the detector for you, initialize the detector * via ContourDetector::getInstance(). * Example: * \code{.cpp} * ContourDetector::Ptr cdPtr = ContourDetector::getInstance("detect sth"); * * // delete it later * ContourDetector::deleteInstance("detect sth"); * \endcode * * 1.2) or, if you wish to manage the detector yourself: * \code{.cpp} * ContourDetector::Ptr cdPtr = std::make_shared(); // remember to hold the smart pointer * // balabala, same as above * // ... * \endcode * * 2) If you are using Cyclops as dynamic library, * initialize and manipulate the detector via CyclopsModules APIs. * Example: * \code{.cpp} * // get a long-term detector, and give it an unique name * ContourDetector::Ptr cdPtr = GetModuleInstance("detect sth"); * // get for temporary usage * ContourDetector::Ptr localCdPtr = GetModuleInstance(); * * // delete it later * DeleteModuleInstance("detect sth"); * \endcode * */ class ContourDetector : public ICyclopsModuleInstance { public: /*! \fn setContrastThres * Define minimum contrast of a valid instance, 0 to 100, default to 0 * \fn getContrastThres * Get value of minimum contrast of a valid instance */ DECLARE_PARAMETER2(int, ContrastThres, 0, 100) /*! \fn setSortBy * Define which property used for sorting the contours, default to SortBy::Length, see also getSortBy() * Sort by score means sort by its average magnitude. * \fn getSortBy * Get value of which property used for sorting the contours, see also setSortBy() */ DECLARE_PARAMETER(SortBy, SortBy) /*! \fn setConnectTolerance * Define the maximum length of end points that we treate a contour as closed or two contours are connected, default to 1, see also getConnectTolerance() * \fn getConnectTolerance * Get value of the maximum length of end points that we treate a contour as closed or two contours are connected, see also setConnectTolerance() */ DECLARE_PARAMETER2(int, ConnectTolerance, 1, 10) /*! \fn setClosure * Define whether only closure contours should be returned, default to false, see also getClosure() * \fn getClosure * Get value of whether only closure contours should be returned, see also setClosure() */ DECLARE_PARAMETER(bool, Closure) /*! \fn setExcludeBoundary * Define whether to exclude contours that intersect the ROI boundary, default to false, see also getExcludeBoundary() * \fn getExcludeBoundary * Get value of whether to exclude contours that intersect the ROI boundary, see also setExcludeBoundary() */ DECLARE_PARAMETER(bool, ExcludeBoundary) /*! \fn setFilterByDir * Define whether to only return contours whose major axis is along ROI's direction(if there's no ROI, only return horizontal contours), default to false, see also getFilterByDir() * \fn getFilterByDir * Get value of whether to only return contours whose major axis is along ROI's direction, see also setFilterByDir() */ DECLARE_PARAMETER(bool, FilterByDir) /*! \fn setPolarity * Define major polarity of contours, default to Polarity::Either, see also getPolarity() * Only works if result is filtered by ROI's direction * \fn getPolarity * Get major polarity of contours, see also setPolarity() */ DECLARE_PARAMETER2(Polarity, Polarity, Polarity::Black2White, Polarity::Either) /*! \fn setFilterShort * Define the gain to filter short contours, 0 to 100, default to 50, see also getFilterShort() * \fn getFilterShort * Get value of the gain to filter short contours, see also setFilterShort() */ DECLARE_PARAMETER2(int, FilterShort, 0, 100) /*! \fn setFilterWeak * Define the gain to filter weak contours, 0 to 100, default to 50, see also getFilterWeak() * \fn getFilterWeak * Get value of the gain to filter weak contours, see also setFilterWeak() */ DECLARE_PARAMETER2(int, FilterWeak, 0, 100) public: ContourDetector() : mContrastThres(0), mSortBy(SortBy::Length), mPolarity(Polarity::Either), mClosure(false), mConnectTolerance(1), mExcludeBoundary(false), mFilterByDir(false), mFilterShort(50), mFilterWeak(50) {} virtual ~ContourDetector() {} //! Smart pointer to hold an instance of ContourDetector typedef std::shared_ptr Ptr; DECL_GET_INSTANCE(ContourDetector::Ptr) /*! Detect the best contour using the detector. By best, we mean the first ranking contour after applying sort strategy * @param img input image for detection * @param biasAngle used as major angle if do filtered by direction * @param contour output the best contour * @param mask input mask for exclude some pixel from detection * @param return score of the major property defined by sort strategy, negative if find nothing */ virtual float detectBest(const Mat& img, float biasAngle, vector& contour, Mat* mask = nullptr); /** @overload */ virtual float detectBest(const Mat& img, const vector& roi, const Point2f& roiDir, vector& contour); /*! Detect multiple best contours using the detector. By best, we mean the first ranking contours after applying sort strategy * @param img input image for detection * @param biasAngle used as major angle if do filtered by direction * @param contours output the best contours * @param bestScores output scores of found contours. Pass null if you don't want it * @param minCount expected minimum count of the found instances * @param maxCount expected maximum count of the found instances * @param mask input mask for exclude some pixel from detection * @return count of the found instances, it may below minCount but wouldn't exceed maxCount. return 0 if we found nothing good. */ virtual int detectMulti(const Mat& img, float biasAngle, vector >& contours, vector* bestScores, int minCount = 0, int maxCount = 10, Mat* mask = nullptr); /** @overload */ virtual int detectMulti(const Mat& img, const vector& roi, const Point2f& roiDir, vector >& contours, vector* bestScores, int minCount = 0, int maxCount = 10); private: void genPeakContourParamPack(PeakContourParamPack& pack, float biasAngle); }; #endif // ContourDetector_h_