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