Como isolar objetos segmentados com o Ultralytics YOLO#
A segmentação de instâncias produz uma máscara precisa ao nível dos píxeis para cada objeto detetado, o que significa que podes extrair cada objeto individualmente de uma imagem. Este guia mostra como transformar os resultados de segmentação do Ultralytics YOLO em objetos isolados usando o Predict Mode e o OpenCV, com um fundo preto sólido ou transparente para guardar como PNG.
Watch: How to Remove Background and Isolate Objects with Ultralytics YOLO Segmentation & OpenCV in Python 🚀
Por que isolar objetos segmentados?#
Extrair objetos individuais de uma imagem permite uma série de fluxos de trabalho posteriores:
- Remoção do fundo para fotografias de produtos, catálogos ou edição criativa.
- Recortes por objeto para criar conjuntos de dados de classificação a partir das tuas deteções.
- Processamento focado para que etapas posteriores, como OCR, análise de cores ou medição, vejam apenas o objeto, e não a cena envolvente.
- Exportação para PNG transparente para compor objetos sobre novos fundos.
A receita funciona com qualquer modelo de segmentação do Ultralytics YOLO e segue quatro etapas: executar a inferência → extrair cada contorno → isolar o objeto → guardar o resultado.
Executar a inferência de segmentação#
Instala as bibliotecas necessárias, carrega um modelo de segmentação (o sufixo -seg, necessário para produzir máscaras) e executa a predição na tua imagem de origem:
from ultralytics import YOLO
# Load a segmentation model
model = YOLO("yolo26n-seg.pt")
# Run inference on a source
results = model.predict(source="path/to/image.jpg")Se chamares model.predict() sem um source, o Ultralytics recorre às imagens de exemplo fornecidas com o pacote (bus.jpg e zidane.jpg), o que é útil para testar rapidamente o fluxo de trabalho.
Extrair contornos de objetos#
Cada item em results corresponde a uma imagem, e iterar sobre um resultado devolve uma deteção de cada vez. Para cada deteção, copia a imagem original, lê o rótulo da classe e desenha o contorno da máscara do objeto numa máscara binária em branco. A região branca desta máscara indica exatamente quais os píxeis que pertencem ao objeto.
Os fragmentos de código desta secção e da seguinte são executados dentro do ciclo de deteção abaixo; o script completo, pronto a copiar e colar, encontra-se em Exemplo completo.
from pathlib import Path
import cv2
import numpy as np
for r in results:
img = np.copy(r.orig_img)
img_name = Path(r.path).stem # source image base-name
# Iterate each detected object in the image
for ci, c in enumerate(r):
label = c.names[c.boxes.cls.tolist().pop()] # class name
# Build a binary mask and draw the object contour onto it
b_mask = np.zeros(img.shape[:2], np.uint8)
contour = c.masks.xy[0].astype(np.int32).reshape(-1, 1, 2)
cv2.drawContours(b_mask, [contour], -1, (255, 255, 255), cv2.FILLED)c.masks.xy[0]devolve o contorno da máscara como coordenadas de pontos(x, y)para o objeto neste resultado de deteção única..astype(np.int32)converte os pontos defloat32, que odrawContours()do OpenCV não aceita..reshape(-1, 1, 2)altera a forma dos pontos para o esquema[N, 1, 2]esperado pordrawContours(), no qualNcorresponde ao número de pontos do contorno.
Passar [contour] com o índice -1 desenha todos os pontos do contorno fornecido, e cv2.FILLED preenche a branco todos os píxeis delimitados.
Isolar o objeto#
Com a máscara binária pronta, combina-a com a imagem original. Existem dois estilos comuns, dependendo do fundo que pretendes:
Converte a máscara em três canais e mantém apenas os píxeis que se sobrepõem ao objeto. Tudo fora do contorno fica preto:
# Isolate object with a black background
mask3ch = cv2.cvtColor(b_mask, cv2.COLOR_GRAY2BGR)
isolated = cv2.bitwise_and(mask3ch, img)
Para manter apenas a região do objeto em vez da imagem em tamanho completo, recorta-a para a caixa delimitadora da deteção:
# Bounding box coordinates
x1, y1, x2, y2 = c.boxes.xyxy.cpu().numpy().squeeze().astype(np.int32)
# Crop the isolated image to the object region
iso_crop = isolated[y1:y2, x1:x2]
Essa opção já está integrada. Passa save_crop=True a predict() e o Ultralytics guarda automaticamente recortes da caixa delimitadora, sem necessidade de aplicar uma máscara.
Guardar o resultado (opcional)#
O que fazer com cada objeto isolado depende de ti. Um passo seguinte comum é escrevê-lo no disco para utilização posterior:
# Save the isolated object to file
cv2.imwrite(f"{img_name}_{label}-{ci}.png", isolated)Aqui, img_name é o nome base da imagem de origem, label é o nome da classe e ci é o índice da deteção, pelo que várias instâncias da mesma classe recebem nomes de ficheiro exclusivos. Substitui isolated por iso_crop se tiveres aplicado o recorte opcional acima.
Exemplo completo#
O script abaixo combina todas as etapas num único bloco executável. Usa um fundo preto por predefinição; altera a única linha assinalada para np.dstack([img, b_mask]) para obter um PNG transparente:
from pathlib import Path
import cv2
import numpy as np
from ultralytics import YOLO
model = YOLO("yolo26n-seg.pt")
results = model.predict(source="path/to/image.jpg")
for r in results:
img = np.copy(r.orig_img)
img_name = Path(r.path).stem
for ci, c in enumerate(r):
label = c.names[c.boxes.cls.tolist().pop()]
# Build a binary mask from the object contour
b_mask = np.zeros(img.shape[:2], np.uint8)
contour = c.masks.xy[0].astype(np.int32).reshape(-1, 1, 2)
cv2.drawContours(b_mask, [contour], -1, (255, 255, 255), cv2.FILLED)
# Isolate the object (black background)
mask3ch = cv2.cvtColor(b_mask, cv2.COLOR_GRAY2BGR)
isolated = cv2.bitwise_and(mask3ch, img) # transparent PNG: isolated = np.dstack([img, b_mask])
# Save or add your custom post-processing here
cv2.imwrite(f"{img_name}_{label}-{ci}.png", isolated)
# Optional: crop to the bounding box before saving
# x1, y1, x2, y2 = c.boxes.xyxy.cpu().numpy().squeeze().astype(np.int32)
# cv2.imwrite(f"{img_name}_{label}-{ci}.png", isolated[y1:y2, x1:x2])Para utilização repetida, coloca o corpo do ciclo numa função para que a possas chamar em várias imagens.
Conclusão#
Agora tens uma receita completa para isolar objetos segmentados com o Ultralytics YOLO: executa a inferência, cria uma máscara binária a partir de cada contorno, extrai o objeto sobre um fundo preto ou transparente e, opcionalmente, recorta-o para a respetiva caixa delimitadora. Consulta a documentação completa de Segment Task e Predict Mode para adaptares o fluxo de trabalho às tuas próprias classes.
Perguntas frequentes#
Carrega um modelo de segmentação, executa a inferência, cria uma máscara binária a partir do contorno de cada deteção e combina-a com a imagem original:
import cv2 import numpy as np from ultralytics import YOLO model = YOLO("yolo26n-seg.pt") results = model.predict(source="path/to/your/image.jpg") img = np.copy(results[0].orig_img) b_mask = np.zeros(img.shape[:2], np.uint8) contour = results[0].masks.xy[0].astype(np.int32).reshape(-1, 1, 2) cv2.drawContours(b_mask, [contour], -1, (255, 255, 255), cv2.FILLED) mask3ch = cv2.cvtColor(b_mask, cv2.COLOR_GRAY2BGR) isolated = cv2.bitwise_and(mask3ch, img)Consulta o Exemplo completo para veres o ciclo completo por deteção.
Existem dois estilos principais. Para um fundo preto, converte a máscara em três canais e usa
cv2.bitwise_and(). Para um fundo transparente (ao guardar como PNG), empilha a máscara como um quarto canal alfa comnp.dstack([img, b_mask]). Ambos são apresentados em Isolar o objeto.Lê as coordenadas da caixa delimitadora a partir da deteção e recorta a imagem isolada:
x1, y1, x2, y2 = results[0].boxes.xyxy[0].cpu().numpy().astype(np.int32) iso_crop = isolated[y1:y2, x1:x2]Obtém mais informações sobre os resultados das caixas delimitadoras na documentação do Predict Mode.
O Ultralytics YOLO fornece segmentação de instâncias rápida e em tempo real, com geração precisa de máscaras e caixas delimitadoras, além de uma API Python simples que transforma os resultados da inferência em objetos isolados com poucas linhas de código OpenCV.
Sim. Usa o argumento
save_cropempredict()para guardar recortes da caixa delimitadora com o fundo original:results = model.predict(source="path/to/your/image.jpg", save_crop=True)Lê mais na secção Argumentos de inferência do Predict Mode.