Ir para o conteúdo

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.

Exemplo de Segmentação de Objeto Isolado

Passo a Passo da Receita

  1. 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.


  2. 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.


  3. 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ção class-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()]
    
    1. Para saber mais sobre como trabalhar com resultados de detecção, consulte a Seção de Caixas para o Modo de Previsão.
    2. 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.


  4. 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 detetados person objetos de classe são mostrados à 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 Seção de Máscaras do Modo de Predição.

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

    3. 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() :: Como masks.xy é uma lista contendo um único elemento; este elemento é extraído usando o pop() método. - .astype(np.int32) :: Usando masks.xy retornará com um tipo de dado de float32, mas isso não será compatível com o OpenCV drawContours() função, então isso mudará o tipo de dado para int32 para compatibilidade. - .reshape(-1, 1, 2) :: Reformata os dados para o formato necessário de [N, 1, 2] onde N é o número de pontos de contorno, com cada ponto representado por uma única entrada 1, e a entrada é composta por 2 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 o drawContours() parâmetro instrui a função a 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 todos os pixels delimitados pelo contorno da mesma cor, neste caso, todos os pixels delimitados serão brancos. - Ver Documentação OpenCV sobre drawContours() para mais informações.


  5. 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 Imagem de Objeto Isolado em Tamanho Real Fundo Preto
    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.

    Exemplo de Imagem de Objeto Isolado Recortado 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 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 no xyxy formato, onde xmin, ymin, xmax, e ymax 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 de float32 para int32, 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 um PNG 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 Imagem de Objeto Isolado em Tamanho Real Sem Fundo
    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.

    Exemplo de Imagem de Objeto Isolado Recortado 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 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 o xyxy formato das coordenadas da caixa, que correspondem aos pontos xmin, 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 de float32 para int32 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.


  6. 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, e ci é 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)
  1. A linha que preenche contour é combinado em uma única linha aqui, onde foi dividido em várias acima.
  2. O que vai aqui depende de você!
  3. Consulte o Modo de Predição para obter informações adicionais.
  4. Consulte Tarefa de Segmentação para obter mais informações.
  5. Saiba mais sobre Como Trabalhar com Resultados.
  6. 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:

  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. 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)
    
  3. 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:

  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 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:

  1. Recuperar coordenadas da caixa delimitadora:

    x1, y1, x2, y2 = results[0].boxes.xyxy[0].cpu().numpy().astype(np.int32)
    
  2. 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.



📅 Criado há 1 ano ✏️ Atualizado há 23 dias

Comentários