На этот раз я хотел бы продемонстрировать комбинированное знание обнаружения краев и свертки и использовать эти способности для анализа изображений, а не просто обработки. Я буду использовать силу, чтобы обнаружить монеты на картинке и нарисовать круг вокруг них!
У тех из вас, кто больше знаком с компьютерным зрением, может иметь момент «я вижу», думая о существующей функции, которая спасет меня много времени … Но так как я многообещающий падаван и хотел применить все с трудом заработанные знания, я пошел на труд, приняв подход «Никогда не говори мне о шансах» (соло, EP V). Хаха.
Ключевая логика опирается на пять петли
Если мы вернемся назад, чтобы нарисовать круг вокруг монет, мне нужно знать их радиус и координаты их центров. Чтобы получить это, я использовал свертку, что я здесь объясняю , чтобы сравнить монеты с эталонными кругами увеличения размера до тех пор, пока не будет выровнен более чем определенный процент краевых пикселей. Наконец, чтобы иметь возможность свернуть круги, мне нужно было найти край монет, которые я исследовал в Эта статья Анкет Звучит достаточно просто? Тем не менее, позвольте мне разбить подход к вам более подробно, если вы хотели бы попробовать его самостоятельно, на этот раз в правильном хронологическом порядке. Как всегда, все Доступно на GitHub Анкет
Шаг 1: Найдите края
Цель состоит в том, чтобы наметить монеты и найти их преимущество. Я использовал гауссовый размытие с ядром 5×5 и обнаружением хитрых краев, чтобы найти края. Вот результаты.
Шаг 2: Сгенерируйте эталонные круги (первые две петли)
Нарисуйте круги на отдельном изображении от наименьшего до самого большого (я проверил радиус самой маленькой и самой большой монеты на изображении, чтобы установить границы). С каждой итерацией увеличивает радиус одним пикселем. Используя другой цикл, сохраните координаты краевых пикселей в список.
Шаг 2.1: Переместите ссылочный круг через изображение монеты (третий цикл)
Для каждого эталонного круга, сгенерированного ранее, перемещайте центр эталонного круга через изображение монеты. Оптимизируйте границы изображения монет, так как нет смысла выравнивать центр контрольного круга с первым угловым пикселем изображения монеты.
Шаг 2.1.1: Выравнивание эталонных кругов с краями монет (четвертая петля)
Для каждой позиции эталонного круга в исходном изображении монеты переверните список координат круга и согласовывает их положение с исходным изображением. Здесь нам нужно установить два порогового значения. Во -первых, это крайний порог, то есть сколько краевых пикселей нужно соответствовать опорному кругу, чтобы рассматриваться достаточно. Второй порог – это порог интенсивности, то есть минимальная белизну края пикселя, все еще считается частью края. Если оба порога передаются, то рассмотрите выравнивание как идентифицированную монету.
Шаг 3: Нарисуйте круги вокруг монет (пятая петля)
Для всех идентифицированных радиусов монет и центральных координат нарисуйте круг на исходном изображении.
Давайте запустим это! ~ визг волнения! ~
В первый раз, когда я запустил код, я установил параметры для минимального и максимального радиуса 40 до 57, и у него был постоянный поток координат и радиусов, чтобы увидеть прогресс. Было поздно Поэтому я пошел спать, думая, что по утрам увижу красивые круги вокруг монет. Когда я встал и пошел проверить, программа просто проходила радиус 44. Я имею в виду, я ожидал, что функция будет работать медленнее, а Python будет интерпретированный язык , но это было немного экстремально.
Так что я оптимизировал. Некоторые переменные были выведены из петли и были предварительно обработаны и, следовательно, не рассчитывались по каждой итерации (например, окружность опорного круга). Другая радикальная оптимизация была изменение размера изображения до половины его размера. Это привело к в 4 раза быстрее, так как в петлях было меньше пикселей, чтобы пройти!
Да, есть более простой способ
Как я намекал в начале, есть, конечно, более простой и гораздо более точный способ обнаружения кругов в OpenCV, так называемый Трансформация круга Hough (Вот ссылка на альтернативное объяснение Не только функция дает один результат на круг (в отличие от ручного способа, как вы можете видеть ниже), но и поскольку OpenCV имеет реализацию в C ++, который является составленным языком, она также работает намного быстрее.
def hough_circle_detection(coins, min_r, max_r): # turn original image to grayscale gray = cv2.cvtColor(coins, cv2.COLOR_BGR2GRAY) # blur grayscale image blurred = cv2.medianBlur(gray, 5) return cv2.HoughCircles( blurred, # source image (blurred and grayscaled) cv2.HOUGH_GRADIENT, # type of detection 1, # inverse ratio of accumulator res. to image res. 40, # minimum distance between the centers of circles param1=50, # Gradient value passed to edge detection param2=30, # accumulator threshold for the circle centers minRadius=min_r*2, # min circle radius maxRadius=max_r*2, # max circle radius )
Вот последнее сравнение
Самая большая проблема для меня состояла в том, чтобы обернуть мою голову вокруг всех вложенных петель. Большинство помогло, чтобы буквально вытащить петли, чтобы визуально увидеть логику. Выяснить, как точно сделать выравнивание круга сравнения на исходном изображении было еще одним жестким. Конечно, есть множество возможностей для улучшения, но в целом я очень доволен результатами. Надеюсь, вам понравился пост, и, как обычно, пожелает некоторая обратная связь:) Да пребудет с тобой питон.
Оригинал: “https://dev.to/tinazhouhui/coin-detection-discovering-opencv-with-python-1ka1”