Этот пример показывает, как использовать imfindcircles
, чтобы автоматически обнаружить круги или круговые объекты в изображении. Это также показывает использование viscircles
, чтобы визуализировать обнаруженные круги.
Этот пример использует изображение круглых пластмассовых микросхем различных цветов.
rgb = imread('coloredChips.png');
imshow(rgb)
Помимо наличия большого количества кругов, чтобы обнаружить, существует несколько интересных вещей, продолжающихся в этом изображении с круговой точки зрения обнаружения:
Существуют микросхемы различных цветов, которые имеют различные контрасты относительно фона. На одном конце синие и красные единицы имеют сильный контраст на этом фоне. На другом конце некоторые желтые микросхемы не контрастируют хорошо с фоном.
Заметьте, как некоторые микросхемы друг на друге и некоторые другие, которые близко друг к другу и почти касаются друг друга. Контуры перекрывающегося объекта и объектное поглощение газов обычно бросают вызов сценариям для обнаружения объектов.
imfindcircles
нужна область значений радиуса, чтобы искать круги. Быстрый способ найти соответствующую область значений радиуса состоит в том, чтобы использовать интерактивный инструмент imdistline
, чтобы получить аппроксимированную оценку радиусов различных объектов.
d = imdistline;
imdistline
создает перемещаемый инструмент, который может быть перемещен, чтобы соответствовать через чип, и числа могут быть считаны, чтобы получить аппроксимированную оценку его радиуса. Большинство микросхем имеет радиус в области значений 21-23 пикселей. Используйте немного большую область значений радиуса 20-25 пикселей только, чтобы быть уверенными. Прежде чем это демонтирует инструмент imdistline
.
delete(d)
Вызовите 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
имеет параметр 'Чувствительность', которая может использоваться, чтобы управлять этим внутренним порогом, и следовательно, чувствительность алгоритма. Более высокая 'Чувствительность' наборы значений порог обнаружения понижается, и приводит к обнаружению большего количества кругов. Это подобно управлению чувствительностью на детекторах движения, используемых в домашних системах безопасности.
Возвращаясь к изображению чипа, возможно, что на уровне уязвимости по умолчанию все круги ниже, чем внутренний порог, который является, почему никакие круги не были обнаружены. По умолчанию 'Чувствительность', которая является номером между 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
содержит предполагаемые радиусы тех кругов.
Функциональный 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);
Этот результат выглядит лучше. 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
находят центры и радиусы частично видимых (закрытых) микросхем точно.
Смотря на последний результат, любопытно, что imfindcircles
не находит желтые микросхемы в изображении. Желтые микросхемы не имеют сильного контраста с фоном. На самом деле у них, кажется, есть очень похожая интенсивность как фон. Действительно ли возможно, что желтые микросхемы не являются действительно 'более темными', чем фон, как был принят? Чтобы подтвердить, покажите полутоновую версию этого изображения снова.
imshow(gray_image)
Желтые микросхемы являются почти той же интенсивностью, возможно, еще более яркой, по сравнению с фоном. Поэтому, чтобы обнаружить желтые микросхемы, измените 'ObjectPolarity' на 'яркий'.
[centersBright,radiiBright] = imfindcircles(rgb,[20 25], ... 'ObjectPolarity','bright','Sensitivity',0.92);
Нарисуйте яркие круги в различном цвете путем изменения 'Цветного' параметра в viscircles
.
imshow(rgb) hBright = viscircles(centersBright, radiiBright,'Color','b');
Обратите внимание на то, что три из недостающих желтых микросхем были найдены, но один желтый чип все еще отсутствует. Эти желтые микросхемы трудно найти, потому что они не выделяются, а также другие на этом фоне.
Существует другой параметр в 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');
Теперь imfindcircles
находит все из желтых единиц и зеленого также. Чертите они входят в долю синий, вместе с другими микросхемами, которые были найдены ранее (с набором 'ObjectPolarity' к 'темному') в красном.
h = viscircles(centers,radii);
Все круги обнаруживаются. Итоговое слово - нужно отметить, что изменение параметров, чтобы быть более агрессивным в обнаружении может найти больше кругов, но это также увеличивает вероятность обнаружения ложных кругов. Существует компромисс между количеством истинных кругов, которые могут быть найдены (процент раскрытых преступлений) и количество ложных кругов, которые найдены с ними (ложный сигнальный уровень).
Счастливый круговой поиск!