как указано в заголовке, я пытаюсь вырезать самый большой круг из изображения. Я использую OpenCV в python. Точнее, это стреляющая мишень, которая всегда имеет один и тот же формат, но ее можно сделать на любом мобильном устройстве и в разных условиях освещения (несколько примеров я приведу ниже).
I ' m совершенно новичок в распознавании изображений, поэтому я пробовал много разных способов сделать это, но не мог придумать универсального решения, которое работало бы со всеми моими целевыми изображениями.
Почему я пытаюсь сделать это:
Мое задание - подсчитать оценку одного или нескольких выстрелов на заданном целевом изображении. Я пробовал цветовую сегментацию, чтобы найти снимки, но, поскольку снимки могут быть на разном фоне, это не сработает должным образом. Итак, теперь я пытаюсь увидеть разницу между изображением пустой мишени для стрельбы и уже снятым изображением цели. Кроме того, мне нужно иметь возможность сказать, по какой цели он был обстрелян (есть два типа целей). Поэтому я пытаюсь вырезать только цель из изображения, чтобы избавиться от фоновых помех, а затем продолжаю идентификацию выстрела.
То, что я пробовал до сих пор:
1) Поиск самый большой круг с HoughCircles. Следующим шагом было бы как-то удалить внешнюю часть найденного круга. Я довольно долго играл с конфигурацией метода HoughCircles, но всегда одно из изображений в качестве примера не выделяло правильно самый внешний круг или не выделяло ни один из кругов: /.
Мой последний конфигурация выглядела примерно так:
img = cv2.GaussianBlur(img, (3, 3), 0)
cv2.HoughCircles(img, cv2.HOUGH_GRADIENT, 2, 10000, param1=50, param2=100, minRadius=200, maxRadius=0)
Похоже, что использование HoughCircles было бы неправильным способом сделать это, поэтому я перешел к другому возможному решению, которое нашел на inte rnet.
2) Поиск всех счетчиков путем фильтрации «черного» цветового диапазона, в котором круги кажутся на картинках, и затем поиск самого большого из них. Проблема с этим решением, казалось, заключалась в том, что иногда изображения имели тень, которая разрушала внешний круг, и поэтому казалось невозможным обрезать ее.
Мой код выглядел так:
# black color boundaries [B, G, R]
lower = [0, 0, 0]
upper = [150, 150, 150]
# create NumPy arrays from the boundaries
lower = np.array(lower, dtype="uint8")
upper = np.array(upper, dtype="uint8")
# find the colors within the specified boundaries and apply the mask
mask = cv2.inRange(img, lower, upper)
output = cv2.bitwise_and(img, img, mask=mask)
ret, thresh = cv2.threshold(mask, 40, 255, 0)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
if len(contours) != 0:
# draw in blue the contours that were founded
cv2.drawContours(output, contours, -1, 255, 3)
# find the biggest countour (c) by the area
c = max(contours, key=cv2.contourArea)
x, y, w, h = cv2.boundingRect(c)
После этого я бы попытался нарисовать круг по самому большому найденному контуру (c) и обрезать по нему. Но я уже видел, что нарисованные круги были неполными (вероятно, из-за какой-то тени на изображении), и поэтому это все равно не сработает.
После этих неудач я перепробовал так много решений от других вопросы здесь, но ни один из них не подойдет для моей проблемы.
Примеры изображений:
Целевой пример 1
Целевой пример 2
Целевой показатель c балл 1
Целевой показатель c балл 2
Чтобы быть полностью честно говоря, я действительно не знаю, как go об этом. Буду признателен за любую помощь, совет, что угодно.