Изолирование объектов сегментации
После выполнения задачи Segment Task иногда бывает необходимо извлечь изолированные объекты из результатов умозаключений. В этом руководстве приводится общий рецепт, как это сделать с помощьюрежима Ultralytics PredictMode.
Просмотр рецептов
-
Краткое руководство по установке необходимых библиотек см. в разделеUltralytics Quickstart Installation.
-
Загрузите модель и запустите
predict()
метод на источнике.from ultralytics import YOLO # Load a model model = YOLO("yolo11n-seg.pt") # Run inference results = model.predict()
Нет аргументов в пользу предсказаний?
Без указания источника будут использоваться примеры изображений из библиотеки:
Это полезно для быстрого тестирования с помощью
predict()
метод.Дополнительную информацию о моделях сегментации можно найти на сайте Задача сегмента Страница. Чтобы узнать больше о
predict()
метод, см. Режим предсказания в разделе Документация.
-
Теперь пройдитесь итерацией по результатам и контурам. Для рабочих процессов, которые хотят сохранить изображение в файл, исходное изображение
base-name
и обнаружениеclass-label
извлекаются для последующего использования (необязательно).from pathlib import Path import numpy as np # Iterate detection results (helpful for multiple images) for r in res: img = np.copy(r.orig_img) img_name = Path(r.path).stem # source image base-name # Iterate each object contour (multiple detections) for ci, c in enumerate(r): # Get detection class name label = c.names[c.boxes.cls.tolist().pop()]
For-Loop
Для одиночного изображения первый цикл будет пройден только один раз. Для одиночного изображения с единственным обнаружением каждый цикл будет пройден только один раз.
-
Начните с создания бинарной маски из исходного изображения, а затем нарисуйте на ней заполненный контур. Это позволит изолировать объект от других частей изображения. Пример из
bus.jpg
для одного из обнаруженныхperson
Объекты класса показаны справа.import cv2 # Create binary mask b_mask = np.zeros(img.shape[:2], np.uint8) # Extract contour result contour = c.masks.xy.pop() # Changing the type contour = contour.astype(np.int32) # Reshaping contour = contour.reshape(-1, 1, 2) # Draw contour onto mask _ = cv2.drawContours(b_mask, [contour], -1, (255, 255, 255), cv2.FILLED)
Чтобы понять, что происходит при определении
contour
переменная.-
c.masks.xy
:: Предоставляет координаты точек контура маски в формате(x, y)
. Для получения более подробной информации см. Раздел "Маски" из режима прогнозирования. -
.pop()
:: Какmasks.xy
является списком, содержащим один элемент, этот элемент извлекается с помощьюpop()
метод. -
.astype(np.int32)
:: Использованиеmasks.xy
вернется с типом данныхfloat32
но это не будет совместимо с OpenCV.drawContours()
функция изменит тип данных наint32
для совместимости. -
.reshape(-1, 1, 2)
:: Переформатирует данные в требуемую форму[N, 1, 2]
гдеN
количество точек контура, каждая из которых представлена одной записью1
, и запись состоит из2
ценности. Сайт-1
означает, что число значений в этом измерении гибкое.
Разверните, чтобы получить объяснение
drawContours()
конфигурация.-
Инкапсуляция
contour
переменная в квадратных скобках,[contour]
В ходе тестирования было установлено, что он эффективно генерирует желаемую контурную маску. -
Значение
-1
указанный дляdrawContours()
Параметр указывает функции нарисовать все контуры, присутствующие на изображении. -
Сайт
tuple
(255, 255, 255)
представляет собой белый цвет, который является желаемым цветом для рисования контура в этой бинарной маске. -
Добавление
cv2.FILLED
окрасит все пиксели, заключенные в границу контура, в один и тот же цвет, в данном случае все заключенные пиксели будут белыми. -
См. Документация по OpenCV на
drawContours()
для получения дополнительной информации.
-
-
Далее предлагаются 2 варианта того, как можно продолжить работу с изображением с этой точки, и последующий вариант для каждого из них.
Параметры изоляции объектов
Пример
# Create 3-channel mask mask3ch = cv2.cvtColor(b_mask, cv2.COLOR_GRAY2BGR) # Isolate object with binary mask isolated = cv2.bitwise_and(mask3ch, img)
Как это работает?
-
Сначала двоичная маска преобразуется из одноканального изображения в трехканальное. Это преобразование необходимо для последующего этапа, на котором маска и исходное изображение объединяются. Оба изображения должны иметь одинаковое количество каналов, чтобы быть совместимыми с операцией смешивания.
-
Исходное изображение и трехканальная бинарная маска объединяются с помощью функции OpenCV
bitwise_and()
. Эта операция сохраняет только значения пикселей, которые больше нуля(> 0)
из обоих изображений. Поскольку пиксели маски больше нуля(> 0)
только В области контура остаются пиксели, перекрывающие контур исходного изображения.
Изолировать с помощью черных пикселей: Подварианты
Полноразмерное изображение
При сохранении полноразмерного изображения никаких дополнительных действий не требуется.
Пример полноразмерного вывода Обрезанное изображение объекта
Дополнительные действия необходимы для обрезки изображения, чтобы включить только область объекта.
# Bounding box coordinates x1, y1, x2, y2 = c.boxes.xyxy.cpu().numpy().squeeze().astype(np.int32) # Crop image to object region iso_crop = isolated[y1:y2, x1:x2]
Что делает этот код?
-
Сайт
c.boxes.xyxy.cpu().numpy()
Вызов извлекает ограничительные рамки в виде массива NumPy вxyxy
формат, гдеxmin
,ymin
,xmax
, иymax
представляют собой координаты прямоугольника ограничительной рамки. См. Секция боксов из режима прогнозирования для более подробной информации. -
Сайт
squeeze()
Операция удаляет лишние размеры из массива NumPy, обеспечивая его ожидаемую форму. -
Преобразование значений координат с помощью
.astype(np.int32)
изменяет тип данных координат коробки сfloat32
наint32
что делает их совместимыми для обрезки изображений с помощью индексных фрагментов. -
Наконец, область ограничительной рамки вырезается из изображения с помощью индексной нарезки. Границы определяются с помощью
[ymin:ymax, xmin:xmax]
координаты ограничительной рамки обнаружения.
# Isolate object with transparent background (when saved as PNG) isolated = np.dstack([img, b_mask])
Как это работает?
- Использование NumPy
dstack()
(укладка массива по оси глубины) в сочетании со сгенерированной бинарной маской создаст изображение с четырьмя каналами. Это позволяет сделать все пиксели за пределами контура объекта прозрачными при сохранении в форматеPNG
файл.
Изолировать с помощью прозрачных пикселей: Подварианты
Полноразмерное изображение
При сохранении полноразмерного изображения никаких дополнительных действий не требуется.
Пример полноразмерного изображения + прозрачный фон Обрезанное изображение объекта
Дополнительные действия необходимы для обрезки изображения, чтобы включить только область объекта.
# Bounding box coordinates x1, y1, x2, y2 = c.boxes.xyxy.cpu().numpy().squeeze().astype(np.int32) # Crop image to object region iso_crop = isolated[y1:y2, x1:x2]
Что делает этот код?
-
При использовании
c.boxes.xyxy.cpu().numpy()
Граничные поля возвращаются в виде массива NumPy, используяxyxy
формат координат бокса, которые соответствуют точкамxmin, ymin, xmax, ymax
для ограничительной рамки (прямоугольника), см. Секция боксов из режима прогнозирования для получения дополнительной информации. -
Добавление
squeeze()
гарантирует, что все лишние размеры будут удалены из массива NumPy. -
Преобразование значений координат с помощью
.astype(np.int32)
изменяет тип данных координат коробки сfloat32
наint32
которые будут совместимы при обрезке изображения с помощью индексных фрагментов. -
Наконец, область изображения для ограничительного поля обрезается с помощью индексной нарезки, где границы задаются с помощью функции
[ymin:ymax, xmin:xmax]
координаты ограничительной рамки обнаружения.
А если мне нужен обрезанный объект , включая фон?
Это встроенная функция библиотеки Ultralytics . См.
save_crop
аргумент за Аргументы для умозаключений в режиме предсказания для деталей.
-
-
Что делать дальше, зависит только от вас как разработчика. В качестве примера показан один из возможных вариантов действий (сохранение изображения в файл для дальнейшего использования).
- ПРИМЕЧАНИЕ: этот шаг не является обязательным и может быть пропущен, если он не требуется для вашего конкретного случая использования.
Пример Заключительный шаг
- В этом примере
img_name
базовое имя исходного файла изображения,label
это имя обнаруженного класса, аci
индекс обнаружение объектов (в случае нескольких экземпляров с одним и тем же именем класса).
Полный код примера
Здесь все шаги из предыдущего раздела объединены в один блок кода. Для повторного использования оптимальным будет определить функцию, которая будет выполнять некоторые или все команды, содержащиеся в for
-петли, но это упражнение остается на усмотрение читателя.
from pathlib import Path
import cv2
import numpy as np
from ultralytics import YOLO
m = YOLO("yolo11n-seg.pt")
res = m.predict()
# Iterate detection results
for r in res:
img = np.copy(r.orig_img)
img_name = Path(r.path).stem
# Iterate each object contour
for ci, c in enumerate(r):
label = c.names[c.boxes.cls.tolist().pop()]
b_mask = np.zeros(img.shape[:2], np.uint8)
# Create contour mask
contour = c.masks.xy.pop().astype(np.int32).reshape(-1, 1, 2)
_ = cv2.drawContours(b_mask, [contour], -1, (255, 255, 255), cv2.FILLED)
# Choose one:
# OPTION-1: Isolate object with black background
mask3ch = cv2.cvtColor(b_mask, cv2.COLOR_GRAY2BGR)
isolated = cv2.bitwise_and(mask3ch, img)
# OPTION-2: Isolate object with transparent background (when saved as PNG)
isolated = np.dstack([img, b_mask])
# OPTIONAL: detection crop (from either OPT1 or OPT2)
x1, y1, x2, y2 = c.boxes.xyxy.cpu().numpy().squeeze().astype(np.int32)
iso_crop = isolated[y1:y2, x1:x2]
# TODO your actions go here
ЧАСТО ЗАДАВАЕМЫЕ ВОПРОСЫ
Как выделить объекты с помощью Ultralytics YOLO11 для задач сегментации?
Чтобы изолировать объекты с помощью Ultralytics YOLO11 , выполните следующие действия:
-
Загрузите модель и запустите вывод:
-
Создайте бинарную маску и нарисуйте контуры:
-
Выделите объект с помощью двоичной маски:
Дополнительную информацию см. в руководстве по режиму прогнозирования и задаче "Сегмент".
Какие опции доступны для сохранения изолированных объектов после сегментации?
Ultralytics YOLO11 предлагает два основных варианта сохранения изолированных объектов:
-
С черным фоном:
-
С прозрачным фоном:
Более подробную информацию можно найти в разделе "Режим прогнозирования ".
Как обрезать изолированные объекты до их ограничительных рамок с помощью Ultralytics YOLO11 ?
Чтобы обрезать изолированные объекты до их ограничительных рамок:
-
Получение координат ограничительной рамки:
-
Обрежьте изолированное изображение:
Более подробную информацию о результатах построения ограничительной рамки можно найти в документации по режиму Predict.
Почему следует использовать Ultralytics YOLO11 для выделения объектов в задачах сегментации?
Ultralytics YOLO11 обеспечивает:
- Высокоскоростное обнаружение и сегментация объектов в реальном времени.
- Точная генерация ограничительных рамок и масок для точного выделения объектов.
- Исчерпывающая документация и простой в использовании API для эффективной разработки.
Изучите преимущества использования YOLO в документации Segment Task.
Можно ли сохранить изолированные объекты, включая фон, с помощью Ultralytics YOLO11 ?
Да, это встроенная функция в Ultralytics YOLO11 . Используйте save_crop
аргумент в predict()
метод. Например:
Подробнее о save_crop
аргумент в Аргументы для умозаключений в режиме предсказания раздел.