Isolamento de objetos de segmentação
Depois de executar a Tarefa de Segmento, às vezes é desejável extrair os objetos isolados dos resultados da inferência. Este guia fornece uma receita genérica sobre como fazer isso usando o Ultralytics Predict Mode.
Passeio pelas receitas
Consulta a secçãoUltralytics Quickstart Installation para obteres um passo-a-passo rápido sobre a instalação das bibliotecas necessárias.
Carrega um modelo e executa
predict()
numa fonte.from ultralytics import YOLO # Load a model model = YOLO("yolo11n-seg.pt") # Run inference results = model.predict()
Não tens argumentos de previsão?
Sem especificar uma fonte, serão utilizadas as imagens de exemplo da biblioteca:
Isto é útil para testes rápidos com o
predict()
método.Para obter informações adicionais sobre os modelos de segmentação, visita a página Tarefa do segmento página. Para saberes mais sobre
predict()
método, vê Modo de previsão secção da Documentação.Agora repete os resultados e os contornos. Para fluxos de trabalho que pretendam guardar uma imagem num ficheiro, a imagem de origem
base-name
e a deteçãoclass-label
são recuperados para utilização 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 saberes mais sobre como trabalhar com resultados de deteção, consulta a secção Caixas para o Modo de previsão.
- Para saberes mais sobre
predict()
resultados ver Trabalho com resultados do modo de previsão
For-Loop
Uma única imagem itera o primeiro ciclo apenas uma vez. Uma única imagem com uma única deteção irá iterar cada ciclo apenas uma vez.
Começa por gerar uma máscara binária a partir da imagem de origem e depois desenha um contorno preenchido na máscara. Isto permitirá que o objeto seja isolado das outras partes da imagem. Um exemplo de
bus.jpg
para um dos detectadosperson
é mostrado à 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
vê Secção de máscaras do modo de previsão.Aqui os valores são convertidos em
np.int32
para compatibilidade comdrawContours()
function from OpenCV.O OpenCV
drawContours()
espera que os contornos tenham uma forma de[N, 1, 2]
expande a secção abaixo para obteres mais informações.
Expande para compreender o que está a acontecer ao definir o
contour
variável.c.masks.xy
:: Fornece as coordenadas dos pontos de contorno da máscara no formato(x, y)
. Para mais pormenores, consulta a Secção de máscaras do modo de previsão..pop()
:: Comomasks.xy
é uma lista que contém um único elemento, este elemento é extraído utilizando opop()
método..astype(np.int32)
:: Usandomasks.xy
retornará com um tipo de dados defloat32
mas isso não será compatível com o OpenCVdrawContours()
por isso, altera o tipo de dados paraint32
para compatibilidade..reshape(-1, 1, 2)
:: Reformata os dados na forma requerida de[N, 1, 2]
ondeN
é o número de pontos de contorno, sendo cada ponto representado por uma única entrada1
e a entrada é composta por2
valores. Os-1
indica que o número de valores ao longo desta dimensão é flexível.
Expande para uma explicação do
drawContours()
configuração.Encapsulando o
contour
entre parênteses rectos,[contour]
, foi considerado eficaz para gerar a máscara de contorno desejada durante os testes.O valor
-1
especificado para odrawContours()
dá instruções à função para desenhar todos os contornos presentes na imagem.O
tuple
(255, 255, 255)
representa a cor branca, que é a cor desejada para desenhar o contorno nesta máscara binária.A adição de
cv2.FILLED
Colore todos os pixéis delimitados pelo contorno com a mesma cor, neste caso, todos os pixéis delimitados serão brancos.Vê Documentação do OpenCV em
drawContours()
para mais informações.
De seguida, há duas opções para avançar com a imagem a partir deste ponto e uma opção subsequente para cada uma delas.
Opções de isolamento de objectos
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 é que isto funciona?
Primeiro, a máscara binária é convertida de uma imagem de um canal para uma imagem de três canais. Esta conversão é necessária para o passo seguinte, em que 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 combinação.
A imagem original e a máscara binária de três canais são fundidas utilizando a função OpenCV
bitwise_and()
. Esta operação mantém apenas valores de pixéis superiores a zero(> 0)
de ambas as imagens. Uma vez que os pixéis da máscara são maiores do que zero(> 0)
apenas dentro da região de contorno, os pixels restantes da imagem original são aqueles que se sobrepõem ao contorno.
Isolar com píxeis pretos: Sub-opções
Imagem em tamanho real
Não são necessários passos adicionais para manter a imagem em tamanho real.
Imagem do objeto recortada
Passos adicionais necessários para cortar 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]
- For more information on bounding box results, see Boxes Section from Predict Mode
O que é que este código faz?
O
c.boxes.xyxy.cpu().numpy()
recupera as caixas delimitadoras como uma matriz NumPy noxyxy
formato, em quexmin
,ymin
,xmax
eymax
representa as coordenadas do retângulo da caixa delimitadora. Vê Secção de caixas do modo de previsão para mais pormenores.O
squeeze()
remove quaisquer dimensões desnecessárias da matriz NumPy, assegurando que tem a forma esperada.Converte os valores das coordenadas utilizando
.astype(np.int32)
altera o tipo de dados das coordenadas da caixa defloat32
paraint32
tornando-os compatíveis com o corte de imagens utilizando cortes de índice.Finalmente, a região da caixa delimitadora é cortada da imagem utilizando o corte de índice. Os limites são definidos pelo parâmetro
[ymin:ymax, xmin:xmax]
coordenadas da caixa delimitadora da deteção.
# Isolate object with transparent background (when saved as PNG) isolated = np.dstack([img, b_mask])
Como é que isto funciona?
- Usando o NumPy
dstack()
(empilhamento de matriz ao longo do eixo de profundidade) em conjunto com a máscara binária gerada, criará uma imagem com quatro canais. Isto permite que todos os pixels fora do contorno do objeto sejam transparentes quando guardados como umaPNG
arquiva.
Isolar com pixels transparentes: Sub-opções
Imagem em tamanho real
Não são necessários passos adicionais para manter a imagem em tamanho real.
Imagem do objeto recortada
Passos adicionais necessários para cortar 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 mais informações sobre os resultados da caixa delimitadora, consulta a secção Caixas do modo Prever
O que é que este código faz?
Quando utilizas
c.boxes.xyxy.cpu().numpy()
as caixas delimitadoras são devolvidas como uma matriz NumPy, utilizando a funçãoxyxy
formato das coordenadas da caixa, que correspondem aos pontosxmin, ymin, xmax, ymax
para a caixa delimitadora (retângulo), consulta Secção de caixas do modo de previsão para mais informações.Acrescentar
squeeze()
assegura que quaisquer dimensões estranhas são removidas da matriz NumPy.Converte os valores das coordenadas utilizando
.astype(np.int32)
altera o tipo de dados das coordenadas da caixa defloat32
paraint32
que será compatível quando recortares a imagem utilizando cortes de índice.Finalmente, a região da imagem para a caixa delimitadora é cortada utilizando o corte de índice, em que os limites são definidos utilizando a função
[ymin:ymax, xmin:xmax]
coordenadas da caixa delimitadora da deteção.
E se eu quiser o objeto cortado incluindo o fundo?
Esta é uma funcionalidade incorporada na biblioteca Ultralytics . Vê a página
save_crop
argumento para Argumentos de inferência do modo de previsão para mais pormenores.O que fazer a seguir é inteiramente deixado ao teu critério como programador. É apresentado um exemplo básico de um passo seguinte possível (guardar a imagem num ficheiro para utilização futura).
- NOTA: este passo é opcional e pode ser ignorado se não for necessário para o teu caso de utilização específico.
Exemplo Etapa final
- Neste exemplo, o
img_name
é o nome base do ficheiro de imagem de origem,label
é o nome da classe detectada, eci
is the index of the deteção de objectos (in case of multiple instances with the same class name).
Código de exemplo completo
Aqui, todos os passos da secção anterior são combinados num único bloco de código. Para uma utilização repetida, seria ótimo definir uma função para executar alguns ou todos os comandos contidos no bloco for
-loops, mas isso é um exercício deixado ao 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 o
contour
é combinada numa única linha aqui, onde foi dividida em várias acima. - O que vai aqui é contigo!
- Consulta o Modo de previsão para obteres mais informações.
- Para mais informações, consulta Tarefa de segmento.
- Sabe mais sobre Trabalhar com resultados
- Sabe mais sobre os resultados da máscara de segmentação
FAQ
Como posso isolar objectos utilizando Ultralytics YOLO11 para tarefas de segmentação?
Para isolar objectos utilizando Ultralytics YOLO11, segue estes passos:
Carrega o modelo e executa a inferência:
Gera uma máscara binária e desenha contornos:
Isola o objeto utilizando a máscara binária:
Para mais informações, consulta o guia sobre o Modo de previsão e a Tarefa de segmento.
Que opções estão disponíveis para guardar os objectos isolados após a segmentação?
Ultralytics O YOLO11 oferece duas opções principais para guardar objectos isolados:
Com um fundo preto:
Com um fundo transparente:
Para mais informações, visita a secção Modo de previsão.
Como posso cortar objectos isolados para as suas caixas delimitadoras utilizando Ultralytics YOLO11?
Recorta objectos isolados para as suas caixas delimitadoras:
Recupera as coordenadas da caixa delimitadora:
Corta a imagem isolada:
Sabe mais sobre os resultados da caixa delimitadora na documentação do Modo de previsão.
Por que razão devo utilizar o Ultralytics YOLO11 para o isolamento de objectos em tarefas de segmentação?
Ultralytics YOLO11 fornece-te:
- Deteção e segmentação de objectos a alta velocidade e em tempo real.
- Geração precisa da caixa delimitadora e da máscara para um isolamento preciso do objeto.
- Documentação abrangente e API fácil de utilizar para um desenvolvimento eficiente.
Explora as vantagens de utilizar YOLO na documentação da Tarefa de Segmento.
Posso guardar objectos isolados, incluindo o fundo, utilizando Ultralytics YOLO11?
Sim, esta é uma funcionalidade incorporada em Ultralytics YOLO11. Utiliza o botão save_crop
no argumento predict()
método. Por exemplo:
Lê mais sobre o save_crop
no argumento Argumentos de inferência do modo de previsão secção.