Обнаружение эллипса с использованием преобразования Хафа - PullRequest
6 голосов
/ 10 июня 2011

с помощью преобразования Хафа, как я могу обнаружить и получить координаты (x0, y0) и "a" и "b" эллипса в 2D-пространстве?

Это 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

Ответы [ 4 ]

2 голосов
/ 05 марта 2014

Хотя это старый вопрос, возможно, то, что я нашел, может кому-то помочь.

Основной проблемой использования обычного преобразования Хафа для обнаружения эллипсов является размерность аккумулятора, поскольку нам нужно будет проголосовать за 5 переменных (уравнение объясняется здесь ):

ellipse equation

Существует очень хороший алгоритм , где аккумулятором может быть, например, простой одномерный массив, который работает в O3. Если вы хотите увидеть код, вы можете посмотреть здесь (изображение, использованное для тестирования, было выше).

2 голосов
/ 10 июня 2011

Если вы используете кружок для грубого преобразования, то оно определяется как rho = x cos (theta) + y sin (theta) Для эллипса, так как это enter image description here

Вы можете преобразовать уравнение как rho = a x cos (тета) + b y sin (тета) Хотя я не уверен, что если вы используете стандартное преобразование Хафа, для эллипсоподобных преобразований вы могли бы манипулировать первой данной функцией.

1 голос
/ 28 января 2016

Если ваш эллипс такой, как он есть, он является настоящим эллипсом, а не шумным образцом точек;поиск двух самых дальних точек дает концы большой оси, поиск двух ближайших точек дает концы малой оси, пересечение этих линий (вы можете проверить, что это прямой угол) происходит в центре.

0 голосов
/ 10 июня 2011

Если вы знаете «a» и «b» эллипса, то вы можете изменить масштаб изображения с коэффициентом a / b в одном направлении и искать круг.Я все еще думаю о том, что делать, когда a и b неизвестны.

Если вы знаете, что это круг, используйте преобразование Хафа для кругов.Вот пример кода:

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 );
    }    
...