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.
161 lines
4.0 KiB
C
161 lines
4.0 KiB
C
|
4 years ago
|
#ifndef LP_GenHoughTrans_H_
|
||
|
|
#define LP_GenHoughTrans_H_
|
||
|
|
|
||
|
|
#include <opencv2/opencv.hpp>
|
||
|
|
#include <opencv2/opencv_modules.hpp>
|
||
|
|
|
||
|
|
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<luffy_base::Rpoint> pts;
|
||
|
|
std::vector<luffy_base::Rpoint2> pts2;
|
||
|
|
|
||
|
|
// reference point (inside contour)
|
||
|
|
cv::Vec2i refPoint;
|
||
|
|
// R-table of template object:
|
||
|
|
std::vector<std::vector<cv::Vec2i>> 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<std::vector<cv::Vec2i>> getTable() {
|
||
|
|
return Rtable;
|
||
|
|
}
|
||
|
|
void insertRTable(std::vector<std::vector<cv::Vec2i>> &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<luffy_base::Rpoint> &pts);
|
||
|
|
static void getEdgeInfo(cv::Mat &src, cv::Mat & edge, int intervals, float rangeXY, std::vector<luffy_base::Rpoint2> &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<typename T1, typename T2>
|
||
|
|
static void RotateTransform(std::vector<std::vector<T1>> & RtableSrc,
|
||
|
|
std::vector<std::vector<T2>> &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<std::vector<T1>>::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<typename T1, typename T2>
|
||
|
|
static void ScaleTransform(std::vector<std::vector<T1>> & RtableSrc, std::vector<std::vector<T2>> &RtableScaled, float dScale) {
|
||
|
|
RtableScaled.resize(RtableSrc.size());
|
||
|
|
|
||
|
|
typedef typename std::vector<std::vector<T1>>::size_type t1;
|
||
|
|
typedef typename std::vector<T1>::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_
|
||
|
|
|