hough变换可以检测指定参数的直线或曲线,它的原理是将图像从空间域变换到直线或曲线的参数域上,参数域中的极大值点,就是要检测的直线或曲线。
检测直线的matlab代码如下:
close all
filename='hough/data/circle.bmp';
degree_range = [0 90]; %检测0到90度范围的直线
line_length = 100; %检测长度大于100的直线
dtheta=1; %theta的步长
drho=1; %rho的步长
%图像预处理
I=rgb2gray(imread(filename));
[width,height] = size(I);
BI = edge(I);
dtheta = dtheta*pi/180;
radian_upper = max(degree_range*pi/180);
radian_lower = min(degree_range*pi/180);
radian_range = radian_upper-radian_lower;
rho_max = sqrt(width^2+height^2);
nrho = ceil(2*rho_max/drho);
theta_value = [radian_lower:dtheta:radian_upper];
ntheta = length(theta_value);
rho_matrix = zeros(nrho,ntheta);
hough_line = zeros(width,height);
%霍夫变换,将空间域变换到参数域 rho=x*cos(theta)+y*sin(theta),rho和theta是参数
[rows,cols] = find(BI);
pointcount = length(rows);
rho_value = zeros(pointcount,ntheta);
for i = 1:pointcount
m=rows(i);
n=cols(i);
for k = 1:ntheta
rho = (m*cos(theta_value(k)))+(n*sin(theta_value(k)));
rho_index = round((rho+rho_max)/drho);
rho_matrix(rho_index,k)= rho_matrix(rho_index,k)+1;
rho_value(rho_index,k) = rho;
end
end
%在参数域空间找符合要求的直线
[index_rho,index_theta] = find(rho_matrix>line_length);
for k = 1:length(index_rho)
theta = theta_value(index_theta(k));
rho = rho_value(index_rho(k),index_theta(k));
for i = 1:pointcount
x=rows(i);
y=cols(i);
rate = (x*cos(theta)+y*sin(theta))/rho;
if(rate>1-10^-3&rate<1+10^-3)
hough_line(x,y)=1;
end
end
end
figure(1);imshow(I);title('src image');
figure(2);imshow(BI);title('edge image');
figure(3);imshow(rho_matrix,[]);title('t');
figure(4);imshow(hough_line);title('hough image');
检测圆的matlab代码如下:
close all
filename = 'hough\data\circle.bmp'; %文件名
radius_range = [5 80]; %检测半径范围
step_angle = 5; %角度步长
step_radius = 1; %半径步长
radius_min = min(radius_range);
radius_max = max(radius_range);
step_angle = step_angle*pi/180;
I = rgb2gray(imread(filename));
[m,n] = size(I);
BI = edge(I);
[rows,cols] = find(BI);
PointCount = size(rows);
RadiusCount = ceil((radius_max-radius_min)/step_radius);
AngleCount = ceil(2*pi/step_angle);
hough_space = zeros(m,n,RadiusCount);
%将原图转换到参数域,a=x-r*cos(theta),b=y-r*sin(theta)
for i = 1:PointCount
for r = 1:RadiusCount
for k = 1:AngleCount
a = round( rows(i) - (radius_min+(r-1)*step_radius)*cos(k*step_angle) );
b = round( cols(i) - (radius_min+(r-1)*step_radius)*sin(k*step_angle) );
if ( a>0&a<=m & b>0&b<=n )
hough_space(a,b,r) = hough_space(a,b,r) + 1;
end
end
end
end
%在参数域中找符合要求的圆
thresh = 0.48;
max_PointCount = max(max(max(hough_space)));
index = find(hough_space>=max_PointCount*thresh);
length = size(index);
hough_circle = zeros(m,n);
size_hough_space = size(hough_space);
for i = 1:PointCount
for k = 1:length
[a,b,r] = ind2sub(size_hough_space,index(k));
rate = ((rows(i)-a)^2 + (cols(i)-b)^2)/((radius_min+(r-1)*step_radius)^2);
if(rate<1.1)
hough_circle(rows(i),cols(i))=1;
end
end
end
figure(1),imshow(I); title('原图');
figure(2),imshow(BI);title('边缘图');
figure(3),imshow(hough_circle);title('结果图');