Как вырезать самый большой круг из изображения (мишень для стрельбы) с помощью OpenCV - PullRequest
1 голос
/ 30 мая 2020

как указано в заголовке, я пытаюсь вырезать самый большой круг из изображения. Я использую 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 об этом. Буду признателен за любую помощь, совет, что угодно.

1 Ответ

0 голосов
/ 30 мая 2020

В ваших образцах есть два разных типа мишени. Вы можете обработать их отдельно или спросить пользователя, что это за цель. По сути, вы хотите знать, насколько велика черная часть цели, покрывает ли она 7-10 или 4-10.

Бинаризуйте ваше изображение. Постройте гистограмму по X и Y - вы найдете положение черной части вашей цели как (x_left, x_right, y_top, y_bottom). Как только вы это узнаете, вы можете вычислить центр ((top+bottom)/2, (left+right)/2). После этого вы можете легко подсчитать оценку для каждого пикселя изображения, так как вы знаете центр, размер черного пятна и количество различных областей оценки внутри.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...