关闭

椭圆慢检测

153人阅读 评论(0) 收藏 举报

原文地址:http://blog.csdn.net/u012507022/article/details/50979005

由椭圆的公式(1)可得,确定一个椭圆需要5个参数,a,b 为椭圆的长轴和段轴,P,Q 为椭圆中心坐标,θ为椭圆的旋转角度。如果用传统的Hough变换方法,参数空间需要五维。这种方法在计算过程中所耗费的时间和空间资源是惊人的,根本无法应用于实际。为此,人们提出了很多新的改进算法。

 

 

 

改进算法主要分为两种:

  • 1)随机Hough变换(RHT),采用多到一的映射,但是随机采样会带来大量无效的计算,当点数很大时,算法的性能急剧下降。
  • 2)利用椭圆的几何特征降低参数的维度。

本文所提出的椭圆检测方法也是基于第二种方法。在讲该方法之前,先引入椭圆的一个几何定理:

定理 设平面上有一个椭圆,点 c 为椭圆中心,任取平面上一点 p(不同于点 c),点 p 距椭圆上点的最大距离一 定大于点 c 距椭圆上点的最大距离

该定理是该方法的核心思想,也可表达为椭圆中心(P,Q)是平面上所有点中,距离椭圆轮廓上点最大距离最小的点

利用这一几何性质,降低Hough 参数空间的维度。这句话听起来比较别扭,意思很简单。

通俗的说,就是计算 图像中每一点与椭圆(椭圆边界)最远的距离L,其中,L最小的点就是椭圆的中心,L就是椭圆的短轴a .

 

算法的具体步骤:

  • 1)首先对图像进行边缘检测,得到二值化的边缘轮廓图,将边缘图上的点坐标存入数组 A。 
  • 2)对图像上的每一点, 计算与上一步所得数组 A 中点的距离,得到每一点距数组 A 中点的最大距离,所有点中最大距离最小的点,即是椭圆中心(p, q),该最大距离即是椭圆长轴长度 a。
  • 3)将数组A中每一点的数值和刚才得到的3个椭圆参数p、q、a 代入椭圆方程 (1)。
  • 4)在二维参数空间上对参数 b、θ 进行统计,得到峰值超过一定阈值的一组参数即为椭圆。  

 

实验结果:

结果分析:本文运用了椭圆的几何性质,把hough参数空间减少到2维。减少了运算量。由于第一步要得到椭圆的轮廓图,如果,图像中几个椭圆有重叠部分,无法保证提取的轮廓是一个椭圆,则无法检测出椭圆。

openCV代码(VS2010+opencv2.4.11):http://download.csdn.net/detail/u012507022/9405763

