Обнаружение круга в данных изображения с шумом

17

У меня есть изображение, которое выглядит как показано ниже: введите описание изображения здесь

Я пытаюсь найти радиус (или диаметр) круга. Я попытался использовать круговое преобразование Хафа (с помощью Matlab's imfindcircles(bw,[rmin rmax],'ObjectPolarity','bright')) и подгонку к кругу или эллипсу (домашняя функция, которая работает довольно хорошо для менее шумных данных, см. Ниже).

Я также попробовал некоторую обработку изображений, чтобы получить более четкий круг, например, см. Ниже:

se = strel('disk', 2);
bw = imdilate(bw, se);
bw = bwareaopen(bw,100000); 
bw =  edge(bw); 

введите описание изображения здесь

Однако, когда я передаю обработанное изображение любым из методов (аппроксимация Хафа и круга \ эллипса), ни одному из них не удается обнаружить круг достойным образом.

Вот фрагмент кода искателя круга, который я написал (matlab) [row col] = find (bw); contour = bwtraceboundary (bw, row (1), col (1)], 'N', связность, num_points);

    x = contour(:,2);
    y = contour(:,1);

    % solve for parameters a, b, and c in the least-squares sense by
    % using the backslash operator
    abc = [x y ones(length(x),1)] \ -(x.^2+y.^2);
    a = abc(1); b = abc(2); c = abc(3);

    % calculate the location of the center and the radius
    xc = -a/2;
    yc = -b/2;
    radius  =  sqrt((xc^2+yc^2)-c);

Будут оценены альтернативные подходы ...

бла
источник
Hough transform ищет круг, а не заполненный диск. вам нужно было бы сначала обнаружить края, чтобы преобразовать заполненный диск в пустой круг. каковы свойства ваших кругов? размер постоянен? могут ли они быть эллипсами? точки могут быть распределены по-другому?
эндолит
Я пытался (см. Отредактированный пример), он слишком шумный или недостаточно круглый? Кроме того, размер является постоянным и может иметь незначительную эллиптичность (хотя в действительности это идеально круглое окно) из-за ошибки угла обзора камеры.
бла
если размер и форма постоянны, вы можете попробовать что-то вроде взаимной корреляции заполненного шаблона диска с исходным точечным изображением
эндолит
Помимо моего ответа, я думаю, что вы, возможно, пытаетесь сделать это на более поздней стадии процесса обработки изображений. Не могли бы вы рассказать нам больше о проблеме и показать некоторые предыдущие шаги?
Андрей Рубштейн

Ответы:

13

Вот мое решение, оно близко к идее @ Йоды, но я изменил некоторые шаги.

  • Пометить все пиксели так, чтобы их окрестности были не менее 6 пикселей
  • Удалить все капли, но самые большие
  • Заполнить отверстия
  • Применить обнаружение края
  • Найти круг с помощью преобразования Хафа

введите описание изображения здесь введите описание изображения здесь введите описание изображения здесь введите описание изображения здесь введите описание изображения здесь

Вот соответствующий код Matlab. Я использую преобразование Хафа для файла .m в моем коде.

function FindCircle()
    close all;
    im = imread('C:\circle.png');
    im = im(:,:,2);

    ims = conv2(double(im), ones(7,7),'same');
    imbw = ims>6;
    figure;imshow(imbw);title('All pixels that there are at least 6 white pixels in their hood');

    props = regionprops(imbw,'Area','PixelIdxList','MajorAxisLength','MinorAxisLength');
    [~,indexOfMax] = max([props.Area]);
    approximateRadius =  props(indexOfMax).MajorAxisLength/2;

    largestBlobIndexes  = props(indexOfMax).PixelIdxList;
    bw = false(size(im));
    bw(largestBlobIndexes) = 1;
    bw = imfill(bw,'holes');
    figure;imshow(bw);title('Leaving only largest blob and filling holes');
    figure;imshow(edge(bw));title('Edge detection');

    radiuses = round ( (approximateRadius-5):0.5:(approximateRadius+5) );
    h = circle_hough(edge(bw), radiuses,'same');
    [~,maxIndex] = max(h(:));
    [i,j,k] = ind2sub(size(h), maxIndex);
    radius = radiuses(k);
    center.x = j;
    center.y = i;

    figure;imshow(edge(bw));imellipse(gca,[center.x-radius  center.y-radius 2*radius 2*radius]);
    title('Final solution (Shown on edge image)');

    figure;imshow(im);imellipse(gca,[center.x-radius  center.y-radius 2*radius 2*radius]);
    title('Final solution (Shown on initial image)');

