houghlines hough algorithm matlab hough-transform

algorithm - houghlines - Detección de elipse usando Hough Transform



matlab hough-transform (4)

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

Esto es ellipse01.bmp:

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


Si usa el círculo para la transformación aproximada se da como rho = xcos (theta) + y sin (theta) Para la elipse ya que es

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


Si conoce la ''a'' y la ''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 sabes que es un círculo, utiliza 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 ); }


Si su elipse es como se proporciona, 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 mayor, la búsqueda de los dos puntos más cercanos da los extremos del eje menor, la intersección de estas líneas (puede verificar que es un ángulo recto) ocurre en el centro.


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

El principal problema de usar la Transformada Hough normal para detectar elipses es la dimensión del acumulador, ya que tendríamos que votar por 5 variables (la ecuación se explica aquí ):

Hay un algoritmo muy bueno en el que el acumulador puede ser una matriz 1D simple, por ejemplo, y que se ejecuta en . Si quieres ver el código, puedes mirarlo aquí (la imagen utilizada para probar fue la publicada anteriormente).