加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

【matlab攻坚】用matlab检测图片中的直线

(2013-03-07 16:21:16)
标签:

matlab

图片直线检测

rough算法

杂谈

分类: matlab攻坚
    数字图像的直线检测是非常重要的应用,在路面监控的视频处理等等方面有着极为重要的应用。

    目前对于直线检测的算法有很多种,最著名的是rough变换。

    直线的解析式有多种形式,由于用斜率描述的直线存在斜率无穷大的特殊情况,这里选用直线的极坐标描述:ρ=хcos(θ)+уsin(θ)
    式中ρ为直线到原点的距离,θ为限定了直线的斜率。对于任意一组确定的(ρ,θ),上式都可以唯一确定一条直线。开辟二维参数空间H(ρ,θ),对ρ,θ整数化,则对于任意有限平面区域,参数空间H可以表示为有限个点的集合。而H(ρ,θ)中任意点都一一对应原平面区域上的一条直线。

    将上述结论推广到任意平面图像上可知,图像上任意直线区域都可以一一对应参数空间H(ρ,θ)中一个点,而图像上的任意像素都同时存在于很多直线区域之上。可以将图像上的直线区域想象为容器,把特定像素想象成放在容器中的棋子,只不过在这里,每个棋子都可以同时存在于多个容器中。那么Hough变换可以理解为依次检查图像上的每个棋子(特定像素),对于每个棋子,找到所有包含它的容器(平面上的直线区域),并为每个容器的计数器加1,这们就可以统计出每个容器所包含的棋子数量。当图像中某个直线区域包含的特定像素足够多(大于设定的阈值K)时,就可以认为直线区域表示的直线存在。

    用二维向量(ρ,θ)描述图像上的每一条直线区域,则可将图像上的直线区域计数器映射到参数空间H(ρ,θ)中的存储单元。由于ρ为直线区域到原点的距离,因此对于对角线长度为n的图像,固定左上角为原点,可得到ρ的取值范围为[0,n],令θ以1度为增量,可得到θ的取值范围为[0,180]。定义二维数组
accarray(ρ, θ)作为存储单元,其中对于任意(ρ,θ)决定的直线区域,计数器为accarray(ρ, θ)。

    对于 直线的Hough变换过程可以简单描述为,依次遍历图像的所有像素,对于每个像素判断是否满足特定的条件,若满足则对经过该像素的所有直线区域的计数器加1,否则继续判断下一个像素。为了得到经过某个像素的所有直线区域,可以依次用θ的所有可能取值,借助此像素的坐标和直线的极坐标方程计算ρ,而每一组(ρ,θ)就对应了一条经过此像素的直线区域。

根据rough算法写的图片直线检测的代码:
RGB = imread('olympic.jpg');%Read the image
Highlight=RGB;
I=rgb2gray(RGB); %transform the image to gray
[x,y]=size(I);   %get the size of the picture
BW=edge(I);      %get the edge of the picture


rho_max=floor(sqrt(x^2+y^2))+1; %由原图数组坐标算出ρ最大值,并取整数部分加1
%此值作为ρ,θ坐标系ρ最大值
accarray=zeros(rho_max,180); %定义ρ,θ坐标系的数组,初值为0。
%θ的最大值,180度

Theta=[0:pi/180:pi]; %定义θ数组,确定θ取值范围

for n=1:x,
    for m=1:y
        if BW(n,m)==1
            for k=1:180
            %将θ值代入hough变换方程,求ρ值
                rho=(m*cos(Theta(k)))+(n*sin(Theta(k)));
                %将ρ值与ρ最大值的和的一半作为ρ的坐标值(数组坐标),这样做是为了防止ρ值出现负数
                rho_int=round(rho/2+rho_max/2);
                %在ρθ坐标(数组)中标识点,即计数累加
                accarray(rho_int,k)=accarray(rho_int,k)+1;
            end
        end
    end
end



%=======利用hough变换提取直线======%
%寻找100个像素以上的直线在hough变换后形成的点
K=1; %存储数组计数器
for rho_n=1:rho_max %在hough变换后的数组中搜索
    for theta_m=1:180
        if accarray(rho_n,theta_m)>=100 %设定直线的最小值。
        case_accarray_n(K)=rho_n; %存储搜索出的数组下标
        case_accarray_m(K)=theta_m;
        K=K+1;
        end
    end
end

%=====把这些点构成的直线提取出来,输出图像数组为I_out===%
I_out=zeros(x,y);
I_jiao_class=zeros(x,y);
for n=1:x,
    for m=1:y
         if BW(n,m)==1
             for k=1:180
              rho=(m*cos(Theta(k)))+(n*sin(Theta(k)));
              rho_int=round(rho/2+rho_max/2);
             %如果正在计算的点属于100像素以上点,则把它提取出来
                for a=1:K-1
                    if rho_int==case_accarray_n(a)&k==case_accarray_m(a)%%%==gai==%%% k==case_accarray_m(a)&rho_int==case_accarray_n(a)
                    I_out(n,m)=BW(n,m); 
                        for p=0:5 %在原RGB图像上高亮
                         Highlight(n,m+p,1)=255;
                         Highlight(n,m+p,2)=0;
                         Highlight(n,m+p,3)=0;
                        end
                    I_jiao_class(n,m)=k;
                    end
                end
             end
         end
    end
end


figure,imshow(RGB);
title('原图');
imwrite(RGB,'原图.jpg','jpg');

figure,imshow(BW);
title('edge处理后的边界图');
imwrite(BW,'edge处理后的边界图.jpg','jpg');

figure,imshow(I_out);
title('Hough变换检测出的直线');
imwrite(I_out,'Hough变换检测出的直线.jpg','jpg');

figure,imshow(Highlight);
title('高亮后的图');
imwrite(Highlight,'高亮后的图.jpg','jpg');

用于实验的olympic.jpg:



测试与结果:

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有