#python #opencv
#python #opencv
Вопрос:
Я хочу определить внешний круг, который ограничивает фигуру, края фигуры и круг внутри фигуры.
Я использую этот код для порога:
def adjustImage(img):
src = adjust_gamma(img, 0.5)
src_gray = src.copy()
src_gray = cv.blur(src_gray, (5,5))
hsv = cv.cvtColor(src_gray, cv.COLOR_BGR2HSV)
h, s, v = cv.split(hsv)
thresh = cv.adaptiveThreshold(v, 255, cv.ADAPTIVE_THRESH_MEAN_C, cv.THRESH_BINARY_INV, 5, 3)
return thresh
Однако этот код не всегда работает. Например, для этого изображения результат кода неверен:
Может ли кто-нибудь дать мне некоторые рекомендации о том, почему этот код не работает для всех этих изображений? Спасибо!
Комментарии:
1. Вы пробовали разные параметры для
adaptiveThreshold()
?2. @Powercoder Я пробовал использовать разные параметры для adaptiveThreshold() . Однако, когда я меняю параметры, некоторые изображения работают, а некоторые изображения не работают. Из того, что я могу сказать, не существует определенного набора параметров, которые работают для всех изображений.
3. Прикрепление исходных изображений без нарисованных кругов облегчит людям помощь вам
4. Ваш адаптивный порог должен быть настроен для каждого изображения. Попробуйте пороговое значение OTSU на его месте. Пропустите размытие, и если вам нужно избавиться от незначительных посторонних областей, используйте фильтрацию контуров по области или морфологии.
Ответ №1:
Предоставленные вами изображения несколько зашумлены, и кажется, что перед использованием им требуется фильтрация adaptiveThreshold()
, что-то лучше, чем просто размытие. Возможно cv.fastNlMeansDenoising()
, это кандидат. Проверьте разницу:
cv.blur: , cv.fastnl означает уменьшение шума:
Если ваши входные изображения всегда такие, я имею в виду довольно однотонные, я бы рекомендовал вместо этого использовать этот способ определения порога:
def adjustImage(img):
src_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
v_avg = np.average(src_gray)
v_max = np.max(src_gray)
_, thresh = cv.threshold(src_gray, v_avg (v_max - v_avg) / 2, 255, cv.THRESH_BINARY)
thresh = cv.morphologyEx(thresh, cv.MORPH_CLOSE, np.ones((5, 5)))
return thresh
Или, как упоминал @fmw42, OTSU — еще более естественное решение:
def adjustImage(img):
src_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
_, thresh = cv.threshold(src_gray, 0, 255, cv.THRESH_BINARY cv.THRESH_OTSU)
thresh = cv.morphologyEx(thresh, cv.MORPH_CLOSE, np.ones((5, 5)))
return thresh
Опубликованный вами код по какой-то причине не рисует круги прямо после копирования, но взгляните на то, что мы получаем с помощью функции выше:
Комментарии:
1. Почему бы просто не использовать пороговое значение OTSU?
2. OTSU тоже отличное решение