Обнаружение серебра и отражающих шаров с OpenCV

Я пытаюсь обнаружить серебряные шары, отражающие окружающую среду, с помощью OpenCV: серебряный шар

С черными шарами я успешно сделал это, обнаружив круги:

gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

gray = cv2.GaussianBlur(gray,(5,5),0);
gray = cv2.medianBlur(gray,5)

gray = cv2.adaptiveThreshold(gray,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY,11,3.5)

kernel = np.ones((3,3),np.uint8)

gray = cv2.erode(gray,kernel,iterations = 1)

gray = cv2.dilate(gray,kernel,iterations = 1)

circles = cv2.HoughCircles(gray, cv.CV_HOUGH_GRADIENT, 1, 260, \
                    param1=30, param2=65, minRadius=0, maxRadius=0)

Но при использовании программы с серебряными шарами мы не получаем никакого результата.

Если посмотреть на края, рассчитанные программой, края шара довольно острые. Но Кодекс не признает мяч.

края серебряного шара

Как улучшить скорость обнаружения серебряного шара? Я думаю о двух способах сделать это: - Улучшение расчета краев - Заставить обнаружение круга принимать изображение с нечеткими краями. Возможно ли это? Как лучше всего это сделать?

Помощь очень ценится.


person fecavy    schedule 04.04.2018    source источник
comment
Если фон, который у вас есть, является репрезентативным, вы можете попробовать определить конкретный цвет, что даст вам изрядную долю шара для начала. 1. Преобразовать в HSV. Используйте InRagnge для вашего конкретного цветового диапазона   -  person GPPK    schedule 04.04.2018
comment
Соответствуют ли ваши параметры синтетическому кругу такого же размера? Пробовали ли вы другие методы обнаружения краев, чтобы получить лучший замкнутый контур? (минимальный воспроизводимый пример)   -  person handle    schedule 04.04.2018


Ответы (1)


Вам нужно настроить свои параметры. Функция HoughCircles отлично справляется с обнаружением кругов (даже с промежутками). Обратите внимание, что HoughCircles выполняет внутреннюю бинаризацию, используя хитрое обнаружение краев. Таким образом, вам не нужно устанавливать пороговые значения.

Учитывая ваше изображение выше, код

import cv2
from matplotlib import pyplot as plt
import numpy as np

PATH = 'path/to/the/image.jpg'    

img = cv2.imread(PATH, cv2.IMREAD_GRAYSCALE)
plt.imshow(img, cmap='gray')
circles = cv2.HoughCircles(img, cv2.HOUGH_GRADIENT, 1, 20, param1=130, param2=30, minRadius=0, maxRadius=0)
if circles is not None:
    for x, y, r in circles[0]:
        c = plt.Circle((x, y), r, fill=False, lw=3, ec='C1')
        plt.gca().add_patch(c)
plt.gcf().set_size_inches((12, 8))
plt.show()

дает результат

Что означают разные параметры?

Сигнатура функции определяется как

cv.HoughCircles(image, method, dp, minDist[, circles[, param1[, param2[, minRadius[, maxRadius]]]]])

изображение и круги говорят сами за себя и будут пропущены.

метод

Определяет вариант алгоритма hough, который используется внутри компании. Как указано в документации, только HOUGH_GRADIENT поддерживает atm. В этом методе используется алгоритм 21HT (стр. 2, ПРЕОБРАЗОВАНИЕ 2-1 HOUGH) . Основное преимущество этого варианта заключается в уменьшении использования памяти. Стандартный способ обнаружения кругов с помощью преобразования Хафа требует поиска в трехмерном пространстве (x, y и радиус). Однако с 21HT ваше внутреннее пространство сокращается до двух измерений, что значительно снижает потребление памяти.

dp

Параметр dp устанавливает обратное разрешение аккумулятора. Хорошее объяснение можно найти здесь. Обратите внимание, что в этом объяснении в качестве примера используется стандартное преобразование Хафа. Но эффект такой же для 21HT. Аккумулятор для 21HT немного отличается от стандартного HT.

minDist

Просто указывает минимальное расстояние между центрами окружностей. В приведенном выше примере кода для него установлено значение 20, что означает, что центры двух обнаруженных кругов должны находиться на расстоянии не менее 20 пикселей друг от друга. Я не уверен, как opencv фильтрует круги, но при сканировании исходного кода кажется, что круги с меньшими совпадениями выбрасываются.

param1

Задает пороговые значения, которые передаются алгоритму Canny Edge. В основном это называется cv2.Canny(image, param1 / 2, param1).

param2

Этот абзац, вероятно, должен быть проверен кем-то, кто более знаком с исходным кодом opencv. param2 указывает порог накопителя. Это значение определяет, насколько полным должен быть круг, чтобы его можно было считать действительным кругом. Я не уверен, в какой единице дан параметр, тем не менее. Но (повторное сканирование исходного кода) похоже, что это абсолютный порог голосования (что означает, что на него напрямую влияют разные радиусы). На изображении ниже показаны разные круги (или то, что можно обозначить как круг). Чем дальше вы идете вправо, тем ниже должен быть порог для обнаружения этого круга.

Порог накопления

minRadius и maxRadius

Просто ограничивает круговой поиск в диапазоне [minRadius, maxRadius] радиуса. Это полезно (и может повысить производительность), если вы можете приблизительно (или знать) размер кругов, которые ищете.

person Timo    schedule 04.04.2018
comment
Не могли бы вы разместить ссылку на документацию по этим параметрам? (Или лучше: объясните их?) Спасибо. - person fecavy; 24.04.2018
comment
Читали ли вы официальную документацию cv2.HoughCircles? Я думаю, что мы объясним это там, но я могу пойти более подробно, если вы этого не понимаете. - person Timo; 24.04.2018
comment
Было бы здорово, если бы вы пошли поподробнее, думаю, я не до конца разобрался в документации. - person fecavy; 24.04.2018