Matlab中用Hough变换检测并保留平行线的技术问题及输入疑问
解决方案:筛选存在平行/近似平行线的线条
首先给你个核心建议:既然你已经有了线条的端点坐标矩阵Location1,完全不需要把plot的输出转成图像再做Hough变换——直接处理原始的几何数据效率更高、精度也更可控,还能避开图像采样带来的误差。
具体实现步骤
1. 先算出每条线段的方向角
每条线段的方向是判断平行的核心,我们可以用atan2函数计算方向角,并且统一转换到[0, π)区间(因为平行线的方向角要么完全相同,要么相差π,转成这个区间后就不用考虑反向的情况了):
num_segments = size(Location1, 1) - 1; theta = zeros(num_segments, 1); for i = 1:num_segments dx = Location1(i+1, 1) - Location1(i, 1); dy = Location1(i+1, 2) - Location1(i, 2); theta(i) = mod(atan2(dy, dx), pi); % 转成[0, π)的角度 end
2. 设定平行阈值,筛选符合条件的线段
你可以自己定义一个平行度阈值(比如0.1弧度,大概5.7度,数值越大允许的角度误差越大),然后检查每条线段是否存在至少一条其他线段和它的方向角差小于这个阈值:
theta_threshold = 0.1; % 可根据需求调整 keep = false(num_segments, 1); % 遍历每条线段,统计有多少近似平行的线段(排除自身) for i = 1:num_segments diffs = abs(theta - theta(i)); parallel_count = sum(diffs < theta_threshold) - 1; % 减去自身的匹配 if parallel_count >= 1 keep(i) = true; end end
如果线段数量特别多,双重循环效率低的话,可以用更高效的矩阵操作替代:
theta_matrix = repmat(theta, 1, num_segments); diffs = abs(theta_matrix - theta_matrix'); keep = sum(diffs < theta_threshold, 2) > 1; % 每行求和大于1说明有至少一条平行线
3. 重新绘制保留的线段
最后只绘制那些被标记为keep的线段就可以了:
figure; imshow(blackImage); hold on; for i = 1:num_segments if keep(i) h = plot([Location1(i,1) Location1(i+1,1)], [Location1(i,2) Location1(i+1,2)]); set(h, 'linewidth', 0.1, 'color', 'b'); end end hold off;
关于Hough变换的补充
如果你一定要尝试Hough变换的话,需要先把绘制好的图形转成图像:
% 先绘制所有线条,再把figure转成图像 figure; imshow(blackImage); hold on; for i=1:size(Location1,1)-1 h = plot([Location1(i,1) Location1(i+1,1)], [Location1(i,2) Location1(i+1,2)]) ; set(h,'linewidth', .1, 'color', 'b') ; end hold off; frame = getframe(gcf); img = rgb2gray(frame.cdata);
然后对img做Hough变换,提取线条的方向和rho值,再通过方向bin的聚类来判断平行。但这种方法会因为图像分辨率、线条宽度等引入误差,远不如直接处理坐标数据靠谱。
内容的提问来源于stack exchange,提问作者Matte
相关产品推荐
相关产品推荐

