Matlab之Hough变换(十六)

Hough变换和Otsu算法都是属于第一类基于灰度的图像特征检测和分割手段。Hough变换将对直线的检测处理为对点的统计,使得数值计算成为可能;Otsu算法基于灰度值分布,提出类方差最大的分割原则,算法简单可行,而且他们共同的优点就是对噪声不敏感,这与之前介绍的微分算符差别较大。


Hough变换思想

按照前面提到的表象变换,可以绘制出与xy平面中所有图像点相对应的mn平面上空间直线,且xy平面中的主要直线可以通过识别mn平面中大量直线相交的点来找到。然而这一方法的困难在于xy中直线斜率无穷大时,对应的a值无穷大,无法表示。解决这一问题的方式就是采用极坐标系,也就是所谓的Hough变换,将xy平面直线上的点映射到极坐标下一系列余弦(或者正弦)曲线的共同交点,通过极坐标下交点的重叠密集度来反推该交点所对应的xy平面上的直线是否存在,下图展示了Hough变换的原理和过程。
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

利用Hough变换检测直线

Hough变换除了有降噪以及衔接不均匀照明引起的边缘断裂等优点外,也有其在计算上的优点,它能消除xy空间斜率无穷大的影响,将对直线的检测变为对点的累加统计,使得数值计算成为可能。利用Hough变换检测xy二维平面上直线步骤具体如下:

  • Step1
    把ρ’θ’空间细分为累加器单元,距离取值范围[0,D],D 为像素矩阵对角距离,角度取值范围是[-pi,pi],如下图。
    在这里插入图片描述

  • Step2
    设置一个与极坐标空间相应的空矩阵,初始值均为0,每个矩阵元素S(i,j)对应(p’i,θ’j)。

  • Step3
    对于xy图像矩阵中的非背景点(xk,yk),逐点扫描极坐标中的θ’,得到相应的距离值即ρ’=xk cosθ’+ykrsinθ’,将ρ’四舍五入为沿p’轴最近的单元,相应的累加器加1。

  • Step4
    设定一定的筛选阈值,选出累加器s矩阵中的系列取值,峰值所对应的点就是xy平面中直线的参数。

Hough变换检测直线

  • 缺点在在于计算量大,像素矩阵元素数量成线性关系;
  • 优点在于其明显的去噪功能以及将对线的检测变成对点的统计。
常用函数
Hough
[H, theta, rho] = hough(BW)
[H, theta, rho] = hough(BW,Name ,Value, ...)

[H,theta,rho] = hough(BW) 计算二值图像BW的标准Hough变换(SHT)。Hough 函数旨在检测线条。

该函数使用线条的参数化表示

rho = x*cos(theta) + y*sin(theta)

该函数返回rho (沿垂直于线条的向量从原点到线条的距离)和theta (x 轴与该向量之间的角度,以度为单位)。该函数还返回标准Hough变换H,它是一个参数空间矩阵, 其行和列分别对应于rho和theta值。

输入参数BW
规定为二值图像

输出参数[H,T,R] = hough(BW,‘RhoResolution’,0.5,‘Theta’,0.5)

  • ‘RhoResolution’
    Hough 变换沿 rho 轴的 bin 的间距
    默认为1或选择0 和 norm(size(BW)) 之间(不包含两者)的实数数值标量
  • ‘Theta’
    输出矩阵 H 的对应列的 Theta 值
    默认为-90:89或选择实数数值向量

举例:


RGB = imread('gantrycrane.png');
I  = rgb2gray(RGB);
BW = edge(I,'canny');
[H,T,R] = hough(BW,'RhoResolution',0.5,'Theta',-90:0.5:89);
subplot(2,1,1);
imshow(RGB);
title('gantrycrane.png');
subplot(2,1,2);
%imshow(imadjust(rescale(H)),'XData',T,'YData',R, 'InitialMagnification','fit');
imshow(H,[],'XData',theta,'YData',rho,'InitialMagnification','fit');
title('Hough transform of gantrycrane.png');
xlabel('\theta'), ylabel('\rho');
axis on, axis normal, hold on;
colormap(gca,hot);

在这里插入图片描述

具体可参考:
https://ww2.mathworks.cn/help/images/ref/hough.html?s_tid=srchtitle#d120e14384


houghlines

基于 Hough 变换提取线段

lines = houghlines(BW, theta, rho, peaks)

%提取图像BW中与Hough变换中的特定bin相关联的线段
%theta 和rho是函数hough返回的向量
%peaks是由houghpeaks函数返回的矩阵,其中包含Hough变换bin的行和列坐标,用于搜索线段
%返回值lines是结构体数组,长度等于
找到的合并后的线段数
lines = houghlines(...,Name ,Value,...)

%提取图像BW中的线段,其中指定的参数影响运算。
 lines = houghlines(BW,T,R,P,'FillGap',5,'MinLength',7)
 %BW - 二值图像
