|
|
#ifndef _ED_
|
|
|
#define _ED_
|
|
|
|
|
|
#include <opencv2/opencv.hpp>
|
|
|
#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<cv::Point> getAnchorPoints();
|
|
|
std::vector<std::vector<cv::Point>> getSegments();
|
|
|
std::vector<std::vector<cv::Point>> getSortedSegments();
|
|
|
|
|
|
cv::Mat drawParticularSegments(std::vector<int> list);
|
|
|
|
|
|
protected:
|
|
|
int width; // 源图像宽度
|
|
|
int height; // 源图像高度
|
|
|
uchar *srcImg; //指向原图的数据区
|
|
|
std::vector<std::vector< cv::Point> > 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<cv::Point> anchorPoints;
|
|
|
std::vector<cv::Point> 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 |