Saltar para o conteúdo

Isolamento de objectos 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.

Exemplo de segmentação de objectos isolados

Passeio pelas receitas

  1. Consulte a secçãoUltralytics Quickstart Installation para obter um passo-a-passo rápido sobre a instalação das bibliotecas necessárias.


  2. Carregar um modelo e executar predict() numa fonte.

    from ultralytics import YOLO
    
    # Load a model
    model = YOLO("yolo11n-seg.pt")
    
    # Run inference
    results = model.predict()
    

    Não há argumentos de previsão?

    Sem especificar uma fonte, serão utilizadas as imagens de exemplo da biblioteca:

    '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 os modelos de segmentação, visite o site Tarefa do segmento página. Para saber mais sobre predict() método, ver Modo de previsão secção da Documentação.


  3. Agora itere sobre os resultados e os contornos. Para fluxos de trabalho que pretendem guardar uma imagem num ficheiro, a imagem de origem base-name e a deteção class-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()]
    
    1. Para saber mais sobre como trabalhar com resultados de deteção, consulte a secção Caixas para o modo de previsão.
    2. Para saber mais sobre predict() resultados ver Trabalho com resultados do modo de previsão
    For-Loop

    Uma única imagem só irá iterar o primeiro ciclo uma vez. Uma única imagem com apenas uma única deteção irá iterar cada ciclo apenas uma vez.


  4. Comece por gerar uma máscara binária a partir da imagem de origem e, em seguida, desenhe 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 person é mostrado à direita.

    Imagem de máscara binária

    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)
    
    1. Para mais informações sobre c.masks.xy ver Secção de máscaras do modo de previsão.

    2. Aqui os valores são convertidos em np.int32 para compatibilidade com drawContours() função de OpenCV.

    3. O OpenCV drawContours() espera que os contornos tenham uma forma de [N, 1, 2] expandir a secção abaixo para mais pormenores.

    Expandir 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, consultar o Secção de máscaras do modo de previsão.

    • .pop() :: Como masks.xy é uma lista que contém um único elemento, este elemento é extraído utilizando o pop() método.

    • .astype(np.int32) :: Utilizar masks.xy retornará com um tipo de dados de float32mas isso não será compatível com o OpenCV drawContours() por isso, isto irá alterar o tipo de dados para int32 para compatibilidade.

    • .reshape(-1, 1, 2) :: Reformata os dados na forma requerida de [N, 1, 2] onde N é o número de pontos de contorno, sendo cada ponto representado por uma única entrada 1e a entrada é composta por 2 valores. Os -1 indica que o número de valores ao longo desta dimensão é flexível.

    Expandir para uma explicação do drawContours() configuração.

    • Encapsulando o contour variável entre parênteses rectos, [contour]foi considerado eficaz para gerar a máscara de contorno desejada durante os testes.

    • O valor -1 especificado para o drawContours() 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 irá colorir da mesma forma todos os pixéis incluídos no limite do contorno, neste caso, todos os pixéis incluídos serão brancos.

    • Ver Documentação do OpenCV em drawContours() para mais informações.


  5. De seguida, existem 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?
    • Em primeiro lugar, 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.

    Exemplo de imagem de objeto isolado em tamanho real com fundo preto
    Exemplo de saída em tamanho real

    Imagem do objeto recortada

    São necessários passos adicionais para cortar a imagem de modo a incluir apenas a região do objeto.

    Exemplo de recorte de imagem de objeto isolado com fundo preto

    # (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]
    

    1. Para mais informações sobre os resultados da caixa delimitadora, consulte Secção de caixas do modo Prever
    O que é que este código faz?
    • O c.boxes.xyxy.cpu().numpy() recupera as caixas delimitadoras como uma matriz NumPy no xyxy formato, em que xmin, ymin, xmaxe ymax representam as coordenadas do retângulo da caixa delimitadora. Ver 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.

    • Converter os valores das coordenadas utilizando .astype(np.int32) altera o tipo de dados das coordenadas da caixa de float32 para int32tornando-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 [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 uma PNG ficheiro.

    Isolar com píxeis transparentes: Sub-opções

    Imagem em tamanho real

    Não são necessários passos adicionais para manter a imagem em tamanho real.

    Exemplo Imagem de objeto isolado em tamanho real sem fundo
    Exemplo de saída em tamanho real + fundo transparente

    Imagem do objeto recortada

    São necessários passos adicionais para cortar a imagem de modo a incluir apenas a região do objeto.

    Exemplo de recorte de imagem de objeto isolado sem fundo

    # (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]
    

    1. Para mais informações sobre os resultados da caixa delimitadora, consulte Secção de caixas do modo Prever
    O que é que este código faz?
    • Ao utilizar c.boxes.xyxy.cpu().numpy()as caixas delimitadoras são devolvidas como uma matriz NumPy, utilizando a função xyxy formato das coordenadas da caixa, que correspondem aos pontos xmin, ymin, xmax, ymax para a caixa delimitadora (retângulo), ver Secção de caixas do modo de previsão para mais informações.

    • Adição squeeze() assegura que quaisquer dimensões estranhas são removidas da matriz NumPy.

    • Converter os valores das coordenadas utilizando .astype(np.int32) altera o tipo de dados das coordenadas da caixa de float32 para int32 que será compatível com o recorte da imagem utilizando cortes de índice.

    • Por fim, 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 . Veja o save_crop argumento para Argumentos de inferência do modo de previsão para mais pormenores.


  6. O que fazer a seguir é inteiramente deixado ao critério do 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 seu caso de utilização específico.
    Exemplo Etapa final
    # Save isolated object to file
    _ = cv2.imwrite(f"{img_name}_{label}-{ci}.png", iso_crop)
    
    • Neste exemplo, o img_name é o nome de base do ficheiro de imagem de origem, label é o nome da classe detectada, e ci é o índice do deteção de objectos (no caso de múltiplas instâncias com o mesmo nome de classe).

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-mas isso é 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)
  1. A linha que preenche contour é combinada numa única linha aqui, onde foi dividida em várias acima.
  2. O que vai aqui é consigo!
  3. Consulte Modo de previsão para obter informações adicionais.
  4. Consulte Tarefa de segmento para obter mais informações.
  5. Saiba mais sobre Trabalhar com resultados
  6. Saiba 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 , siga estes passos:

  1. 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")
    
  2. Gerar uma máscara binária e desenhar 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)
    
  3. Isolar o objeto utilizando a máscara binária:

    mask3ch = cv2.cvtColor(b_mask, cv2.COLOR_GRAY2BGR)
    isolated = cv2.bitwise_and(mask3ch, img)
    