%'FillGap' - 与同一Hough 变换 bin 相关联的两个线段之间的距离
%默认为20或选择正实数标量
%'MinLength' - 最小线条长度,默认为40或选择正实数标量
%lines - 找到的线条,为结构体数组

在这里插入图片描述

举例:

I  = imread('circuit.tif');

rotI = imrotate(I,33,'crop');%旋转图像

BW = edge(rotI,'canny');

[H,T,R] = hough(BW);
imshow(H,[],'XData',T,'YData',R,...
            'InitialMagnification','fit');
xlabel('\theta'), ylabel('\rho');
axis on, axis normal, hold on;

P  = houghpeaks(H,5,'threshold',ceil(0.3*max(H(:))));
x = T(P(:,2)); y = R(P(:,1));
plot(x,y,'s','color','white');

lines = houghlines(BW,T,R,P,'FillGap',5,'MinLength',7);
figure, imshow(rotI), hold on
max_len = 0;
for k = 1:length(lines)
   xy = [lines(k).point1; lines(k).point2];
   plot(xy(:,1),xy(:,2),'LineWidth',2,'Color','green');

   % Plot beginnings and ends of lines
   plot(xy(1,1),xy(1,2),'x','LineWidth',2,'Color','yellow');
   plot(xy(2,1),xy(2,2),'x','LineWidth',2,'Color','red');

   % Determine the endpoints of the longest line segment
   len = norm(lines(k).point1 - lines(k).point2);
   if ( len > max_len)
      max_len = len;
      xy_long = xy;
   end
end

plot(xy_long(:,1),xy_long(:,2),'LineWidth',2,'Color','cyan');

原图:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

参考文章为:
https://ww2.mathworks.cn/help/images/ref/houghlines.html


houghpeaks
peaks = houghpeaks(H, numpeaks )

%在Hough变换矩阵中定位峰值,H有hough功能。numpeaks指定要标识的最大峰值数。函数返回peaks保存峰的行和列坐标的矩阵。
%numpeaks — 要识别的最大峰值数,1(默认)正整数
%'Threshold' — 最小值应视为峰值,0.5*max(H(:))(默认)非负数
%'NHoodSize' — 抑制邻域大小,正奇整数的2-元向量
%'Theta' — Hough变换θ值,-90:89(默认)数值向量
%peaks-发现峰的行和柱坐标,Q-乘以-2矩阵
peaks = houghpeaks(H, numpeaks , Name ,Value)
%使用名称-值对参数控制操作的各个方面。
I  = imread('circuit.tif');
BW = edge(imrotate(I,50,'crop'),'canny');
[H,T,R] = hough(BW);
P  = houghpeaks(H,2);
imshow(H,[],'XData',T,'YData',R,'InitialMagnification','fit');
xlabel('\theta'), ylabel('\rho');
axis on, axis normal, hold on;
plot(T(P(:,2)),R(P(:,1)),'s','color','white');

在这里插入图片描述

代码实现
% matlab 检测直线
RGB  = imread('septagon.tif');
I = im2double(RGB);
BW = edge(I,'canny');
figure, imshow(BW);

[H, theta, rho] = hough(BW, 'RhoResolution', 0.5, 'Theta', -90:0.2:89);

figure
imshow(H,[],'XData',theta,'YData',rho,'InitialMagnification','fit');
title('霍夫变换图'), xlabel('\theta'), ylabel('\rho');
axis on , axis normal
hold on

% Find peaks in the Hough transform of the image.
P  = houghpeaks(H,8,'threshold', ceil(0.3*max(H(:))));
x = theta(P(:,2));
y = rho(P(:,1));
plot(x,y,'s','color','white');


% Find lines and plot them.
lines = houghlines(BW,theta,rho,P,'FillGap',10,'MinLength',5);
figure, imshow(RGB), hold on
max_len = 0;
for k = 1:length(lines)
   xy = [lines(k).point1; lines(k).point2];
   plot(xy(:,1),xy(:,2),'LineWidth',2,'Color','green');

   % Plot beginnings and ends of lines
   plot(xy(1,1),xy(1,2),'x','LineWidth',2,'Color','yellow');
   plot(xy(2,1),xy(2,2),'x','LineWidth',2,'Color','red');

   % Determine the endpoints of the longest line segment
   len = norm(lines(k).point1 - lines(k).point2);
   if ( len > max_len)
      max_len = len;
      xy_long = xy;
   end
end
% Highlight the longest line segment by coloring it cyan.
plot(xy_long(:,1),xy_long(:,2),'LineWidth',2,'Color','cyan');

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述


参考文章为:https://mp.weixin.qq.com/s?src=3&timestamp=1588333110&ver=1&signature=aARZqVlWaHtaooYo91BKK1mkji7VgJ8QA3VR6KyEX3xOu22vTMO7Ku4t48Y1Qy9xuspOk61J8XArCDr9d-tNp52N4HaIfkLGnYRWttD2wBPJFV4TEW0lPtYQKBTGSxkklWh4AefhSDc2WyQYinQYDwsH-o7NIihko3YJ*qE=

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值