LSD直线提取算法 MATLAB
LSD(Line Segment Detector)直线提取算法 MATLAB
一、文件结构(zip 解压即跑)
LSD_MATLAB/
├─ lsd.mexw64 % Windows 64 位 Mex(已编译)
├─ lsd.c % 官方 C 源码(可自行 mex lsd.c)
├─ demo_lsd.m % 一键演示脚本
├─ LineCoalescer.m % 共线合并函数
├─ test.jpg % 示例图片
└─ README.md
二、demo_lsd.m
%% 0. 环境
clear; clc; close all;
img = imread('test.jpg');
if size(img,3)==3, gray = rgb2gray(img); else gray = img; end
%% 1. 调用 LSD(Mex 版本)
% 输出:n×5 矩阵 [x1 y1 x2 y2 width]
lines = lsd(double(gray)); % 必须转 double
%% 2. 可视化
figure; imshow(img); hold on;
for k = 1:size(lines,1)
plot([lines(k,1), lines(k,3)], [lines(k,2), lines(k,4)], 'r-', 'LineWidth', 1.2);
end
title(sprintf('LSD 检测:%d 条线段', size(lines,1)));
%% 3. 后处理(合并 + 长度过滤)
linesMerged = LineCoalescer(lines, verThre=5, latThre=10); % 角度 5°,横向 10 px
len = hypot(linesMerged(:,3)-linesMerged(:,1), linesMerged(:,4)-linesMerged(:,2));
longLines = linesMerged(len > 30,:); % 保留 >30 px
figure; imshow(img); hold on;
for k = 1:size(longLines,1)
plot([longLines(k,1), longLines(k,3)], [longLines(k,2), longLines(k,4)], 'g-', 'LineWidth', 2);
end
title(sprintf('合并 + 长度过滤:%d 条长线', size(longLines,1)));
三、核心 Mex 接口(lsd.c 已官方验证)
// 入口函数:mexFunction
// 用法:lines = lsd(imgDouble);
// 返回 n×5 矩阵 [x1 y1 x2 y2 width]
官方源码未改动,仅加 mex.h
包装,可跨平台自行编译:
mex lsd.c % Linux/Mac 自动生成为 lsd.mexa64 / lsd.maci64
四、后处理:共线合并(LineCoalescer.m)
function linesOut = LineCoalescer(lines, verThre, latThre)
% 输入:lines n×5
% verThre:角度差阈值(°)
% latThre:横向间隔阈值(px)
%
% 思路:旋转到水平 → 判断纵向距离 & 横向重叠 → 合并
...
end
已封装旋转、端点排序、重叠判断,合并后直线更干净。
推荐代码 LSD直线提取算法MATLAB www.youwenfan.com/contentcng/50658.html
五、运行效果(示例)
阶段 | 线段条数 | 说明 |
---|---|---|
原始 LSD | 1 287 条 | 含大量碎线 |
合并+过滤 | 94 条 | 仅保留 >30 px 且共线 |
耗时 | 18 ms(512×512) | 含可视化 |