Como isolar objetos segmentados com Ultralytics YOLO#
A segmentação de instâncias produz uma máscara precisa ao nível do pixel para cada objeto detectado, permitindo recortar cada objeto individualmente de uma imagem. Este guia mostra como transformar os resultados de segmentação do Ultralytics YOLO em objetos isolados usando o Modo de previsão e o OpenCV, com um fundo preto sólido ou transparente para salvar como PNG.
Assista: Como remover o fundo e isolar objetos com segmentação do Ultralytics YOLO e OpenCV em Python 🚀
Por que isolar objetos segmentados?#
Recortar objetos individuais de uma imagem permite uma variedade de fluxos de trabalho posteriores:
- Remoção do fundo em fotos de produtos, catálogos ou edições criativas.
- Recortes por objeto para criar conjuntos de dados de classificação a partir das suas detecções.
- Processamento direcionado para que etapas posteriores, como OCR, análise de cores ou medição, vejam somente o objeto, não a cena ao redor.
- Exportação como PNG transparente para compor objetos sobre novos fundos.
A receita funciona com qualquer modelo de segmentação Ultralytics YOLO e segue quatro etapas: executar a inferência → extrair cada contorno → isolar o objeto → salvar o resultado.
Executar a inferência de segmentação#
Instale as bibliotecas necessárias, carregue um modelo de segmentação (o sufixo -seg, necessário para produzir máscaras) e execute a predição na imagem de origem:
from ultralytics import YOLO
# Carregar um modelo de segmentação
model = YOLO("yolo26n-seg.pt")
# Executar a inferência em uma imagem de origem
results = model.predict(source="path/to/image.jpg")Se você chamar model.predict() sem source, a Ultralytics usará as imagens de exemplo incluídas no pacote (bus.jpg e zidane.jpg), o que é prático para testar o fluxo de trabalho rapidamente.
Extrair contornos dos objetos#
Cada item em results corresponde a uma imagem, e iterar sobre um resultado retorna uma detecção de cada vez. Para cada detecção, copie a imagem original, leia o rótulo da classe e desenhe o contorno da máscara do objeto sobre uma máscara binária vazia. A região branca dessa máscara indica exatamente quais pixels pertencem ao objeto.
Os trechos desta seção e da próxima são executados dentro do loop de detecção abaixo; o script completo, pronto para copiar e colar, está 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 # nome-base da imagem de origem
# Iterar sobre cada objeto detectado na imagem
for ci, c in enumerate(r):
label = c.names[c.boxes.cls.tolist().pop()] # nome da classe
# Criar uma máscara binária e desenhar nela o contorno do objeto
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]retorna o contorno da máscara como coordenadas de pontos(x, y)do objeto neste resultado de detecção única..astype(np.int32)converte os pontos defloat32, quedrawContours()do OpenCV não aceita..reshape(-1, 1, 2)remodela os pontos para o formato[N, 1, 2]esperado pordrawContours(), em queNé o número de pontos do contorno.
Passar [contour] com o índice -1 desenha todos os pontos do contorno fornecido, e cv2.FILLED preenche de branco todos os pixels dentro do contorno.
Isolar o objeto#
Com a máscara binária pronta, combine-a com a imagem original. Há dois estilos comuns, dependendo do fundo desejado:
Converta a máscara para três canais e mantenha apenas os pixels que se sobrepõem ao objeto. Tudo que estiver fora do contorno ficará preto:
# Isolar objeto com fundo preto
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 inteira, faça um recorte usando a caixa delimitadora da detecção:
# Coordenadas da caixa delimitadora
x1, y1, x2, y2 = c.boxes.xyxy.cpu().numpy().squeeze().astype(np.int32)
# Recortar a imagem isolada até a região do objeto
iso_crop = isolated[y1:y2, x1:x2]
Isso já está integrado. Passe save_crop=True para predict() e a Ultralytics salvará automaticamente os recortes da caixa delimitadora, sem necessidade de máscaras.
Salvar o resultado (opcional)#
O que fazer com cada objeto isolado fica a seu critério. Uma etapa seguinte comum é gravá-lo no disco para uso 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 detecção, de modo que várias instâncias da mesma classe recebam nomes de arquivo exclusivos. Substitua isolated por iso_crop se você tiver aplicado o recorte opcional acima.
Exemplo completo#
O script abaixo reúne todas as etapas em um único bloco executável. Por padrão, ele usa um fundo preto; altere a única linha indicada para np.dstack([img, b_mask]) para gerar 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 reutilizar o código, envolva o corpo do loop em uma função para poder chamá-la com muitas imagens.
Conclusão#
Agora você tem uma receita completa para isolar objetos segmentados com Ultralytics YOLO: execute a inferência, crie uma máscara binária a partir de cada contorno, extraia o objeto com fundo preto ou transparente e, opcionalmente, recorte-o até sua caixa delimitadora. Explore a documentação completa de Tarefa de segmentação e Modo de previsão para adaptar o fluxo de trabalho às suas próprias classes.
Perguntas frequentes#
Carregue um modelo de segmentação, execute a inferência, crie uma máscara binária a partir do contorno de cada detecção e combine-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)Veja o Exemplo completo para conferir o loop completo de cada detecção.
Há dois estilos principais. Para um fundo preto, converta a máscara para três canais e use
cv2.bitwise_and(). Para um fundo transparente (ao salvar como PNG), empilhe a máscara como um quarto canal alfa comnp.dstack([img, b_mask]). Ambos são mostrados em Isolar o objeto.Leia as coordenadas da caixa delimitadora da detecção e faça um recorte da imagem isolada:
x1, y1, x2, y2 = results[0].boxes.xyxy[0].cpu().numpy().astype(np.int32) iso_crop = isolated[y1:y2, x1:x2]Saiba mais sobre os resultados das caixas delimitadoras na documentação do Modo de previsão.
O Ultralytics YOLO oferece 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. Use o argumento
save_cropempredict()para salvar recortes das caixas delimitadoras com o plano de fundo original:results = model.predict(source="path/to/your/image.jpg", save_crop=True)Lê mais na secção Argumentos de inferência do modo Predict.