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/ArcDetector.h

191 lines
6.9 KiB
C

/*!
* \file ArcDetector.h
* \date 2020/04/28 16:41
*
* \author lucas.ma
* Contact: lucas.ma@hzleaper.com
*
* TODO: null
*
* \note
*/
#ifndef _AnnulusSectorDetector_H__
#define _AnnulusSectorDetector_H__
#include "StdUtils.h"
#include "CVUtils.h"
#include "CyclopsEnums.h"
#include "CyclopsModules.h"
struct PeakCircleParamPack;
enum PeakAlgoAccLevel;
struct ArcCurve
{
ArcCurve() : mCircle(Vec3f(0, 0, 0)), mStartPnt(Point2f(0, 0)), mEndPnt(Point2f(0, 0)) {}
ArcCurve(const Vec3f& circle, const Point2f& sp, const Point2f& ep) :
mCircle(circle), mStartPnt(sp), mEndPnt(ep) {}
float getAngle() const
{
Point2f dsp = mStartPnt - Point2f(mCircle[0], mCircle[1]);
Point2f dep = mEndPnt - Point2f(mCircle[0], mCircle[1]);
Point2f ns = dsp / sqrt(dsp.x * dsp.x + dsp.y* dsp.y);
Point2f ne = dep / sqrt(dep.x * dep.x + dep.y * dep.y);
float endAngle = fastAtan2(ne.y, ne.x);
float startAngle = fastAtan2(ns.y, ns.x);
float angle = endAngle - startAngle;
if (startAngle > endAngle)
angle = angle + 360;
return angle;
}
bool isEmpty() const
{
return mCircle == Vec3f::zeros();
}
public:
Vec3f mCircle;
Point2f mStartPnt;
Point2f mEndPnt;
};
class ArcDectector : public ICyclopsModuleInstance
{
public:
/*! \fn setPolarity
* Define polarity of circle edge, Polarity::Black2White to Polarity::Either, default to Polarity::Either, see also getPolarity()
* \fn getPolarity
* Get value of polarity of circle edge, see also setPolarity()
*/
DECLARE_PARAMETER2(Polarity, Polarity, Polarity::Black2White, Polarity::Either)
/*! \fn setFindBy
* Define find-by stategy of detector, FindBy::Best to FindBy::Last, default to FindBy::Best, see also getFindBy()
* \fn getFindBy
* Get value of find-by stategy of detector, see also setFindBy()
*/
DECLARE_PARAMETER2(FindBy, FindBy, FindBy::Best, FindBy::All)
/*! \fn setACThres
* Define minimum acceptable score, 0 to 100, default to 0, see also getACThres()
* \fn getACThres
* Get value of minimum acceptable score, see also setACThres()
*/
DECLARE_PARAMETER2(int, ACThres, 0, 100)
/*! \fn setEdgeWidth
* Define edge width, default to 3, see also getEdgeWidth()
* The value should match the real edge width, which means the range that the edge transit from black to white or vice versa.
* \fn getEdgeWidth
* Get value of edge width, see also setEdgeWidth()
*/
DECLARE_PARAMETER(int, EdgeWidth)
/*! \fn setRadii
* Define the radii range [val1, val2]
* \fn getRadiiStart
* Get value of minimum circle radii
* \fn getRadiiEnd
* Get value of maximum circle radii
*/
DECLARE_PARAMETER_PAIR(unsigned int, Radii)
/*! \fn setAccLevel
* Define accuracy level of the algorithm, default to -1 means hardcoded defaults, see also getAccLevel()
* Note: this value only works for PeakCircle.
* \fn getAccLevel
* Get value of accuracy level of the algorithm, see also setAccLevel()
*/
DECLARE_PARAMETER(int, AccLevel)
/*! \fn setNormBy
* Define how to normalized scores, default to NormBy::RegionMax, see also getNormBy()
* \fn getNormBy
* Get value of how to normalized scores, see also setNormBy()
*/
DECLARE_PARAMETER(NormBy, NormBy)
public:
ArcDectector(Polarity polarity, FindBy findby) : mPolarity(polarity), mFindBy(findby),
mACThres(0), mEdgeWidth(3), mAccLevel(-1), mNormBy(NormBy::RegionMax) {};
ArcDectector() : mPolarity(Polarity::Either), mFindBy(FindBy::Best),
mACThres(0), mEdgeWidth(3), mAccLevel(-1), mNormBy(NormBy::RegionMax) {};
virtual ~ArcDectector() {};
typedef std::shared_ptr<ArcDectector> Ptr;
DECL_GET_INSTANCE(ArcDectector::Ptr)
/*! Detect the best single arc edge using the detector
* @param img input image for detection
* @param bestArc output arc: Vec3f(center.x, center.y, radii), vector<Point2f>{startPoint, endPoint}
* @param estCenter input initial estimated center of circular arc, if estCenter == nullptr, then it will automatically use
center of input image as estimated center
* @param allScores output, represent the score distribution among defined radii range,
* pass null if you don't want it
* @param mask input mask for exclude some pixel from detection
* @return score of the best one, 0 if we found nothing good
*/
virtual float detectBest(const Mat& img,
ArcCurve& bestArc,
Point2f* estCenter = nullptr,
vector<float>* allScores = nullptr,
Mat* mask = nullptr);
/** @overload */
/*! Detect the best single arc edge using the detector
* @param img input image for detection
* @param shapePnts input defined annulus sector ROI
* @param bestArc output arc: Vec3f(center.x, center.y, radii), vector<Point2f>{startPoint, endPoint}
* @param allScores output, represent the score distribution among defined radii range,
* pass null if you don't want it
* @return score of the best one, 0 if we found nothing good
*/
virtual float detectBest(const Mat& img,
const vector<Point2f>& shapePnts,
ArcCurve& bestArc,
vector<float>* allScores = nullptr);
/*! Detect multiple arc edge using the detector
* @param img input image for detection
* @param bestArc output arcs
* @param bestScores output scores of several best arcs
* @param estCenter input initial estimated center of circular arc, if estCenter == Point2f(0,0), then it will automatically use
center of input image as estimated center
* @param allScores output, represent the score distribution among defined radii range,
* pass null if you don't want it
* @param minCount minimum number of arcs there should be
* @param maxCount maximum number of arcs there should be
* @param mask input mask for exclude some pixel from detection
* @return real number of arcs found in the image, it may exceed the provided limitation
*/
virtual int detectMulti(const Mat& img,
vector<ArcCurve>* bestArcs,
vector<float>* bestScores,
Point2f* estCenter = nullptr,
vector<float>* allScores = nullptr,
int minCount = 0,
int maxCount = 10,
Mat* mask = nullptr);
/** @overload */
/*! Detect multiple arc edge using the detector
* @param img input image for detection
* @param shapePnts input defined annulus sector ROI
* @param bestArc output arcs
* @param bestScores output scores of several best arcs
* @param input initial estimated center of circular arc, if estCenter == Point2f(0,0), then it will automatically use
center of input image as estimated center
* @param allScores output, represent the score distribution among defined radii range,
* pass null if you don't want it
* @param minCount minimum number of arcs there should be
* @param maxCount maximum number of arcs there should be
* @return real number of arcs found in the image, it may exceed the provided limitation
*/
virtual int detectMulti(const Mat& img,
const vector<Point2f>& shapePnts,
vector<ArcCurve>* bestArcs,
vector<float>* bestScores,
vector<float>* allScores = nullptr,
int minCount = 0,
int maxCount = 10);
private:
void genPeakArcParamPack(PeakCircleParamPack & pack, PeakAlgoAccLevel defaultAccLevel);
};
#endif // _AnnulusSectorDetector_H__