Найдите максимальную вписанную окружность в невыпуклой оболочке.

Под «невыпуклой оболочкой» я имею в виду что-то вроде

enter image description here

черная часть изображения (извиняюсь, если это не «невыпуклая оболочка», у меня нет лучшего слова для его описания).

То, что я пытаюсь получить, - это максимальный вписанный круг в черной части, как красный круг ниже. enter image description here

Другими словами, я хотел бы знать круг на пустом месте. Возможно ли это с помощью opencv? Когда я пытаюсь получить круг, используя следующий код

dist_map = cv2.distanceTransform(src_mask, cv2.DIST_L2, cv2.DIST_MASK_PRECISE)
_, radius, _, center = cv2.minMaxLoc(dist_map)
result = cv2.cvtColor(src_mask, cv2.COLOR_GRAY2BGR)
cv2.circle(result, tuple(center), int(radius), (0, 0, 255), 2, cv2.LINE_8, 0)

Я получил это вместо этого. enter image description here Как видите, круг выходит за границы. Я рад услышать любые предложения и указатели. Благодарю вас!

Обновлено: Я добавил минимальный пример, чтобы воспроизвести это. Вот скрипт, а результат прикреплен ниже

import cv2
import numpy as np


##########
# create mask
# 0 if background, 255 if foreground
##########
src_mask = np.zeros((281, 500))
src_mask[100:170, 200:400] = 255
src_mask[127:143, 150:440] = 255
src_mask[213: 244, 30:59] = 255
src_mask[239: 279, 360:460] = 255
src_mask = src_mask.astype("uint8")
result = cv2.cvtColor(src_mask, cv2.COLOR_GRAY2BGR)
cv2.imwrite("mask.png", result)

##########
# draw contours
# the reason for 255-src_mask is that I want to have a circle in black portion instead of white portion 
##########
dist_map = cv2.distanceTransform(255 - src_mask, cv2.DIST_L2, cv2.DIST_MASK_PRECISE)
contours, _ = cv2.findContours(255 - src_mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)[-2:]
result = cv2.cvtColor(src_mask, cv2.COLOR_GRAY2BGR)
cv2.drawContours(result, contours, -1, (255, 0, 0))
cv2.imwrite('contour.png', result)

##########
# circle
##########
dist_map = cv2.distanceTransform(255 - src_mask, cv2.DIST_L2, cv2.DIST_MASK_PRECISE)
_, radius, _, center = cv2.minMaxLoc(dist_map)
result = cv2.cvtColor(src_mask, cv2.COLOR_GRAY2BGR)
cv2.circle(result, tuple(center), int(radius), (0, 0, 255), 2, cv2.LINE_8, 0)
cv2.imwrite('circle.png', result)

и выход enter image description here Опять круг выходит за границы.

Анализ настроения постов в Twitter с помощью Python, Tweepy и Flair
Анализ настроения постов в Twitter с помощью Python, Tweepy и Flair
Анализ настроения текстовых сообщений может быть настолько сложным или простым, насколько вы его сделаете. Как и в любом ML-проекте, вы можете выбрать...
7 лайфхаков для начинающих Python-программистов
7 лайфхаков для начинающих Python-программистов
В этой статье мы расскажем о хитростях и советах по Python, которые должны быть известны разработчику Python.
Установка Apache Cassandra на Mac OS
Установка Apache Cassandra на Mac OS
Это краткое руководство по установке Apache Cassandra.
Сертификатная программа "Кванты Python": Бэктестер ансамблевых методов на основе ООП
Сертификатная программа "Кванты Python": Бэктестер ансамблевых методов на основе ООП
В одном из недавних постов я рассказал о том, как я использую навыки количественных исследований, которые я совершенствую в рамках программы TPQ...
Создание персонального файлового хранилища
Создание персонального файлового хранилища
Вы когда-нибудь хотели поделиться с кем-то файлом, но он содержал конфиденциальную информацию? Многие думают, что электронная почта безопасна, но это...
Создание приборной панели для анализа данных на GCP - часть I
Создание приборной панели для анализа данных на GCP - часть I
Недавно я столкнулся с интересной бизнес-задачей - визуализацией сбоев в цепочке поставок лекарств, которую могут просматривать врачи и...
2
0
52
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

ммм, есть несколько случаев, когда это происходит:

Дело 1: неправильно установил переменную center ;-;

случай 2: из-за координат cv2 ( 0, 0 ) это верхний левый угол экрана, так что если центр правильный, то убедитесь, что вы сделали экран cv2 размером вашего экрана, иначе это произойдет

Спасибо за ответ! Я добавил минимальный пример. Думаешь, я сделал что-то не так? Поскольку я могу создать cv2.minEnclosingCircle и максимальный вписанный круг на белой части, я думаю, что проблема может быть в другом?

dragon_and_dracula 10.04.2022 09:20

ммм, на самом деле cv2.minEnclosingCircle просто нарисуйте круг, насколько это возможно. так…. почти без изменений с ним

Yaleyy Yeungy 10.04.2022 10:15

но это все еще нормально :D Вы можете попробовать и сказать мне результат. Вы также можете задать мне вопросы о html, js, css, nodejs, python :D

Yaleyy Yeungy 10.04.2022 10:17

Оказывается, мне нужно установить границу на 255, чтобы opencv работал. Спасибо за ваше предложение!

dragon_and_dracula 10.04.2022 11:11

:) Добро пожаловать

Yaleyy Yeungy 10.04.2022 11:17
Ответ принят как подходящий

Это может творить магию. Маскируйте также границы кадра, например:

src_mask[:, 0 ] = 255
src_mask[:, -1 ] = 255
src_mask[0, : ] = 255
src_mask[-1, : ] = 255

Таким образом, расчетные расстояния будут учитывать границы кадра. (Если вам еще нужна маска, скопируйте ее перед изменениями)

Я получил с вашим примером:

enter image description here

Я понимаю. Установка границы работает!! Благодарю вас!

dragon_and_dracula 10.04.2022 11:10

С удовольствием :)

matanj 10.04.2022 11:54

Другие вопросы по теме