You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

175 lines
6.5 KiB
C++

/*!
* \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<ContourDetector>(); // 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<ContourDetector>("detect sth");
* // get for temporary usage
* ContourDetector::Ptr localCdPtr = GetModuleInstance<ContourDetector>();
*
* // delete it later
* DeleteModuleInstance<ContourDetector>("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<ContourDetector> 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<Vec4f>& contour,
Mat* mask = nullptr);
/** @overload */
virtual float detectBest(const Mat& img, const vector<Point2f>& roi, const Point2f& roiDir,
vector<Vec4f>& 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<vector<Vec4f> >& contours,
vector<float>* bestScores,
int minCount = 0,
int maxCount = 10,
Mat* mask = nullptr);
/** @overload */
virtual int detectMulti(const Mat& img, const vector<Point2f>& roi, const Point2f& roiDir,
vector<vector<Vec4f> >& contours,
vector<float>* bestScores,
int minCount = 0,
int maxCount = 10);
private:
void genPeakContourParamPack(PeakContourParamPack& pack, float biasAngle);
};
#endif // ContourDetector_h_