#ifndef _ED_ #define _ED_ #include #include "EDColor.h" /// Special defines #define EDGE_VERTICAL 1 #define EDGE_HORIZONTAL 2 #define ANCHOR_PIXEL 254 #define EDGE_PIXEL 255 #define LEFT 1 #define RIGHT 2 #define UP 3 #define DOWN 4 enum GradientOperator { PREWITT_OPERATOR = 101, SOBEL_OPERATOR = 102, SCHARR_OPERATOR = 103, LSD_OPERATOR = 104 }; struct StackNode {//存放需要发起搜索的像素点 int r, c; // 像素点位置 int parent; // 这个像素点隶属的链表 int dir; // 搜索方向 }; struct Chain {//边缘画线时用于记录链表信息,每个Chain的方向是相同的,不同Chain之间通过parent,children的值进行查找 int dir; // 当前链的方向 int len; // 当前链的长度,像素个数 int parent; // 当前链的双亲 int children[2]; // 当前链两个方向的孩子,children[0]代表left和up方向,children[1]代表right和down方向 cv::Point *pixels; // 组成当前链的像素点的首地址 }; class ED { public: ED(cv::Mat _srcImage, GradientOperator _op = PREWITT_OPERATOR, int _gradThresh = 20, int _anchorThresh = 0, int _scanInterval = 1, int _minPathLen = 10, double _sigma = 1.0, bool _sumFlag = true); ED(const ED &cpyObj); ED(short* gradImg, uchar *dirImg, int _width, int _height, int _gradThresh, int _anchorThresh, int _scanInterval = 1, int _minPathLen = 10, bool selectStableAnchors = true); ED(EDColor &cpyObj); ED(); cv::Mat getEdgeImage(); cv::Mat getAnchorImage(); cv::Mat getSmoothImage(); cv::Mat getGradImage(); int getSegmentNo(); int getAnchorNo(); std::vector getAnchorPoints(); std::vector> getSegments(); std::vector> getSortedSegments(); cv::Mat drawParticularSegments(std::vector list); protected: int width; // 源图像宽度 int height; // 源图像高度 uchar *srcImg; //指向原图的数据区 std::vector > segmentPoints;//边缘段像素链:二维容器,每一行代表一条边缘,每个数据是一个Point double sigma; //高斯宽度参数σ,σ越大作用范围越宽 cv::Mat smoothImage; uchar *edgeImg; //指向得到的边缘图像数据区 uchar *smoothImg; //指向高斯平滑后的图像数据区 int segmentNos;//第几条边缘 int minPathLen;//用于滤除短、细、杂、碎的边缘 cv::Mat srcImage; private: void ComputeGradient(); void ComputeAnchorPoints(); void JoinAnchorPointsUsingSortedAnchors(); void sortAnchorsByGradValue(); int* sortAnchorsByGradValue1(); static int LongestChain(Chain *chains, int root);//计算出某条边缘的链表集中边缘像素点总数 static int RetrieveChainNos(Chain *chains, int root, int chainNos[]); int anchorNos;//找到的锚点个数 std::vector anchorPoints; std::vector edgePoints; cv::Mat edgeImage;//边缘图像 cv::Mat gradImage;//梯度图像,当用Gx+Gy时,两者之和可能会大于255,所以要用short型。 uchar *dirImg; //指向边缘方向的数据区,用于边缘路径追踪 short *gradImg; //指向梯度图像的数据区 GradientOperator op; //枚举梯度算子类型 int gradThresh; //梯度阈值,用于抑制弱边缘点 int anchorThresh; //锚点阈值,阈值越小,找到的锚点个数越多 int scanInterval; //扫描间隔,每隔scanInterval行,scanInterval列扫描下一行,必须小于高斯核的尺寸。 bool sumFlag;//=1时直接将两个方向的梯度相加(默认为true),=0时求两者平方和的开方(计算量大大增加) }; #endif