Виявлення кола в галасливих даних зображення


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) [рядок col] = find (bw); contour = bwtraceboundary (bw, рядок (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);

Альтернативні підходи будуть оцінені ...


Хоф трансформація шукає коло, а не заповнений диск. спочатку потрібно зробити виявлення ребер, щоб перетворити заповнений диск у порожнє коло. які властивості ваших кіл? чи постійний розмір? вони можуть бути еліпсами? Чи можна розподілити точки по-різному?
ендоліт

Я спробував (див. Відредагований приклад), він занадто галасливий, або недостатньо круговий? Крім того, розмір є постійним, і він може мати хвилинну еліптичність (хоча насправді це ідеально кругле вікно) через помилку кута камери.
бла

якщо розмір і форма постійні, ви можете спробувати щось на зразок перехресного співвіднесення заповненого шаблону диска з оригінальним крапковим зображенням
ендоліт

Окрім моєї відповіді, я думаю, що ви, можливо, намагаєтесь це зробити на занадто пізній стадії вашої обробки зображень. Чи можете ви розповісти більше про проблему та показати кілька попередніх кроків?
Андрій Рубштейн

Відповіді:


13

Ось моє рішення, воно близьке до ідеї @ Yoda, але я змінив деякі кроки.

  • Позначте всі пікселі таким чином, щоб у їх сусідньому районі 7x7 було принаймні 6 пікселів
  • Видаліть всі краплі, але найбільші
  • Заповніть отвори
  • Застосувати виявлення ребер
  • Знайдіть коло за допомогою перетворення Хоф

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

Ось відповідний код Matlab. Я використовую перетворення Hough для .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
Що тут робить трансформація Хаффа, що змушує її вирішити і знайти синє коло? Чи проектує безліч кіл різних радіусів у різних положеннях на зображенні і знаходить той, який найкраще підходить?
Спейсі

@Mohammad, це звичайний детектор кола. Він використовує бінінг та голосування.
Андрій Рубштейн

Ви також можете скористатися швидкою трансформацією радіальної симетрії (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]}]]
    


Дивовижна відповідь! Чи можете ви, будь ласка, розширити трансформацію розширення та наповнення?
Спейсі

@Mohammad дилатація є основною операцією і буде легко пояснити вікі статті. Трансформація заповнення заповнює "дірки" або іншими словами, набори пікселів, які оточені пікселями більш високого значення. Дивіться розділ "Додаткова інформація" тут
Lorem Ipsum

Ах вибачте, я неправильно набрав. Я дещо знайомий з дилатаційною трансформацією, мені було цікаво, чи можна розширити «заповнення перетворення». Яке правило встановлює воно саме? Я, здається, не можу знайти інформацію, пов’язану з цим. Можливо, це переходить під іншою назвою?
Спейсі

@yoda, дякую за відповідь, але якщо ти прочитаєш питання, то помітив би, я спробував розширення та пристосування. Зображення, створене до того, як я виявити краї, схоже на ваше. Я підхожу, це не точно. Те ж саме стосується вашого пристосування, ви бачите, що верхня частина приталеного кола занадто велика, імовірно, тому що ви враховуєте шумну точку у верхній частині над колом. Я також спробував помістити еліпс (як зазначено в питанні), проблема полягає в тому, що примірник недостатньо хороший. Я думаю, що, можливо, кращим способом було б використовувати кращу частину кола (дуги), щоб зробити пристосування.
бла

@nate Я не розумію, що ви маєте на увазі під "верхньою частиною встановленого кола" та "кращою частиною кола". Ви можете використовувати різні показники ... обмежувальне поле, основна довжина осі, незначна довжина осі, середня відстань від центроїда, середня відстань від центроїда тощо. Все залежить від того, що ви хочете.
Lorem Ipsum
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.