hough变换检测直线和圆

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');
hough变换检测直线和圆_第1张图片 hough变换检测直线和圆_第2张图片 hough变换检测直线和圆_第3张图片

检测圆的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('结果图');

hough变换检测直线和圆_第4张图片

你可能感兴趣的:(hough变换检测直线和圆)