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.
191 lines
6.9 KiB
C++
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__
|