Matlab代码:

  1. clc  
  2. clear all  
  3. I = imread('22.png');  
  4. [m,n,L] = size(I);       %m图像的高度,n图像的宽度,L通道数  
  5. if L>1          
  6.     I = rgb2gray(I);  
  7. end  
  8. BW1 = edge(I,'sobel');    %自动选择阈值用Sobel算子进行边缘检测(二值化)  
  9.   
  10. figure(1)  
  11. subplot(121)  
  12. imshow(BW1); title('边缘检测');  
  13. se = strel('square',2);  
  14. BW=imdilate(BW1,se);%图像A1被结构元素B膨胀  
  15.   
  16. hough_circle=zeros(m,n,3);  
  17. [Limage, num] = bwlabel(BW,8);   %num 连通区域个数  
  18. for N=1:num  
  19.       
  20.     %[rows,cols] = find(BW);  % 找出二值图中的所有非零元素,并将这些元素的线性索引值返回到[rows,cols]  即找出边缘  
  21.       [rows,cols] = find(Limage==N);  % 找出二值图中的所有非零元素,并将这些元素的线性索引值返回到[rows,cols]  即找出边缘  
  22.       pointL=length(rows);      %非零元素个数,椭圆的周长  
  23.   
  24.         max_distan=zeros(m,n);  
  25.         distant=zeros(1,pointL);  
  26.         for i=1:m    
  27.             for j=1:n  
  28.                 for k=1:pointL  
  29.                     distant(k)=sqrt((i-rows(k))^2+(j-cols(k))^2); %计算所有点 到椭圆边界的点的距离  
  30.                 end  
  31.             max_distan(i,j)=max(distant);  %(i,j)点到椭圆边界的最大距离  
  32.             end  
  33.         end  
  34.         min_distan=min(min(max_distan));   %图像中所有的点到椭圆边界最大距离 的最小值,这个最小值对应的坐标位置 就是椭圆的中心。  
  35.   
  36.   
  37.         [center_yy,center_xx] = find(min_distan==max_distan);  %检索出椭圆中心的位置,  
  38.         center_y=(min(center_yy)+max(center_yy))/2;            %由于计算误差,椭圆中心可能是一簇点,所以选择中心点  
  39.         center_x=(min(center_xx)+max(center_xx))/2;            %center_x,center_y为椭圆的中心  
  40.         a=min_distan;                                          %a为椭圆的长轴  
  41.     %%  下面进行Hough变换  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  
  42.         hough_space = zeros(round(a+1),180);     %Hough空间  
  43.         for k=1:pointL  
  44.             for w=1:180      %theta  
  45.                 G=w*pi/180; %角度转换为弧度  
  46.                 XX=((cols(k)-center_x)*cos(G)+(rows(k)-center_y)*sin(G))^2/(a^2);  
  47.                 YY=(-(cols(k)-center_x)*sin(G)+(rows(k)-center_y)*cos(G))^2;  
  48.                 B=round(sqrt(abs(YY/(1-XX)))+1);  
  49.                 if(B>0&&B<=a)   %  计算时,B的值可能很大,这里进行异常处理  
  50.                      hough_space(B,w)=hough_space(B,w)+1;  
  51.                 end  
  52.             end  
  53.         end  
  54.   
  55.      %%  搜索超过阈值的聚集点  
  56.         max_para = max(max(max(hough_space)));  % 找出累积最大值  
  57.   
  58.         [bb,ww] = find(hough_space>=max_para);  %找出累积最大值在hough_space位置坐标(坐标值就是b和 theta)  
  59.         if(max_para<=pointL*0.33*0.25)     % 如果累积最大值 不足一定的阈值  则判断不存在椭圆  
  60.            disp('No ellipse');   
  61.            return ;  
  62.         end  
  63.         b=max(bb);                   %  b为椭圆的短轴  
  64.         W=min(ww);                          % %theta  
  65.         theta=W*pi/180;  
  66.   
  67.   
  68.       %% 标记椭圆  
  69.          
  70.       for k=1:pointL  
  71.                 XXX=((cols(k)-center_x)*cos(theta)+(rows(k)-center_y)*sin(theta))^2/(a^2);  
  72.                 YYY=(-(cols(k)-center_x)*sin(theta)+(rows(k)-center_y)*cos(theta))^2/(b^2);  
  73.                 if((XXX+YYY)<=1)   %实心椭圆  
  74.                  %if((XXX+YYY)<=1.1&&(XXX+YYY)>=0.99)  % 椭圆轮廓  
  75.                     hough_circle(rows(k),cols(k),1) = 255;  
  76.                       
  77.                 end  
  78.       end  
  79.        
  80. end  
  81.    subplot(122)  
  82.    imshow(hough_circle);title('检测结果');title('检测结果');  

 参考文献:

[1] 周 祥,孔晓东,曾贵华.一种新的基于 Hough 变换的椭圆轮廓检测方法


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:209381次
    • 积分:4182
    • 等级:
    • 排名:第7374名
    • 原创:132篇
    • 转载:543篇
    • 译文:0篇
    • 评论:18条
    最新评论