Вам нужно настроить свои параметры. Функция 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()
дает результат
![](https://i.stack.imgur.com/Os8uN.png)
Что означают разные параметры?
Сигнатура функции определяется как
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 указывает порог накопителя. Это значение определяет, насколько полным должен быть круг, чтобы его можно было считать действительным кругом. Я не уверен, в какой единице дан параметр, тем не менее. Но (повторное сканирование исходного кода) похоже, что это абсолютный порог голосования (что означает, что на него напрямую влияют разные радиусы). На изображении ниже показаны разные круги (или то, что можно обозначить как круг). Чем дальше вы идете вправо, тем ниже должен быть порог для обнаружения этого круга.
![Порог накопления](https://i.stack.imgur.com/0UmFU.png)
minRadius и maxRadius
Просто ограничивает круговой поиск в диапазоне [minRadius, maxRadius] радиуса. Это полезно (и может повысить производительность), если вы можете приблизительно (или знать) размер кругов, которые ищете.
person
Timo
schedule
04.04.2018