霍夫变换直线检测

一、基本原理:

所谓霍夫变换,即对于图像平面上的一个点(x , y ),我们采用参数方程p=xcos(θ)+ysin(θ)把这个点映射到参数p-theta平面,那么图像平面上的一个点就对应p-theta平面的一条曲线,其中的p表示图像平面中的这个点所在直线到原点的距离,theta表示这个点所在直线与X轴的夹角。

又因为图像平面上的一个点对应一系列穿过这个点的直线,即有一系列对应的p和theta,所以一个点在参数p-theta平面对应着一条正弦曲线。由此我们可以推导,如果是图像平面上的一条直线,那么直线上的每个点在参数p-theta平面对应的曲线都会相交于同一点,即当前直线的(theta, p)。

基于霍夫变换原理,我们可以在p-theta平面找到最多曲线相交的那点,这一点对应着图像平面最长的直线(可以是连续的也可以是不连续的)。这个点的theta坐标即是我们要寻找的倾斜角。
原文:https://blog.csdn.net/LQMIKU/article/details/79138811 
 

对于平面中的一条直线,在笛卡尔坐标系中,常见的有点斜式,两点式两种表示方法。然而在hough变换中,考虑的是另外一种表示方式:使用(r,theta)来表示一条直线。其中r为该直线到原点的距离,theta为该直线的垂线与x轴的夹角。如下图所示。

也就是霍夫变换中表示一条直线的参数变成了(r,theta)。
2.如何判断多个点是否在同一直线上
当我们的对象变成点时,我们知道一个点可以发射出无数条直线,根据霍夫变换的直线表达形式,假设这个点为i,则通过这个点的直线我们用(ri,thetai)表示。再假设一个点为j,则通过点j的一系列直线我们用(rj,thetaj)表示。我们知道两点决定一条直线,所以这两个点的直线必定有ri=rj,thetai= thetaj的时候。
那如果是三个点呢,假设第三个点是k,则通过k点的一系列直线为(rk,thetak),如果三点在一条直线上,那必定有某个ri=rj=rk = r,thetai = thetaj= thetak = theta。
在霍夫变换检测直线时我们需要找到这样一样直线,如何找到这条直线呢?
3.如何检测出直线
假设有N个点,我们要检测其中的直线,也就是我们要找到具体的r和theata。对于上面所说的每个点可以通过无数条直线,这里我们设为n条(通常 n = 180),则我们一起可以找到Nn个(r, theata),对这Nn个(r,theata),我们可以利用统计学,统计到在theta=某个值theta_i时,多个点的r近似相等于r_i。也就是说这多个点都在直线(r_i,theta_i)上。
4.举例说明
如果空间中有3个点,如何判断这三个点在不在一个直线上,如果在,这条直线是的位置为?

这个例子中,对于每个点均求过该点的6条直线的(r,theta)坐标,共求了3*6个(r,theta)坐标。可以发现在theta=60时,三个点的r都近似为80.7,由此可判定这三个点都在直线(80.7,60)上。
通过 r-o-theta 坐标系可更直观表示这种关系,如下图:图中三个点的(r,theta)曲线汇集在一起,该交点就是同时经过这三个点的直线。


在实际的直线检测情况中,如果超过一定数目的点拥有相同的(r,theta)坐标,那么就可以判定此处有一条直线。在r-O-theta 坐标系图中,明显的交汇点就标示一条检测出的直线。
https://blog.csdn.net/weixin_40196271/article/details/83346442

二、霍夫变换直线检测的matlab实现:

这里涉及到三个函数:hough,houghpeaks,houghlines

1、[H,T,R] = hough(BW,'Theta',20:0.1:75);(输入二值图像BW,角度范围与步进(最大,[-90, 90)),返回 H-霍夫空间,T-theta,R-p);

2、PEAKS = houghpeaks(H,NUMPEAKS);(输入霍夫空间和极值数量,返回极值的坐标)

3、LINES=houghlines(BW,T,R,Peaks);(返回lines是一个包含图像中线段首末点、p、theta的结构体)

峰值提取 
peaks = houghpeaks(H,numpeaks)

peaks = houghpeaks(...,param1, val1, param2, val2)

 

H:累计数组;

Numpeaks:指定需要检测的峰值个数;

Param1:可以是'Threshold'或'NHoodSize'

'Threshold'-指定峰值的域值,默认是0.5*max(H(:))

'NHoodSize'-是个二维向量[m,n],检测到一个峰值后,将峰值周围[m,n]内元素置零。

 

画直线段
lines = houghlines(BW,theta, rho, peaks)

lines = houghlines(...,param1, val1, param2, val2)

BW:二值图

Theta、rho、peaks:分别来自函数hough和houghpeaks

Lines:结构数组,大小等于检测到的直线段数

Point1、point2:线段的端点

Theta、rho:线段的theta和rho
 

示例代码1:

I=imread('1.jpg');

Ihsv=rgb2hsv(I);
Iv=Ihsv(:,:,3);                    %提取v空间
Ivl=Iv(500:end,:);              %截取下半部
Iedge=edge(Ivl,'sobel');    %边沿检测
Iedge = imdilate(Iedge,ones(3));%图像膨胀

%新建窗口,绘图用
figure (2)
imshow(Iedge);
hold on

%左方直线检测与绘制
%得到霍夫空间
[H1,T1,R1] = hough(Iedge,'Theta',20:0.1:75);

%求极值点
Peaks=houghpeaks(H1,5);

%得到线段信息
lines=houghlines(Iedge,T1,R1,Peaks);

%绘制线段
for k=1:length(lines)
    xy=[lines(k).point1;lines(k).point2];   
    plot(xy(:,1),xy(:,2),'LineWidth',4);
end

 
%右方直线检测与绘制
[H2,T2,R2] = hough(Iedge,'Theta',-75:0.1:-20);
Peaks1=houghpeaks(H2,5);
lines1=houghlines(Iedge,T2,R2,Peaks1);
for k=1:length(lines1)
xy1=[lines1(k).point1;lines1(k).point2];   
plot(xy1(:,1),xy1(:,2),'LineWidth',4);
end

hold off

示例代码2:

close all;
clear all;
I  = imread('scratch.tif');
figure;
subplot(1,3,1);
imshow(I);
BW = edge(I,'canny');%Canny方法提取图像边界,返回二值图像(边界1,否则0)
[H,T,R] = hough(BW);%计算二值图像的标准霍夫变换,H为霍夫变换矩阵,I,R为计算霍夫变换的角度和半径值
subplot(1,3,2);
imshow(H,[],'XData',T,'YData',R,'InitialMagnification','fit');%hough变换的图像
xlabel('\theta'), ylabel('\rho');
axis on,axis square,hold on;
P  = houghpeaks(H,3);%提取3个极值点
x = T(P(:,2)); 
y = R(P(:,1));
plot(x,y,'s','color','white');%标出极值点
lines=houghlines(BW,T,R,P);%提取线段
subplot(1,3,3);
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

 

 

  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值