Isolando Objetos de Segmentação
Após realizar a Tarefa de Segmentação, às vezes é desejável extrair os objetos isolados dos resultados da inferência. Este guia fornece uma receita genérica sobre como realizar isso usando o Modo de Previsão da Ultralytics.
Passo a Passo da Receita
-
Consulte a seção de instalação rápida do Ultralytics para obter um passo a passo rápido sobre a instalação das bibliotecas necessárias.
-
Carregue um modelo e execute
predict()
método em uma fonte.from ultralytics import YOLO # Load a model model = YOLO("yolo11n-seg.pt") # Run inference results = model.predict()
Sem Argumentos de Predição?
Sem especificar uma fonte, as imagens de exemplo da biblioteca serão usadas:
'ultralytics/assets/bus.jpg' 'ultralytics/assets/zidane.jpg'
Isto é útil para testes rápidos com o
predict()
método.Para obter informações adicionais sobre Modelos de Segmentação, visite a Tarefa de Segmentação página. Para saber mais sobre
predict()
método, veja Modo de Previsão seção da Documentação.
-
Agora itere sobre os resultados e os contornos. Para fluxos de trabalho que desejam salvar uma imagem em um arquivo, a imagem de origem
base-name
e a detecçãoclass-label
são recuperados para uso posterior (opcional).from pathlib import Path import numpy as np # (2) 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): # (1) Get detection class name label = c.names[c.boxes.cls.tolist().pop()]
- Para saber mais sobre como trabalhar com resultados de detecção, consulte a Seção de Caixas para o Modo de Previsão.
- Para saber mais sobre
predict()
resultados veja Trabalhando com Resultados para o Modo de Previsão
Loop For
Uma única imagem iterará o primeiro loop apenas uma vez. Uma única imagem com apenas uma única detecção iterará cada loop apenas uma vez.
-
Comece gerando uma máscara binária da imagem de origem e, em seguida, desenhe um contorno preenchido na máscara. Isso permitirá que o objeto seja isolado das outras partes da imagem. Um exemplo de
bus.jpg
para um dos detetadosperson
objetos de classe são mostrados à direita.import cv2 # Create binary mask b_mask = np.zeros(img.shape[:2], np.uint8) # (1) Extract contour result contour = c.masks.xy.pop() # (2) Changing the type contour = contour.astype(np.int32) # (3) Reshaping contour = contour.reshape(-1, 1, 2) # Draw contour onto mask _ = cv2.drawContours(b_mask, [contour], -1, (255, 255, 255), cv2.FILLED)
-
Para mais informações sobre
c.masks.xy
ver Seção de Máscaras do Modo de Predição. -
Aqui, os valores são convertidos em
np.int32
para compatibilidade comdrawContours()
função de OpenCV. -
O OpenCV
drawContours()
função espera que os contornos tenham uma forma de[N, 1, 2]
expanda a seção abaixo para mais detalhes.
Expanda para entender o que está acontecendo ao definir o
contour
variável.-
c.masks.xy
:: Fornece as coordenadas dos pontos do contorno da máscara no formato(x, y)
. Para mais detalhes, consulte o Seção de Máscaras do Modo de Predição..pop()
:: Comomasks.xy
é uma lista contendo um único elemento; este elemento é extraído usando opop()
método. -.astype(np.int32)
:: Usandomasks.xy
retornará com um tipo de dado defloat32
, mas isso não será compatível com o OpenCVdrawContours()
função, então isso mudará o tipo de dado paraint32
para compatibilidade. -.reshape(-1, 1, 2)
:: Reformata os dados para o formato necessário de[N, 1, 2]
ondeN
é o número de pontos de contorno, com cada ponto representado por uma única entrada1
, e a entrada é composta por2
valores. O-1
indica que o número de valores ao longo desta dimensão é flexível.Expanda para uma explicação do
drawContours()
configuração.- Encapsulando o
contour
variável entre colchetes,[contour]
, foi considerado eficaz para gerar a máscara de contorno desejada durante o teste. - O valor-1
especificado para odrawContours()
parâmetro instrui a função a desenhar todos os contornos presentes na imagem. - Otuple
(255, 255, 255)
representa a cor branca, que é a cor desejada para desenhar o contorno nesta máscara binária. - A adição decv2.FILLED
irá colorir todos os pixels delimitados pelo contorno da mesma cor, neste caso, todos os pixels delimitados serão brancos. - Ver Documentação OpenCV sobredrawContours()
para mais informações.
-
-
Em seguida, existem 2 opções sobre como avançar com a imagem a partir deste ponto e uma opção subsequente para cada.
Opções de Isolamento de Objetos
Exemplo
# Create 3-channel mask mask3ch = cv2.cvtColor(b_mask, cv2.COLOR_GRAY2BGR) # Isolate object with binary mask isolated = cv2.bitwise_and(mask3ch, img)
Como isso funciona?
-
Primeiro, a máscara binária é convertida de uma imagem de canal único para uma imagem de três canais. Esta conversão é necessária para a etapa subsequente, onde a máscara e a imagem original são combinadas. Ambas as imagens devem ter o mesmo número de canais para serem compatíveis com a operação de blending.
-
A imagem original e a máscara binária de três canais são mescladas usando a função OpenCV
bitwise_and()
. Esta operação retém apenas valores de pixel que são maiores que zero(> 0)
de ambas as imagens. Como os pixels da máscara são maiores que zero(> 0)
apenas dentro da região do contorno, os pixels restantes da imagem original são aqueles que se sobrepõem ao contorno.
Isolar com Pixels Pretos: Sub-opções
Imagem em Tamanho Real
Não são necessárias etapas adicionais se você mantiver a imagem em tamanho real.
Exemplo de saída em tamanho real Imagem do objeto recortado
Etapas adicionais necessárias para recortar a imagem para incluir apenas a região do objeto.
# (1) 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]
- Para obter mais informações sobre os resultados da bounding box, consulte a Seção de Caixas do Modo de Previsão.
O que este código faz?
-
O
c.boxes.xyxy.cpu().numpy()
a chamada recupera as caixas delimitadoras como um array NumPy noxyxy
formato, ondexmin
,ymin
,xmax
, eymax
representam as coordenadas do retângulo da caixa delimitadora. Veja Seção de Caixas do Modo de Previsão para mais detalhes. -
O
squeeze()
A operação remove quaisquer dimensões desnecessárias da matriz NumPy, garantindo que ela tenha o formato esperado. -
Convertendo os valores das coordenadas usando
.astype(np.int32)
altera o tipo de dados das coordenadas da caixa defloat32
paraint32
, tornando-os compatíveis para corte de imagem usando fatias de índice. -
Finalmente, a região da caixa delimitadora é recortada da imagem usando o fatiamento de índice. Os limites são definidos pelo
[ymin:ymax, xmin:xmax]
coordenadas da caixa delimitadora de detecção.
# Isolate object with transparent background (when saved as PNG) isolated = np.dstack([img, b_mask])
Como isso funciona?
- Usando o NumPy
dstack()
função (empilhamento de arrays ao longo do eixo de profundidade) em conjunto com a máscara binária gerada, criará uma imagem com quatro canais. Isso permite que todos os pixels fora do contorno do objeto sejam transparentes ao salvar como umPNG
ficheiro.
Isolar com Pixels Transparentes: Sub-opções
Imagem em Tamanho Real
Não são necessárias etapas adicionais se você mantiver a imagem em tamanho real.
Exemplo de saída em tamanho real + fundo transparente Imagem do objeto recortado
Etapas adicionais necessárias para recortar a imagem para incluir apenas a região do objeto.
# (1) 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]
- Para obter mais informações sobre os resultados da bounding box, consulte a Seção de Caixas do Modo de Previsão.
O que este código faz?
-
Ao usar
c.boxes.xyxy.cpu().numpy()
, as caixas delimitadoras são retornadas como um array NumPy, usando oxyxy
formato das coordenadas da caixa, que correspondem aos pontosxmin, ymin, xmax, ymax
para a caixa delimitadora (retângulo), veja Seção de Caixas do Modo de Previsão para mais informações. -
Adicionando
squeeze()
garante que quaisquer dimensões estranhas sejam removidas da matriz NumPy. -
Convertendo os valores das coordenadas usando
.astype(np.int32)
altera o tipo de dados das coordenadas da caixa defloat32
paraint32
que será compatível ao recortar a imagem usando fatias de índice. -
Finalmente, a região da imagem para a caixa delimitadora é recortada usando o fatiamento de índice, onde os limites são definidos usando o
[ymin:ymax, xmin:xmax]
coordenadas da caixa delimitadora de detecção.
E se eu quiser o objeto recortado incluindo o fundo?
Este é um recurso integrado para a biblioteca Ultralytics. Veja o
save_crop
argumento para Argumentos de Inferência do Modo de Previsão para mais detalhes.
-
-
O que fazer a seguir é inteiramente deixado para você como desenvolvedor. Um exemplo básico de uma possível próxima etapa (salvar a imagem em um arquivo para uso futuro) é mostrado.
- NOTA: esta etapa é opcional e pode ser ignorada se não for necessária para o seu caso de uso específico.
Exemplo da Etapa Final
# Save isolated object to file _ = cv2.imwrite(f"{img_name}_{label}-{ci}.png", iso_crop)
- Neste exemplo, o
img_name
é o nome base do arquivo de imagem de origem,label
é o nome da classe detectada, eci
é o índice do detecção de objetos (no caso de múltiplas instâncias com o mesmo nome de classe).
Código de Exemplo Completo
Aqui, todas as etapas da seção anterior são combinadas em um único bloco de código. Para uso repetido, seria ideal definir uma função para executar alguns ou todos os comandos contidos no for
-loops, mas isso fica como um exercício para o leitor.
from pathlib import Path
import cv2
import numpy as np
from ultralytics import YOLO
m = YOLO("yolo11n-seg.pt") # (4)!
res = m.predict() # (3)!
# Iterate detection results (5)
for r in res:
img = np.copy(r.orig_img)
img_name = Path(r.path).stem
# Iterate each object contour (6)
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 (1)
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 (2)
- A linha que preenche
contour
é combinado em uma única linha aqui, onde foi dividido em várias acima. - O que vai aqui depende de você!
- Consulte o Modo de Predição para obter informações adicionais.
- Consulte Tarefa de Segmentação para obter mais informações.
- Saiba mais sobre Como Trabalhar com Resultados.
- Saiba mais sobre os Resultados da Máscara de Segmentação.
FAQ
Como isolar objetos usando Ultralytics YOLO11 para tarefas de segmentação?
Para isolar objetos usando o Ultralytics YOLO11, siga estes passos:
-
Carregue o modelo e execute a inferência:
from ultralytics import YOLO model = YOLO("yolo11n-seg.pt") results = model.predict(source="path/to/your/image.jpg")
-
Gere uma máscara binária e desenhe contornos:
import cv2 import numpy as np 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)
-
Isole o objeto usando a máscara binária:
mask3ch = cv2.cvtColor(b_mask, cv2.COLOR_GRAY2BGR) isolated = cv2.bitwise_and(mask3ch, img)
Consulte o guia sobre o Modo de Predição e a Tarefa de Segmentação para obter mais informações.
Quais opções estão disponíveis para salvar os objetos isolados após a segmentação?
O Ultralytics YOLO11 oferece duas opções principais para salvar objetos isolados:
-
Com um Fundo Preto:
mask3ch = cv2.cvtColor(b_mask, cv2.COLOR_GRAY2BGR) isolated = cv2.bitwise_and(mask3ch, img)
-
Com um Fundo Transparente:
isolated = np.dstack([img, b_mask])
Para mais detalhes, visite a seção Modo de Predição.
Como posso recortar objetos isolados em suas caixas delimitadoras usando Ultralytics YOLO11?
Para recortar objetos isolados em suas bounding boxes:
-
Recuperar coordenadas da caixa delimitadora:
x1, y1, x2, y2 = results[0].boxes.xyxy[0].cpu().numpy().astype(np.int32)
-
Recortar a imagem isolada:
iso_crop = isolated[y1:y2, x1:x2]
Saiba mais sobre os resultados da bounding box na documentação do Modo de Predição.
Por que devo usar Ultralytics YOLO11 para isolamento de objetos em tarefas de segmentação?
Ultralytics YOLO11 oferece:
- Alta velocidade na detecção e segmentação de objetos em tempo real.
- Geração precisa de bounding boxes e máscaras para isolamento preciso de objetos.
- Documentação abrangente e API fácil de usar para um desenvolvimento eficiente.
Explore os benefícios de usar o YOLO na documentação da Tarefa de Segmentação.
Posso salvar objetos isolados, incluindo o fundo, usando o Ultralytics YOLO11?
Sim, este é um recurso integrado no Ultralytics YOLO11. Use o save_crop
argumento no predict()
método. Por exemplo:
results = model.predict(source="path/to/your/image.jpg", save_crop=True)
Leia mais sobre o save_crop
argumento no Argumentos de Inferência do Modo de Previsão secção.