Обнаружьте и измерьте круговые объекты в изображении

Этот пример показывает, как использовать imfindcircles, чтобы автоматически обнаружить круги или круговые объекты в изображении. Это также показывает использование viscircles, чтобы визуализировать обнаруженные круги.

Шаг 1: Загрузка изображения

Этот пример использует изображение круглых пластмассовых микросхем различных цветов.

rgb = imread('coloredChips.png');
imshow(rgb)

Помимо наличия большого количества кругов, чтобы обнаружить, существует несколько интересных вещей, продолжающихся в этом изображении с круговой точки зрения обнаружения:

  1. Существуют микросхемы различных цветов, которые имеют различные контрасты относительно фона. На одном конце синие и красные единицы имеют сильный контраст на этом фоне. На другом конце некоторые желтые микросхемы не контрастируют хорошо с фоном.

  2. Заметьте, как некоторые микросхемы друг на друге и некоторые другие, которые близко друг к другу и почти касаются друг друга. Контуры перекрывающегося объекта и объектное поглощение газов обычно бросают вызов сценариям для обнаружения объектов.

Шаг 2: определите область значений радиуса для поиска кругов

imfindcircles нужна область значений радиуса, чтобы искать круги. Быстрый способ найти соответствующую область значений радиуса состоит в том, чтобы использовать интерактивный инструмент imdistline, чтобы получить аппроксимированную оценку радиусов различных объектов.

d = imdistline;

imdistline создает перемещаемый инструмент, который может быть перемещен, чтобы соответствовать через чип, и числа могут быть считаны, чтобы получить аппроксимированную оценку его радиуса. Большинство микросхем имеет радиус в области значений 21-23 пикселей. Используйте немного большую область значений радиуса 20-25 пикселей только, чтобы быть уверенными. Прежде чем это демонтирует инструмент imdistline.

delete(d)

Шаг 3: начальная попытка найти круги

Вызовите imfindcircles на этом изображении с поисковым радиусом [20 25] пиксели. Перед этим это - хорошая практика, чтобы спросить, являются ли объекты более яркими или более темными, чем фон. Чтобы ответить на тот вопрос, посмотрите на полутоновую версию этого изображения.

gray_image = rgb2gray(rgb);
imshow(gray_image)

Фон довольно ярок, и большинство микросхем является более темным, чем фон. Но по умолчанию imfindcircles находит круговые объекты, которые более ярки, чем фон. Так, установите параметр 'ObjectPolarity' на 'темный' в imfindcircles, чтобы искать темные круги.

[centers,radii] = imfindcircles(rgb,[20 25],'ObjectPolarity','dark')
centers =

     []


radii =

     []

Обратите внимание на то, что выходные параметры centers и radii пусты, что означает, что никакие круги не были найдены. Это часто происходит, потому что imfindcircles является круговым детектором, и подобный большинству детекторов, imfindcircles имеет внутренний порог обнаружения, который определяет его чувствительность. Простыми словами это означает, что уверенность детектора в определенном (круговом) обнаружении должна быть больше, чем определенный уровень, прежде чем это будет рассмотрено допустимым обнаружением. imfindcircles имеет параметр 'Чувствительность', которая может использоваться, чтобы управлять этим внутренним порогом, и следовательно, чувствительность алгоритма. Более высокая 'Чувствительность' наборы значений порог обнаружения понижается, и приводит к обнаружению большего количества кругов. Это подобно управлению чувствительностью на детекторах движения, используемых в домашних системах безопасности.

Шаг 4: увеличьте чувствительность обнаружения

Возвращаясь к изображению чипа, возможно, что на уровне уязвимости по умолчанию все круги ниже, чем внутренний порог, который является, почему никакие круги не были обнаружены. По умолчанию 'Чувствительность', которая является номером между 0 и 1, установлена в 0,85. Увеличьте 'Чувствительность' к 0,9.

[centers,radii] = imfindcircles(rgb,[20 25],'ObjectPolarity','dark', ...
    'Sensitivity',0.9)
centers = 8×2

  146.1895  198.5824
  328.8132  135.5883
  130.3134   43.8039
  175.2698  297.0583
  312.2831  192.3709
  327.1315  297.0081
  243.9893  166.4538
  271.5873  280.8920

radii = 8×1

   23.1604
   22.5710
   22.9576
   23.7356
   22.9551
   22.9929
   22.9055
   23.0298

На этот раз imfindcircles нашел, что некоторые круги - восемь были точны. centers содержит местоположения центров круга, и radii содержит предполагаемые радиусы тех кругов.

Шаг 5: нарисуйте круги на изображении

Функциональный viscircles может использоваться, чтобы нарисовать круги на изображении. Выходные переменные centers и radii от imfindcircles могут быть переданы непосредственно viscircles.

imshow(rgb)
h = viscircles(centers,radii);

Центры круга кажутся правильно расположенными, и их соответствующие радиусы, кажется, соответствуют хорошо к фактическим микросхемам. Но все еще довольно много микросхем были пропущены. Попытайтесь увеличить 'Чувствительность' еще больше, к 0,92.

