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

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_