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.
wheeldetect/3part/Cyclops/include/CornerDetector.h

144 lines
4.8 KiB
C

/*!
* \file CornerDetector.h
* \date 2019/05/28
*
* \author Jin, Bing wen fixed by: Lou, Li xuan
* Contact:
*
*
* \note
*/
#ifndef CornerDetector_h__
#define CornerDetector_h__
#include "CVUtils.h"
#include "StdUtils.h"
#include "CyclopsModules.h"
/*! \brief Located corner points in the given contour line.
*
*
* 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 CornerDetector::getInstance().
* Example:
* \code{.cpp}
* CornerDetector::Ptr cdPtr = CornerDetector::getInstance("detect sth");
*
* // delete it later
* CornerDetector::deleteInstance("detect sth");
* \endcode
*
* 1.2) or, if you wish to manage the detector yourself:
* \code{.cpp}
* CornerDetector::Ptr cdPtr = std::make_shared<CornerDetector>(); // 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
* CornerDetector::Ptr cdPtr = GetModuleInstance<CornerDetector>("detect sth");
* // get for temporary usage
* CornerDetector::Ptr localCdPtr = GetModuleInstance<CornerDetector>();
*
* // delete it later
* DeleteModuleInstance<CornerDetector>("detect sth");
* \endcode
*
*/
class CornerDetector : public ICyclopsModuleInstance
{
public:
/*! \fn set_win
* Define length of slide window, 3 to 60, default to 10, which influence operation speed significantly
* \fn get_win
* Get value of window length
*/
DECLARE_PARAMETER2(int, _win, 3, 60)
/*! \fn set_skipWin
* Define useless part length of window, 0 to (_win-1), default to 5
* \fn get_skipWin
* Get value of skipWin length
*/
DECLARE_PARAMETER_GET(int, _skipWin)
/*! \fn set_filterWin
* Define window length of mean filter, 0 to 10, default to 2
* \fn get_filterWin
* Get value of mean filter window length
*/
DECLARE_PARAMETER2(int, _filterWin, 0, 10)
/*! \fn set_maxCornerAngle
* Define the upper limit angle of a corner, 0 to 180, default to 160
* \fn get_maxCornerAngle
* Get value of upper limit angle of a corner
*/
DECLARE_PARAMETER2(float, _maxCornerAngle, 0.0, 180.0)
/*! \fn set_closed
* Define whether the contour is closed, default to false
* \fn get_closed
* Get value of whether the input contour is closed
*/
DECLARE_PARAMETER(bool, _closed)
/*! \fn set_filterDuplicatedCorners
* Define whether to filter duplicated corners, default to true
* \fn get_filterDuplicatedCorners
* Get value of whether to filter duplicatedCorners
*/
DECLARE_PARAMETER(bool, _filterDuplicatedCorners)
/*! \fn set_downSampleFactor
* Define down sampling factor, every nth sample after the first
* \fn get_downSampleFactor
* Get value of down sampling factor
*/
DECLARE_PARAMETER2(int, _downSampleFactor, 1, 200)
public:
CornerDetector();
virtual ~CornerDetector() {}
//! Smart pointer to hold an instance of CornerDetector
typedef std::shared_ptr<CornerDetector> Ptr;
DECL_GET_INSTANCE(CornerDetector::Ptr)
/*! Detect corners in a contour, whose angle is smaller than m_maxCornerAngle
* @param posVec input the coordinates of points in the contour
* @param pCornerVec output coordinates of corners
* @param pContourVec output contours after segmentation, set_segment(true) to get result
* @param pCornerIDVec output ID of corners, you can get a corner by posVec[ID]
* @param return whether algorithm work properly
*/
virtual bool detectCorners(const vector<Point2f>& posVec, vector<Point2f>* pCornerVec = nullptr,
vector<vector<Point2f>>* pContourVec = nullptr, vector<int>* pCornerIDVec = nullptr);
/*! \fn set_skipWin
* Define useless part length of window, 0 to (_win-1), default to 5
*/
void set_skipWin(int val) { m_skipWin = ensureRng(val, 0, m_win - 1);}
protected:
// Detect corners in a contour, whose angle is smaller than m_maxCornerAngle
bool detectCornersID(const vector<Point2f>& posVec, vector<int>& cornerIDVec);
// gen angle using pos points
bool genAngle(const vector<Point2f>& posVec, vector<float>& angleVec);
// filtering angle using mean filter
bool filterAngle(vector<float>& angleVec);
// get corner ID according to m_maxCornerAngle
void findCorners(const vector<float>& angleVec, vector<int>& cornerIDVec);
// filter corners whose distance is smaller than m_win
void filterDuplicatedCorners(const vector<float>& angleVec, vector<int>& cornerIDVec);
// segment contour using corners, number of points will down sample according to downSampleFactor
bool segmentContour(const vector<Point2f>& posVec, const vector<int>& cornerIDVec,
vector<vector<Point2f>>& contourVec);
// decreases sample rate from head index to tail index, every nth sample after the first.
void downSample(const vector<Point2f>& ori, int headIdx, int tailIdx, vector<Point2f>& res);
};
#endif // CornerDetector_h__