2011-06-10 27 views
5

usando Hough Transform, ¿cómo puedo detectar y obtener coordenadas de (x0, y0) y "a" y "b" de una elipse en el espacio 2D?Detección de elipse usando Hough Transform

Ésta es ellipse01.bmp:

ellipse image

I = imread('ellipse01.bmp'); 
[m n] = size(I); 
c=0; 
for i=1:m 
    for j=1:n 
     if I(i,j)==1 
     c=c+1; 
     p(c,1)=i; 
     p(c,2)=j; 
     end 
    end 
end 
Edges=transpose(p); 
Size_Ellipse = size(Edges); 
B = 1:ceil(Size_Ellipse(1)/2); 
Acc = zeros(length(B),1); 
a1=0;a2=0;b1=0;b2=0; 
Ellipse_Minor=[];Ellipse_Major=[];Ellipse_X0 = [];Ellipse_Y0 = []; 
Global_Threshold = ceil(Size_Ellipse(2)/6);%Used for Major Axis Comparison 
Local_Threshold = ceil(Size_Ellipse(1)/25);%Used for Minor Axis Comparison 
[Y,X]=find(Edges); 
Limit=numel(Y); 
Thresh = 150; 
Para=[]; 

for Count_01 =1:(Limit-1) 
    for Count_02 =(Count_01+1):Limit 
    if ((Count_02>Limit) || (Count_01>Limit)) 
     continue 
    end 
    a1=Y(Count_01);b1=X(Count_01); 
    a2=Y(Count_02);b2=X(Count_02); 
    Dist_01 = (sqrt((a1-a2)^2+(b1-b2)^2)); 
    if (Dist_01 >Global_Threshold) 
     Center_X0 = (b1+b2)/2;Center_Y0 = (a1+a2)/2; 
     Major = Dist_01/2.0;Alpha = atan((a2-a1)/(b2-b1)); 
     if(Alpha == 0) 
     for Count_03 = 1:Limit 
      if((Count_03 ~= Count_01) || (Count_03 ~= Count_02)) 
      a3=Y(Count_03);b3=X(Count_03); 
      Dist_02 = (sqrt((a3 - Center_Y0)^2+(b3 - Center_X0)^2)); 
      if(Dist_02 > Local_Threshold) 
       Cos_Tau = ((Major)^2 + (Dist_02)^2 - (a3-a2)^2 - (b3-b2)^2)/(2*Major*Dist_02); 
       Sin_Tau = 1 - (Cos_Tau)^2; 
       Minor_Temp = ((Major*Dist_02*Sin_Tau)^2)/(Major^2 - ((Dist_02*Cos_Tau)^2)); 
       if((Minor_Temp>1) && (Minor_Temp<B(end))) 
       Acc(round(Minor_Temp)) = Acc(round(Minor_Temp))+1; 
       end 
      end 
      end 
     end 
     end 
     Minor = find(Acc == max(Acc(:))); 
     if(Acc(Minor)>Thresh) 
     Ellipse_Minor(end+1)=Minor(1);Ellipse_Major(end+1)=Major; 
     Ellipse_X0(end+1) = Center_X0;Ellipse_Y0(end+1) = Center_Y0; 
     for Count = 1:numel(X) 
      Para_X = ((X(Count)-Ellipse_X0(end))^2)/(Ellipse_Major(end)^2); 
      Para_Y = ((Y(Count)-Ellipse_Y0(end))^2)/(Ellipse_Minor(end)^2); 
      if (((Para_X + Para_Y)>=-2)&&((Para_X + Para_Y)<=2)) 
      Edges(X(Count),Y(Count))=0; 
      end 
     end 
     end 
     Acc = zeros(size(Acc)); 
    end 
    end 
end 
+0

? Http: //en.wikipedia.org/wiki/Hough_transform#Implementation_of_an_Efficient_Ellipse_Detection_Algorithm –

+0

Intenté implementar ese algoritmo con MATLAB, sin embargo, no funciona correctamente. Creo que no lo implementé correctamente. Por favor revise la pregunta nuevamente. – Ata

+0

Esta implementación está copiada de http://en.wikipedia.org/wiki/Hough_transform# – Ata

Respuesta

2

Si utiliza círculo para transformar bruto se da como rho = x cos (theta) + y sen (theta) Para elipse ya que es enter image description here

se podría transformar la ecuación como rho = a x cos (theta) + b y sin (theta) Aunque no estoy seguro si usa Transformada Hough estándar, para transformaciones similares a elipse, podría manipular la primera función dada.

+0

Como saben, tenemos una imagen en la que solo hay una elipse sin información. (No sabemos "a", "b" y "(x0, y0)"). deberíamos usar la transformada Hough para descubrir estos parámetros. – Ata

0

Si conoce la 'a' y 'b' de una elipse, puede cambiar la escala de la imagen por factor de a/b en una dirección y buscar el círculo. Todavía estoy pensando qué hacer cuando a y b son desconocidos.

Si sabe que es un círculo, utilice la transformación Hough para círculos. Aquí hay un código de muestra:

int accomulatorResolution = 1; // for each pixel 
    int minDistBetweenCircles = 10; // In pixels 
    int cannyThresh   = 20; 
    int accomulatorThresh  = 5*_accT+1; 
    int minCircleRadius  = 0; 
    int maxCircleRadius  = _maxR*10; 
    cvClearMemStorage(storage); 
    circles = cvHoughCircles(gryImage, storage, 
           CV_HOUGH_GRADIENT, accomulatorResolution, 
           minDistBetweenCircles, 
           cannyThresh , accomulatorThresh, 
           minCircleRadius,maxCircleRadius);  
    // Draw circles 
    for (int i = 0; i < circles->total; i++){ 
     float* p = (float*)cvGetSeqElem(circles,i); 
     // Draw center 
     cvCircle(dstImage, cvPoint(cvRound(p[0]),cvRound(p[1])), 
          1, CV_RGB(0,255,0), -1, 8, 0); 
     // Draw circle 
     cvCircle(dstImage, cvPoint(cvRound(p[0]),cvRound(p[1])), 
          cvRound(p[2]),CV_RGB(255,0,0), 1, 8, 0); 
    }  
+0

En realidad, no sabemos 'a' y 'b'. pero por ahora, supongamos que es un círculo (a = b). qué algoritmo debemos seguir para calcular Radius y (x0, y0)? – Ata

+0

Agregué una muestra de código en mi respuesta anterior – DanielHsH

1

Aunque esta es una vieja pregunta, tal vez lo que encontré puede ayudar a alguien.

El principal problema de la utilización de Hough normales Transform para detectar elipses es la dimensión del acumulador, ya que tendríamos que votar por 5 variables (la ecuación se explica here):

ellipse equation

Hay es una muy buena algorithm donde el acumulador puede ser una simple matriz 1D, por ejemplo, y que se ejecuta en O3. Si quieres ver el código, puedes mirar here (la imagen utilizada para probar fue publicada anteriormente).

1

Si su elipse es como se proporcionó, siendo una verdadera elipse y no una muestra ruidosa de puntos; la búsqueda de los dos puntos más lejanos da los extremos del eje principal, la búsqueda de los dos puntos más cercanos da los extremos del eje menor, la intersección de estas líneas (puede comprobar que es un ángulo recto) se produce en el centrar.