LSD直线检测
一、简介
LSD是一种线段检测算法^{[1]},该方法能在较短的时间内获得较高精度的直线段检测结果。
LSD直线检测算法首先计算图像中所有点的梯度大小和方向,然后将梯度方向变化小且相邻的点作为一个连通域,接着根据每一个域的矩形度判断是否需要按照规则将其断开以形成多个矩形度较大的域,最后对生成的所有的域做改善和筛选,保留其中满足条件的域,即为最后的直线检测结果。该算法的优点在于检测速度快,而且无需参数调节,利用错误控制的方法,提高直线检测的准确度。
1 算法介绍
LSD直线检测方法首先计算每个像素点的水平线(Level-Line)角度,从而形成了一个水平线场(Level-Line Field),即单位矢量场。这里像素点的水平线角度就是该点梯度方向的垂直角度,如图2-1所示,而水平线场就是一个与图像中的点一一对应的矩阵,矩阵中元素的值即为对应到图像中点的水平线角度,如图2-2中间图所示。
获得水平线场后,依据水平线角度用区域生长的方法将其切割成若干个连通域,每个连通域中所有像素点的水平线角度变化不能超过容忍值\tau,这样的连通域称为线支持区域(Line Support Regions),每个线支持区域都是线段检测的候选对象。如图2所示,绿色区域、橙色区域和蓝色区域各是一个线支持区域。
获得线支持区域后,把线支持区域的主惯性轴方向作为矩形方向,构造一个包含区域中所有点的矩形,如图2-3所示构造方式在3.6节中详细说明。然后将矩形中所有水平线方向角度与矩形方向角度偏差小于\tau的点叫做对齐点(Aligned Point)如图2-4所示,设一个矩形内总的点数为n,其中对齐点点数为k,这将用于之后验证矩形是否能作为线段检测结果。
二、源代码
% lsd store and draw
img_path = './undistortedImage/1.png';
a = detect(img_path);
lines_list = flsd(a);
lines_list = lines_list(:,1:4);
swap = lines_list(:,1);
lines_list(:,1) = lines_list(:,2);
lines_list(:,2) = swap;
swap = lines_list(:,3);
lines_list(:,3) = lines_list(:,4);
lines_list(:,4) = swap;
% lines_list = and;
fusion_lines = mergeLine(lines_list,5,5,10,180);
% minAngleDis = 5; minDis = 5; minLen = 20; minGap = 180;
img = imread(img_path);
line = fusion_lines;
figure,
hold on
imagesc(img);
colormap bone;
for i = 1: size(line,1)
plot([line(i,1),line(i,3)],[line(i,2),line(i,4)],'red');
end
axis ij
hold off
img = imread(img_path);
line = lines_list;
figure,
hold on
imagesc(img);
colormap bone;
for i = 1: size(line,1)
plot([line(i,1),line(i,3)],[line(i,2),line(i,4)],'red');
end
axis ij
hold off
三、运行结果