Para mais informações, consulte 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 YOLO11 oferece duas opções principais para guardar objectos isolados:

  1. Com um fundo preto:

    mask3ch = cv2.cvtColor(b_mask, cv2.COLOR_GRAY2BGR)
    isolated = cv2.bitwise_and(mask3ch, img)
    
  2. Com um fundo transparente:

    isolated = np.dstack([img, b_mask])
    

Para mais informações, visite a secção Modo de previsão.

Como posso cortar objectos isolados para as suas caixas delimitadoras utilizando Ultralytics YOLO11 ?

Para cortar objectos isolados nas suas caixas delimitadoras:

  1. Recuperar coordenadas da caixa delimitadora:

    x1, y1, x2, y2 = results[0].boxes.xyxy[0].cpu().numpy().astype(np.int32)
    
  2. Recorte a imagem isolada:

    iso_crop = isolated[y1:y2, x1:x2]
    

Saiba mais sobre os resultados da caixa delimitadora na documentação do Modo de previsão.

Por que razão devo utilizar Ultralytics YOLO11 para o isolamento de objectos em tarefas de segmentação?

Ultralytics YOLO11 fornece:

  • Deteção e segmentação de objectos em tempo real e a alta velocidade.
  • Geração precisa de caixas delimitadoras e máscaras para um isolamento preciso dos objectos.
  • Documentação abrangente e API fácil de utilizar para um desenvolvimento eficiente.

Explore 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 . Utilize o botão save_crop argumento no predict() método. Por exemplo:

results = model.predict(source="path/to/your/image.jpg", save_crop=True)

Saiba mais sobre o save_crop argumento no Argumentos de inferência do modo de previsão secção.

📅C riado há 1 ano ✏️ Atualizado há 2 meses

Comentários