#ifndef LP_GenHoughTrans_H_ #define LP_GenHoughTrans_H_ #include #include namespace luffy_base { struct Rpoint { int dx; int dy; float phi; }; struct Rpoint2 { float x; float y; int phiIndex; }; } class GenHoughTrans { cv::Mat accum; std::vector pts; std::vector pts2; // reference point (inside contour) cv::Vec2i refPoint; // R-table of template object: std::vector> Rtable; // number of intervals for angles of R-table: int intervals; // minimum and maximum rotation allowed for template float phimin; float phimax; // dimension in pixels of squares in image int rangeXY; int method; float deltaPhi; int R; int S; public: enum EM_GHT_METHOD{ emXY = 0x01, emRotate = 0x02, emScale = 0x04 }; GenHoughTrans(); ~GenHoughTrans(); void setMethod(int method); int getIntervals() const { return intervals; } void setIntervals(int nIntervals) { intervals = nIntervals; deltaPhi = CV_PI / intervals; } float getMinPhi() const { return phimin; } float getMaxPhi() const { return phimax; } float getDeltaPhi() { return deltaPhi; } int getR() const { return R; } int getS() const { return S; } int getFloorR() const { return floor(phimin / deltaPhi); } int getCeilR() const { return ceil(phimax / deltaPhi); } int getX(int w) const { return ceil((float)w / rangeXY); } int getY(int h) const { return ceil((float)h / rangeXY); } int getRangeXY() const { return rangeXY; } void genRefPoint(cv::Mat &edge); void genRefPoint(cv::Point pt) { refPoint = pt; } std::vector> getTable() { return Rtable; } void insertRTable(std::vector> &rTable){ Rtable = rTable; } static int genKey(int R, int S = 1) { return R * S; }; static void parse(int key, int R, int &r, int &s) { s = key / R; r = key % R; } static void phase(cv::Mat &src, cv::Mat &angle); static void getEdgeInfo(cv::Mat &src, cv::Mat & edge, cv::Point pt, std::vector &pts); static void getEdgeInfo(cv::Mat &src, cv::Mat & edge, int intervals, float rangeXY, std::vector &pts2); void createRTable(cv::Mat &src, cv::Mat & edge); void accumlate(cv::Mat & src, cv::Mat & edge); void bestCandidate(cv::Mat & src, cv::Mat& dst); void detect(cv::Size size, int r, int s = 1); template static void RotateTransform(std::vector> & RtableSrc, std::vector> &RtableRotated, int angleIndex, float deltaAngle) { int intervals = RtableSrc.size(); double cs = cos(angleIndex * deltaAngle); double sn = sin(angleIndex * deltaAngle); RtableRotated.resize(intervals); typedef typename std::vector>::size_type t1; for (t1 ii = 0; ii < RtableSrc.size(); ++ii) { int nSize = RtableSrc[ii].size(); int iiMod = (ii + angleIndex) % intervals; RtableRotated[iiMod].resize(nSize); for (t1 jj = 0; jj < nSize; jj++) { RtableRotated[iiMod][jj] = T2(cs*RtableSrc[ii][jj][0] - sn * RtableSrc[ii][jj][1], sn*RtableSrc[ii][jj][0] + cs*RtableSrc[ii][jj][1]); } } } template static void ScaleTransform(std::vector> & RtableSrc, std::vector> &RtableScaled, float dScale) { RtableScaled.resize(RtableSrc.size()); typedef typename std::vector>::size_type t1; typedef typename std::vector::size_type t2; for (t1 ii = 0; ii < RtableSrc.size(); ++ii){ int nSize = RtableSrc[ii].size(); RtableScaled[ii].resize(nSize); for (t2 jj = 0; jj < nSize; ++jj){ RtableScaled[ii][jj] = T2(dScale*RtableSrc[ii][jj][0], dScale*RtableSrc[ii][jj][1]); } } } }; class GHTInvoker : public cv::ParallelLoopBody { public: GHTInvoker(GenHoughTrans *_ght,cv::Size _size){ ght = _ght; size = _size; } cv::Size size; GenHoughTrans *ght; virtual void operator() (const cv::Range& range) const; }; #endif // LP_GenHoughTrans_H_