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

В этом примере показано, как автоматически обнаружить круги или округлые предметы в изображении и визуализировать обнаруженные круги.

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

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

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

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

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

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

Найдите соответствующую область значений радиуса кругов с помощью drawline функция. Чертите линию по аппроксимированному диаметру чипа.

d = drawline;

Длина ROI линии является диаметром чипа. Типичные микросхемы имеют диаметры в области значений 40 - 50 пикселей.

pos = d.Position;
diffPos = diff(pos);
diameter = hypot(diffPos(1),diffPos(2))
diameter = 45.3448

Шаг 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.1316  297.0077
  243.9893  166.4538
  271.5873  280.8920

radii = 8×1

   23.1604
   22.5710
   22.9576
   23.7356
   22.9551
   22.9995
   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);

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

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

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

|

Похожие темы

Для просмотра документации необходимо авторизоваться на сайте