最早接触霍夫变换(Hough Transform )[4,5,6,7,8]就是用在检测直线,大四的时候用来分割ROI用的,原理看起来很简单。
一.检测直线
直线y=k*x+b上一点(x0,y0),满足方程y0=k*x0+b。那么换过来看,在坐标系(k,b)上,这就是一条直线,即b=- x0* k+ y0;再来直线上的一点(x1,y1),同样满足y1=k*x1+b,那么在(k,b)坐标系上就是另外一条直线,即b=-x1*k+y1;这两条直线的交点就是(k,b),即为(x,y)平面的斜率和截距。
(x,y)平面上的一条直线映射到(k,b)平面就变成一个点了。
为了解决k为无穷大的问题以及如果采用(k,b)矩阵,参数范围会比较庞大(k和b的范围不好取),采用极坐标表示x*cos(theta) + y*sin(theta)=r,这样r就固定在x,y对角线范围内,角度可以设置为0到180°。程序关键在于步长怎么确定,太密了时间长,太稀疏了,可能找不到最大值。
1. 算法流程为:
1) 初始化累加器H为零
2) 遍历图像中每个边缘点
for theta = 0 to 180
r=x*cos(theta) + y*sin(theta)
H(theta,r) = H(theta,r)+1;
end
3) H中最大的值对应的theta和r就是要求的直线(实际使用的时候可以设定最大值的阈值)
Code:
M = imread(‘sqr1.gif’);
if size(M,3) == 3
M1=rgb2gray(M);
else
M1=M;
end
BW = edge(M1,’canny’);
[sy,sx]=size(I);
[y,x]=find(I);
totalpix = length(x);
maxrho = round(sqrt(sx^2 + sy^2)); %Rou的最大坐标