Получение контура объекта внутри ограничивающей рамки

#python #opencv #image-processing

#python #opencv #обработка изображений

Вопрос:

Входное изображение

Я хотел бы определить контур контура мяса. Я подготовил модель обнаружения объектов для мяса. Выходные данные модели можно увидеть ниже, а координаты ограничивающей рамки равны (44,34) для верхнего левого и (321,348) для нижних правых углов.

Обнаружено мясо

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

Комментарии:

1. Как вы думаете, правильна ли оценка глубины? Поверхность под концом кажется перпендикулярной камере и плоской, но это не отражено в оценке глубины.

2. Смотрите здесь. Это не на 100% правильно, но я протестировал книгу с обычным определением контура на плоской поверхности, усреднил значения глубины внутри контура книги и плоской поверхности (эталонной), затем линейно рассчитал глубину книги, затем ее толщину. Это привело к ошибке 5%.

3. Хорошо, вы хотите извлечь только контур beef? Я думаю, что этого можно достичь без оценки глубины.

4. Да! Я также обучил модель обнаруживать мясо (ограничивающую рамку, а не сегментацию), если это поможет.

5. Я добился прогресса, используя пороговое значение Otsu для удаления артефактов, но этого все еще было недостаточно. Обновил вопрос в соответствии с запросом.

Ответ №1:

Вы можете использовать алгоритм Grabcut [1] для извлечения сегмента из ограничивающей рамки.

Grabcut пытается объединить пиксели в две группы, за пределами ограничивающей рамки и внутри, наказывая за несоответствие метки соседним пикселям с аналогичным цветом.

Например:

 import cv2 
import numpy as np

im = cv2.imread('beef.jpg')
mask = np.zeros(im.shape[:2], np.uint8)

bgd_model = np.zeros((1, 65), np.float64)
fgd_model = np.zeros((1, 65), np.float64)

rect = (30, 25, 30   318, 25   350)  # (x, y, w, h)
cv2.grabCut(im, mask, rect, bgd_model, fgd_model, 10, cv2.GC_INIT_WITH_RECT)                      

mask = np.where((mask == cv2.GC_BGD) | (mask == cv2.GC_PR_BGD), 0, 1).astype(np.uint8)

contour, _= cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(im, contour, -1, (0, 255, 0)) 

cv2.imwrite("output.png", im) 
  

вывод.png

[1] Ротер, Карстен, Владимир Колмогоров и Эндрю Блейк. Интерактивное извлечение переднего плана «GrabCut» с использованием повторяющихся сокращений графика.» Транзакции ACM с графикой (TOG) 23.3 (2004): 309-314.

Ответ №2:

Проблема, с которой вы сталкиваетесь, связана с тенью в верхней части, которая местами делает мясо таким же темным, как фон.

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

введите описание изображения здесь

Комментарии:

1. Это выглядит довольно потрясающе. Какую форму вы бы предложили для закрытия ядра?

2. Я использовал восьмиугольник, который является простым приближением окружности.

3. Я получаю похожие результаты, но не такие приятные, как у вас. Не могли бы вы также сказать мне, какой размер и сколько итераций вы использовали для преобразования. закрытие, если вы все еще помните?

4. @aizuon: извините, я не помню. Я увеличивал, пока «дыра» не исчезла.