[centers,radii] = imfindcircles(rgb,[20 25],'ObjectPolarity','dark', ...
    'Sensitivity',0.92);

length(centers)
ans = 16

Так увеличение 'Чувствительности' получает нас еще больше кругов. Постройте эти круги на изображении снова.

delete(h)  % Delete previously drawn circles
h = viscircles(centers,radii);

Шаг 6: используйте второй метод (2D этап) для нахождения кругов

Этот результат выглядит лучше. imfindcircles имеет два различных метода для нахождения кругов. До сих пор метод по умолчанию, названный методом кодирования фазы, использовался для обнаружения кругов. Существует другой метод, обычно названный методом 2D этапа, который доступен в imfindcircles. Используйте метод 2D этапа и покажите результаты.

[centers,radii] = imfindcircles(rgb,[20 25],'ObjectPolarity','dark', ...
          'Sensitivity',0.92,'Method','twostage');

delete(h)
h = viscircles(centers,radii);

Метод 2D этапа обнаруживает больше кругов в Чувствительности 0,92. В целом эти два, метод дополнителен в этом, сделали, у них есть различные сильные места. Метод кодирования Фазы обычно быстрее и немного более устойчив к шуму, чем метод 2D этапа. Но этому, возможно, также понадобятся более высокие уровни 'Чувствительности', чтобы получить то же количество обнаружений как метод 2D этапа. Например, метод кодирования фазы также находит те же микросхемы, если уровень 'Чувствительности' повышен выше, скажите 0,95.

[centers,radii] = imfindcircles(rgb,[20 25],'ObjectPolarity','dark', ...
          'Sensitivity',0.95);

delete(h)
viscircles(centers,radii);

Обратите внимание на то, что и методы в imfindcircles находят центры и радиусы частично видимых (закрытых) микросхем точно.

Шаг 7: Почему Некоторые Круги Все еще пропускаемый?

Смотря на последний результат, любопытно, что imfindcircles не находит желтые микросхемы в изображении. Желтые микросхемы не имеют сильного контраста с фоном. На самом деле у них, кажется, есть очень похожая интенсивность как фон. Действительно ли возможно, что желтые микросхемы не являются действительно 'более темными', чем фон, как был принят? Чтобы подтвердить, покажите полутоновую версию этого изображения снова.

imshow(gray_image)

Шаг 8: найдите 'яркие' круги в изображении

Желтые микросхемы являются почти той же интенсивностью, возможно, еще более яркой, по сравнению с фоном. Поэтому, чтобы обнаружить желтые микросхемы, измените 'ObjectPolarity' на 'яркий'.

[centersBright,radiiBright] = imfindcircles(rgb,[20 25], ...
    'ObjectPolarity','bright','Sensitivity',0.92);

Шаг 9: нарисуйте 'яркие' круги с различным цветом

Нарисуйте яркие круги в различном цвете путем изменения 'Цветного' параметра в viscircles.

imshow(rgb)

hBright = viscircles(centersBright, radiiBright,'Color','b');

Обратите внимание на то, что три из недостающих желтых микросхем были найдены, но один желтый чип все еще отсутствует. Эти желтые микросхемы трудно найти, потому что они не выделяются, а также другие на этом фоне.

Шаг 10: понизьте значение 'EdgeThreshold'

Существует другой параметр в imfindcircles, который может быть полезным здесь, а именно, 'EdgeThreshold'. Чтобы найти круги, imfindcircles использует только краевые пиксели в изображении. Эти краевые пиксели являются по существу пикселями с высоким значением градиента. Параметр 'EdgeThreshold' управляет, как высоко значение градиента на уровне пикселя должно быть, прежде чем это будет рассмотрено краевым пикселем и включено в вычисление. Высокое значение (ближе к 1) для этого параметра позволит только сильным ребрам (более высокие значения градиента) быть включенными, тогда как низкая стоимость (ближе к 0) является более разрешающей и включает даже более слабые ребра (более низкие значения градиента) в вычислении. В случае недостающего желтого чипа, поскольку контраст является низким, некоторые граничные пиксели (на окружности чипа), как ожидают, будут иметь низкие значения градиента. Поэтому понизьте параметр 'EdgeThreshold', чтобы гарантировать, что большинство краевых пикселей для желтого чипа включено в вычисление.

[centersBright,radiiBright,metricBright] = imfindcircles(rgb,[20 25], ...
    'ObjectPolarity','bright','Sensitivity',0.92,'EdgeThreshold',0.1);

delete(hBright)
hBright = viscircles(centersBright, radiiBright,'Color','b');

Шаг 11: нарисуйте 'темные' и 'яркие' круги вместе

Теперь imfindcircles находит все из желтых единиц и зеленого также. Чертите они входят в долю синий, вместе с другими микросхемами, которые были найдены ранее (с набором 'ObjectPolarity' к 'темному') в красном.

h = viscircles(centers,radii);

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

Счастливый круговой поиск!

Смотрите также

|

Похожие темы