- hough变换的介绍
在理想情况下,利用Sobel、LoG和Canny边缘检测算子讨论的方法应该只产生位于边缘上的像素。实际上,得到的像素因为噪声,以及不均匀照明引起的边缘断裂和杂散的亮度不连续而难以得到完全的边缘特性。因而,典型的边缘检测算法紧接着用连接过程把像素组装成有意义的边缘。一种寻找并连接图像中线段的方法是霍夫变换。
2. 算法原理
Hough是将原始图像中直线的检测问题转化为寻找参数空间中的交点个数统计的极值问题。
也就是说图像空间中的一条线,在r-theta参数空间中为一个点,经过某一点的所有直线为r-theta参数空间中的一条曲线(三角函数曲线),r-theta参数空间中曲线的交点为图像中一条直线,r-theta参数空间中的一条水平直线为图像空间中的一个圆
对于图像的每个像素点(x,y),对应到参数空间中,找到曲线的交点,交于此点的曲线个数就是图像空间的直线上的像素点数。设置一个阈值,交于一点曲线个数超过这个值,图像中才算一条直线。
3. 实现步骤
基于边缘检测进行的,先将图像进行灰度处理的操作,然后对边缘进行canny的边缘检测。
hough函数
对二值边缘图像进行Hough变换
[H,theta,rho] = hough(BW,Name,Value,...)
其中:
H:hough变换矩阵,(一行表示一垂线长度,一列表示一旋转角度)矩阵中的值表示过(theta, rho)的曲线的个数,即直线上像素点个数
theta:角度(以度计)
rho:是 ρ 和 θ 值向量
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 来清理峰值。
houghlines函数
一旦一组候选的峰值在霍夫变换中被识别出来,如果存在与这些峰值相关的有意义的线段,剩下的就是决定线的起始点和终点。
函数 houghlines 用默认的语法执行这个任务: lines = houghlines(f, theta, rho, peaks)
结果
完整代码
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