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

335 lines
12 KiB
C

#ifndef _Luffy_Process_h_
#define _Luffy_Process_h_
#include "CVUtils.h"
#include "stdio.h"
#include <list>
#include <map>
using namespace cv;
using std::vector;
namespace luffy_base
{
#define LP_MAX_ANGLE 360
#define LP_GRAY_LEVEL 256
#define LP_MAX_GRAY_VALUE 255
#define LP_COLOR_GREEN Scalar(0, 255, 0)
#define LP_COLOR_RED Scalar(0, 0, 255)
#define LP_COLOR_BLUE Scalar(255, 0, 0)
#define LP_COLOR_WHITE Scalar(255, 255, 255)
#define LP_COLOR_BLACK Scalar(0, 0, 0)
#define LuffyMax(a, b) ((a)>(b) ? (a) : (b))
#define LuffyMin(a, b) ((a)<(b) ? (a) : (b))
#define LP_SINGLE_LINE 1
class luffyCircle
{
public:
luffyCircle() :ptCenter(0,0), fRadius(0){}
public:
Point2f ptCenter;
float fRadius;
};
class luffyObject
{
public:
luffyObject();
Rect rtPos;
float getRadius() { return (rtPos.width / 2.0); }
//Rect
};
typedef int LP_NORM_METHOD;
class luffyPos
{
public:
Point m_ptInPic; //圆在大图中的圆心位置
Point m_ptInROI; //圆在ROI中的圆心位置
Rect m_rtROI; //ROI区域
float m_fRadiusAvg; //半径
};
/*
emThresMethodDefault param1
emThresMethodInv param1
emThresMethodRatio emThresMethodRatio
emThresMethodNum emThresMethodNum
emThresMethodOtsu
emThresMethodIteration
emThresMethodBasicGlobal
emThresMethodMaxEntropy
emThresMethodHuangFuzzy
*/
namespace luffy_threshold {
enum EmThresMethod {
emThresMethodDefault = 000, emThresMethodInv = 100, emThresMethodRatio = 2, emThresMethodNum = 3, emThresMethodOtsu = 4,
emThresMethodIteration= 5, emThresMethodBasicGlobal = 6, emThresMethodMaxEntropy = 7, emThresMethodHuangFuzzy = 8, emThresMethod2 = 9
};
void calcuHist(const Mat &src, Mat &matHist, int &nTotal, Mat &mask = gDummyMat);
int getThresValue(Mat &matHist, int nTotal, double dRatio, EmThresMethod emMethod = emThresMethodRatio);
int Threshold(const Mat &src, Mat &dst, double param1, int nThresMethod = emThresMethodDefault, Mat mask = Mat());
int Threshold(const Mat &src, Mat &dst, vector<double> param, int nThresMethod = emThresMethodDefault, Mat mask = Mat());
}
/*
*/
namespace luffy_projection {
enum EmProjectionDirect { emProjX = 0, emProjY = 1 };
void project2point(const Mat & src, Mat & projDst, Point ptCenter, int nAngleCount, LP_NORM_METHOD normType = 0);
void project2axis(const Mat & src, Mat & projDst, EmProjectionDirect param1 = emProjX, LP_NORM_METHOD normType = 0);
}
//<! 基本的图像处理方法
namespace luffy_imageProc {
void meanvarnorm(Mat& src, Mat &dst, double avg, double var, Mat mask = Mat()); //<! 此函数由大饼提供
bool lsCircleFit(vector<Point> &points, float &fRadius, Point2f &center); //<! 最小二乘法圆拟合
bool lsLineFit(vector<Point> &points, float& a, float &b); //<! 最小二乘法直线拟合 y = a + b * x
void rotateImage(Mat &src, Mat &dst, float angle, Point ptCenter = Point(), int clockWise = 1);
void RemoveSmallRegion(Mat &Src, Mat &Dst, int AreaLimit, int CheckMode, int NeihborMode);
int judgeCircle(const vector<Point> &vec, Point2f ptCenter, float radius, float dDiff);
enum EmCreateMode{
emCreateDefault, emCreateGray, emCreateColor, emCreateCopy, emCreateNull
};
void createImage(Mat & src, Mat & dst, EmCreateMode emMode = emCreateDefault, Scalar color = Scalar::all(0));
void sobel(Mat &src, Mat *pDst = NULL, Mat *pSobelX = NULL, Mat *pSobelY = NULL, int iBlockSize = 3);
enum EmGradientMethod {
emGradient1
};
void ComputeGradient(Mat & src, EmGradientMethod method = emGradient1, Mat *pAngle = nullptr, Mat *pMag = NULL);
//<! fit model by Ransac
enum EmModel {
emModelCircle, emModelLine
};
struct RansacParam {
RansacParam(float fProb, float fErrorDis, int nMaxItCount, int nMinFitNum, int nBreakCondit) {
m_fProb = fProb; m_fErrorDis = fErrorDis; m_nMinFitNum = nMinFitNum; m_nMaxItCount = nMaxItCount; m_nBreakCondit = nBreakCondit;
}
float m_fProb;
float m_fErrorDis;
int m_nMaxItCount;
int m_nMinFitNum;
int m_nBreakCondit;
};
vector<Point> genRandPoints(vector<Point> & vecPoints, float fProb, int prec = 100);
vector <Point> fitModelbyRansac(vector<Point> &vecPoints, EmModel emModel, float fProb, float errorDis, int nMaxItNum, int minFitNum, int breakCondi);
vector <Point> fitModelbyRansac(vector<Point> &vecPoints, EmModel emModel, RansacParam *pParam);
bool fitModel(vector<Point> &vecPoints, vector<double> &vecRes, EmModel emModel);
}
/*
+
*/
namespace luffy_math {
int mod(int index, int total, int periodNum = 1); //<! 取余
float getVectorsAngle(float angle1, float angle2, const int nMaxAngle = 360); //<! 求夹角中心
float caculAngle(Point ptCenter, Point ptTarget); //<! 角度计算
template<typename T1, typename T2> //<! 点之间距离
float disofPoints(T1 pt1, T2 pt2) {
float dx = pt1.x - pt2.x;
float dy = pt1.y - pt2.y;
return (float)sqrtf(dx*dx + dy*dy);
}
template <typename T>
float disofPoint2Line(T pt, float a, float b) { //<! 点与直线间的距离, y=a+bx
return fabs(pt.x * b + a - pt.y) / sqrtf(a*a + b*b);
}
template<typename T>
bool sort2Data(T &minData, T &maxData) { //<! 2数据排序
if (minData <= maxData) return true;
else {
T tmp = minData; minData = maxData; maxData = tmp;
return false;
}
};
bool isOutRange(Point pt, Size size);
bool checkPoint(Point &pt, Rect rt);
bool checkData(int &nData, int nMax, int nMin);
bool checkRoiRect(Size imgSize, Rect & rtRoi);
bool checkSquare(Rect rect, int nMinWidth, int nMaxWidth, int nMaxDiff = 20);
bool checkSquare(RotatedRect rect, float nMinWidth, float nMaxWidth, float nMaxDiff = 20);
bool checkSquare(Size2f size, float nMinWidth, float nMaxWidth, float nMaxDiff = 20);
void LeastSquare1d(const cv::Mat & mat1d, cv::Mat &Basemat, cv::Mat &Residualmat);
double rotateRectIntersects(const cv::RotatedRect &rRect1, const cv::RotatedRect& rRect2, bool ifDis = true);
enum EmDataMinMax{ emDataMax, emDataMin };
double getMinMaxData(const Mat & src, EmDataMinMax emData = emDataMax, Point *pIndex = NULL);
Point polar2rect(Point2f ptCenter, float radius, float dCos, float dSin);
void polar2rect(const Mat &src, Mat &dst, Point ptCenter, int nRadiusIn, int nRadiusOut, int nAngleMax);
}
bool CheckMatEqu(const cv::Mat &mask1, const cv::Mat &mask2, bool ifcheckType=false);
bool CheckMatLogical(const cv::Mat &src);
//<! 一位数组数据可视化
void drawCurveUsingArray(const Mat &src, Mat &dst, LP_NORM_METHOD normType = 0, Scalar bgColor = Scalar::all(255), Scalar curveColor = Scalar::all(0));
//<! 大小端
void swapBigEndian(unsigned short &data);
/*
1广
2线
*/
namespace luffy_match {
enum EmLoopMatchDirect { emLoopMatchCol = 0, emLoopMatX = 0, emLoopMatchRow = 1, emLoopMatY = 1 };
bool LoopMatMatch(Mat & src, Mat &temp, EmLoopMatchDirect direct, Mat &result, int method = CV_TM_CCORR_NORMED);
void LoopMatShift(Mat & src, Mat & dst, EmLoopMatchDirect direct, int clockwiseShift = 0); //<! 顺时针偏移 偏移量为clockwiseShift
}
/*
blob
0906blob
*/
namespace luffy_blob {
struct PolyEdge{
PolyEdge() : y0(0), y1(0), x(0), dx(0), next(0) {}
int y0, y1;
int x, dx;
PolyEdge *next;
};
static const int CodeDeltas[8][2] =
{ { 1, 0 }, { 1, -1 }, { 0, -1 }, { -1, -1 }, { -1, 0 }, { -1, 1 }, { 0, 1 }, { 1, 1 } };
struct CmpEdges
{
bool operator ()(const PolyEdge& e1, const PolyEdge& e2)
{
return e1.y0 - e2.y0 ? e1.y0 < e2.y0 :
e1.x - e2.x ? e1.x < e2.x : e1.dx < e2.dx;
}
};
enum { XY_SHIFT = 16, XY_ONE = 1 << XY_SHIFT, DRAWING_STORAGE_BLOCK = (1 << 12) - 256 };
//20150906 当前版本只能计算每个blob的面积
//获取面积
//std::list<int> getArea(Size imgSize, vector< vector<Point> > &contours);
int getArea(const Size imgSize, const vector<Point> & contours);
//获取长度
std::list<int> getLeng(Size imgSize, vector< vector<Point> > contours, int contourIdx);
std::list<int> cvProcessContours(Size imgSize, CvSeq* contour, int max_level);
void CollectPolyEdges(const Point* v, int count, vector<PolyEdge>& edges, int shift);
int CaculCollectionArea(Size imgSize, vector<PolyEdge>& edges);
}
/*
1createNewTrigValuetotal360°total
2使getCos/SingetCosPtr/SinPtrindextotal
*/
namespace luffy_triangle {
bool createNewTrigValue(int total);
bool releaseTrigValue(int total);
double getCos(int total, int index);
double getSin(int total, int index);
double *getCosPtr(int total);
double *getSinPtr(int total);
}
/*
*/
namespace luffy_hit {
enum EmHitDirectParam {
emHitIn2Out = 0, emHitOut2In = 1,
emHitUp2Down = 0, emHitDown2Up = 1,
emHitLeft2Right = 2, emRight2Left = 3
};
class MoutainClamp {
public:
MoutainClamp(int iTotal = 360, bool bLoop = false) {
left = 0; right = 0; total = iTotal; m_bLoop = bLoop;
}
int left;
int right;
int total;
bool m_bLoop;
int getLen() {
return (m_bLoop == false) ? (right - left + 1) : luffy_math::mod(right - left + 1, total);
}
vector<Rect> getRect(int nRow, int nCols) {
vector<Rect> vecRect;
if (1 != nCols) {
if (left <= right) {
vecRect.push_back(Rect(left, 0, getLen(), LP_SINGLE_LINE));
}
else {
vecRect.push_back(Rect(left, 0, nCols - left + 1, LP_SINGLE_LINE));
vecRect.push_back(Rect(0, 0, right, LP_SINGLE_LINE));
}
}
else {
if (left <= right) {
vecRect.push_back(Rect(0, left, LP_SINGLE_LINE, getLen()));
}
else {
vecRect.push_back(Rect(0, left, LP_SINGLE_LINE, nRow - left + 1));
vecRect.push_back(Rect(0, 0, LP_SINGLE_LINE, right));
}
}
return vecRect;
};
double getSum(Mat & src){
double dSum = 0.0;
vector<Rect> vecRect = getRect(src.rows, src.cols);
for (int i = 0; i < vecRect.size(); i++) {
dSum += cv::sum(src(vecRect[i]))[0];
}
return dSum;
};
int getMid(){
return luffy_math::getVectorsAngle(left, right, total);
}
bool judgeLen(int nMin = 0, int nMax = 360, bool bLoop = false) {
int nLen = getLen();
return luffy_math::checkData(nLen, nMax, nMin);
}
};
void firstHit4Circle(Mat &binary, Mat &hit, vector<Point> &vecHit, Point ptCenter, int nIn, int nOut, int nHitCount = 360, EmHitDirectParam emHit = emHitOut2In);
void firstHit4Axis(Mat &binary, Mat &hit, int nMin, int nMax, EmHitDirectParam emHit = emHitUp2Down);
void hit2Moutain(Mat & src, std::vector<MoutainClamp> &vecMouts, float thresValue, int nWidth);
void filterMoutain(std::vector<MoutainClamp> & vecMouts, int nTotal, int minSpace, int minWidth, bool bLoop = false);
MoutainClamp getMaxWidthMoutain(std::vector<MoutainClamp> & vecMouts, bool bLoop = false);
MoutainClamp getMaxDensityMoutain(Mat &src, std::vector<MoutainClamp> & vecMouts, bool bLoop = false);
}
}
#endif //_Luffy_Process_h_