end
Андрей Рубштейн
источник
1
Что здесь делает преобразование Хафа, которое заставляет его решать и находить синий круг? Проецирует ли много кругов с разными радиусами в разные позиции на изображении и находит тот, который лучше всего подходит?
Спейси
@ Мохаммед, это обычный круговой детектор. Использует биннинг и голосование.
Андрей Рубштейн
Вы также можете использовать быстрое преобразование радиальной симметрии (FRST) после первого шага в этом ответе.
Geniedesalpages
10

Это довольно просто сделать с помощью обработки изображений. Следующее является доказательством концепции в Mathematica . Вам придется перевести его на MATLAB.

  • Во-первых, обрежьте оси и оставьте только часть изображения. Я называю эту переменную img.
  • Бинаризируйте изображение и расширяйте его, а затем заполняющее преобразование. Я также удаляю паразитные мелкие компоненты, которые не связаны с основным объектом. Это должно дать вам что-то вроде следующего:

    filled = Binarize@img ~Dilation~ 3 // FillingTransform // DeleteSmallComponents
    

  • Затем найдите центр тяжести этого большого двоичного объекта и эквивалентный радиус диска большого двоичного объекта (openCV, MATLAB имеют эквивалентные команды для этого)

    {center, radius} = 1 /. ComponentMeasurements[filled, {"Centroid", "EquivalentDiskRadius"}]
    
  • Это оно! Теперь нарисуйте исходное изображение и круг с указанным выше центром и радиусом, чтобы увидеть, как оно подходит:

    Show[img, Graphics[{Red, Circle[center, radius]}]]
    

Лорем Ипсум
источник
Отличный ответ! Можете ли вы расширить трансформацию расширения и заполнения?
Spacey
@Mohammad дилатация является основной операцией и будет легко объяснить вики статьи. Заполнение преобразования заполняет «дыры» или, другими словами, наборы пикселей, которые окружены пикселями более высокого значения. Смотрите раздел «Дополнительная информация» здесь
Lorem Ipsum
Ах, прости, я неправильно набрал. Я немного знаком с дилатационным преобразованием, мне было интересно, не могли бы вы рассказать о «заполняющем преобразовании». Какой набор правил он использует именно? Я не могу найти информацию, связанную с этим. Возможно, это идет под другим именем?
Spacey
@yoda, спасибо за ответ, но если вы прочитаете вопрос, вы заметите, что я попробовал расширение и подгонку. Изображение, полученное до того, как я обнаружил края, похоже на ваше. Я получаю некоторую форму, это не точно. То же самое касается вашей посадки, вы можете видеть, что верхняя часть подогнанного круга слишком велика, вероятно, потому что вы принимаете во внимание шумную точку в верхней части над кружком. Я также попытался вписать эллипс (как указано в вопросе), проблема в том, что подгонка недостаточно хороша. Я думаю, что, возможно, лучшим способом было бы использовать лучшую часть круга (дугу) для подгонки.
бла
@nate Я не понимаю, что вы подразумеваете под "верхней частью подогнанного круга" и "лучшей частью круга". Вы можете использовать различные метрики ... ограничивающий прямоугольник, длину главной оси, длину вспомогательной оси, среднее расстояние от центроида, среднее расстояние от центроида и т. Д. Все зависит от того, что вы хотите.
Lorem Ipsum