利用Hough变换进行直线检测

    • hough变换的介绍

在理想情况下,利用Sobel、LoG和Canny边缘检测算子讨论的方法应该只产生位于边缘上的像素。实际上,得到的像素因为噪声,以及不均匀照明引起的边缘断裂和杂散的亮度不连续而难以得到完全的边缘特性。因而,典型的边缘检测算法紧接着用连接过程把像素组装成有意义的边缘。一种寻找并连接图像中线段的方法是霍夫变换。

2. 算法原理

Hough是将原始图像中直线的检测问题转化为寻找参数空间中的交点个数统计的极值问题。

也就是说图像空间中的一条线,在r-theta参数空间中为一个点,经过某一点的所有直线为r-theta参数空间中的一条曲线(三角函数曲线),r-theta参数空间中曲线的交点为图像中一条直线,r-theta参数空间中的一条水平直线为图像空间中的一个圆

对于图像的每个像素点(x,y),对应到参数空间中,找到曲线的交点,交于此点的曲线个数就是图像空间的直线上的像素点数。设置一个阈值,交于一点曲线个数超过这个值,图像中才算一条直线。

3. 实现步骤

  1. 基于边缘检测进行的,先将图像进行灰度处理的操作,然后对边缘进行canny的边缘检测。

  1. hough函数

对二值边缘图像进行Hough变换

[H,theta,rho] = hough(BW,Name,Value,...)

其中:

H:hough变换矩阵,(一行表示一垂线长度,一列表示一旋转角度)矩阵中的值表示过(theta, rho)的曲线的个数,即直线上像素点个数

theta:角度(以度计)

rho:是 ρ 和 θ 值向量

  1. houghpeaks函数

线检测和连接用的霍夫变换的第一步是用高的计数寻找累加单元(工具箱文本把高的计数 单元作为峰值)。因为存在霍夫变换参数空间中的量化和典型图像的边缘并不是很完美的直线这 样的事实,霍夫变换的峰值倾向于相比霍夫变换单元更多。函数 houghpeaks 用任意寻找指定的峰值数:

peaks = houghpeaks(H, NumPeaks)

或者使用完整的语法形式:

peaks = houghpeaks(..., 'Threshold', val1, 'NHoodSize', val2)

其中,“...”指出来自默认语法和 peaks 的输入是持有峰值行和列坐标的 Q×2 大小的矩 阵。Q 的范围是 0 到 NumPeaks,H 是霍夫变换矩阵。参数 val1 是非负的标量,指定了 H 中 的什么值被考虑为峰值;val1 可以从 0 到 Inf 变化,默认值是 0.5*max(H(:))。

这个过程的基本思想是:通过把发现峰值的直接邻域中的霍夫变换单元置 0 来清理峰值。

  1. houghlines函数

一旦一组候选的峰值在霍夫变换中被识别出来,如果存在与这些峰值相关的有意义的线段,剩下的就是决定线的起始点和终点。

函数 houghlines 用默认的语法执行这个任务: lines = houghlines(f, theta, rho, peaks)

  1. 结果

  1. 完整代码

I  = imread('图片2.png');
figure;
subplot(1,3,1);
imshow(I);title('原始图像');
 
I =rgb2gray(I);
 
BW = edge(I,'canny');
%Canny方法提取图像边界,返回二值图像(边界1,否则0)
 
[H,T,R] = hough(BW,'RhoResolution',0.5,'Theta',-10:0.5:10);
%计算二值图像的标准霍夫变换,H为霍夫变换矩阵,I,R为计算霍夫变换的角度和半径值
subplot(1,3,2);
imshow(H,[],'XData',T,'YData',R,'InitialMagnification','fit');title('hough变换的图像');
%hough变换的图像
xlabel('\theta'), ylabel('\rho');
axis on,axis square,hold on;
 
%霍夫峰值
P  = houghpeaks(H,5,'threshold',0.7*max(H(:)));%提取5个极值点
x = T(P(:,2)); 
y = R(P(:,1));
plot(x,y,'s','color','white');%标出极值点
%标记起点与终点
lines=houghlines(BW,T,R,P);%提取线段
subplot(1,3,3);title('得到线段结果图像');
imshow(I), hold on;
for k = 1:length(lines)
xy = [lines(k).point1; lines(k).point2];
 plot(xy(:,1),xy(:,2),'LineWidth',2,'Color','green');%画出线段
plot(xy(1,1),xy(1,2),'x','LineWidth',2,'Color','yellow');%起点
plot(xy(2,1),xy(2,2),'x','LineWidth',2,'Color','red');%终点
end

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cramyyy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值