资料:Line Segments Detection

线段检测算法汇总,若无时间看正文,直接到链接看线段检测算法代码集合。

HoughLine

基于hough变换的线段检测算法。opencv提供了2个基于hough变换的函数:cv::HoughLines()以及cv::HoughLinesP()。其中cv::HoughLines()标准霍夫变换,此函数通常不会用到,它经常会被累积概率霍夫变换函数cv::HoughLinesP()代替。概率霍夫变换函数原型:

1
2
3
4
5
6
7
8
void cv::HoughLinesP(InputArray image,
OutputArray lines,
double rho,
double theta,
int threshold,
double minLineLength = 0,
double maxLineGap = 0
)

注意函数返回值line,它是一个四维向量$(x_1,y_1,x_2,y_2)$,其中$(x_1,y_1)$以及$(x_2,y_2)$分别表示线段的端点坐标。以下给出示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
Mat src, dst, color_dst;
if( argc != 2 || !(src=imread(argv[1], 0)).data)
return -1;
// 边缘检测转换为二值边缘图
Canny( src, dst, 50, 200, 3 );
cvtColor( dst, color_dst, COLOR_GRAY2BGR );
vector<Vec4i> lines;
HoughLinesP( dst, lines, 1, CV_PI/180, 80, 30, 10 );
for( size_t i = 0; i < lines.size(); i++ )
{
line( color_dst, Point(lines[i][0], lines[i][1]),
Point( lines[i][2], lines[i][3]), Scalar(0,0,255), 3, 8 );
}
namedWindow( "Source", 1 );
imshow( "Source", src );
namedWindow( "Detected Lines", 1 );
imshow( "Detected Lines", color_dst );
waitKey(0);
return 0;
}

LSD

该方法是目前性价比(速度精度)最好的算法,现已经集成到opencvLSDDetector。LSD能够在线性时间内检测到亚像素精度的线段。无需调整参数,适用于各种场景。因为每张图有误检,LSD能够控制误检率。PS:论文此处不介绍了,可以参考这里

LSWMS

EDline(ED: Edge Drawing)

CannyLines

本文提出了一种鲁棒的线段检测算法来有效地检测来自输入图像的线段。首先,文章提出了一种无参数的Canny算子,称为Canny(PANYPF),通过自适应地设置传统Canny算子的低阈值和高阈值来鲁棒地从输入图像中提取边缘。然后,提出了有效的像素连接和分割技术,直接从边缘图中收集共线点群,用于基于最小二乘拟合方法拟合初始线段。第三,通过有效的扩展和合并,产生更长、更完整的线段。最后,利用亥姆霍兹原理(Helmholtz Principle)对所有的检测线段检测,主要考虑梯度方向和幅度信息。该算法能够在人工场景中能够获得比LSD以及EDline精度更高以及平均长度更高的线段。

MCMLSD