A tarefa "Segmentação de imagens" permite dividir imagens em regiões com base em e aplicar efeitos visuais como o desfoque do plano de fundo. Esses mostram como usar o segmentador de imagens com aplicativos para iOS.
O exemplo de código descrito nestas instruções está disponível em GitHub.
Para ver essa tarefa em ação, visualizando o demonstração. Para mais informações sobre recursos, modelos e opções de configuração, desta tarefa, consulte a Visão geral.
Exemplo de código
O exemplo de código do MediaPipe Tasks contém uma implementação simples de uma Aplicativo de segmentação de imagens para iOS.
O exemplo implementa um segmento de imagens que gera máscaras de categoria. Ela usa a câmera de um dispositivo iOS físico para realizar a segmentação de imagens em um feed da câmera ou em imagens e vídeos da galeria do dispositivo.
Você pode usar o app como ponto de partida para seu próprio app iOS ou consultá-lo ao modificar um aplicativo existente. O exemplo de código do segmentador de imagens está hospedado GitHub.
Fazer o download do código
As instruções a seguir mostram como criar uma cópia local do exemplo. usando a ferramenta de linha de comando git.
Para fazer o download do código de exemplo:
Clone o repositório git usando o seguinte comando:
git clone https://github.com/google-ai-edge/mediapipe-samples/
Opcionalmente, configure sua instância git para usar a finalização esparsa. Assim, você terá somente os arquivos do aplicativo de exemplo do Segmentador de imagens:
cd mediapipe git sparse-checkout init --cone git sparse-checkout set examples/image_segmentation/ios/
Depois de criar uma versão local do código de exemplo, você pode instalar o MediaPipe, abrir o projeto usando Xcode e executar o app. Para instruções, consulte o Guia de configuração do iOS.
Principais componentes
Os arquivos a seguir contêm o código essencial para o exemplo do segmentador de imagens aplicativo:
- ImageSegmenterService.swift: Inicializa o segmentador de imagens, processa a seleção do modelo e executa inferência nos dados de entrada.
- CameraViewController.swift: Implementa a interface para o modo de entrada de transmissão da câmera em tempo real e visualiza a resultados.
- MediaLibraryViewController.swift Implementa a interface para o modo de entrada de arquivo de vídeo e imagem estática e visualiza os resultados.
Configuração
Esta seção descreve as principais etapas para configurar seu ambiente de desenvolvimento e projetos de código para usar o segmentador de imagens. Para informações gerais sobre como configurar sua ambiente de desenvolvimento para usar tarefas do MediaPipe, incluindo a versão da plataforma , consulte o Guia de configuração para iOS.
Dependências
O segmentador de imagens usa a biblioteca MediaPipeTasksVision
, que precisa ser instalada
usando o CocoaPods. A biblioteca é compatível com aplicativos Swift e Objective-C
e não requer configuração específica do idioma.
Para instruções sobre como instalar o CocoaPods no macOS, consulte a documentação do CocoaPods
guia de instalação (em inglês).
Para instruções sobre como criar um Podfile
com os pods necessários para
aplicativo, consulte Usar
CocoaPods.
Adicione o pod do MediaPipeTasksVision no Podfile
usando o seguinte código:
target 'MyImageSegmenterApp' do
use_frameworks!
pod 'MediaPipeTasksVision'
end
Se o app incluir destinos de teste de unidade, consulte o Guia de configuração do
iOS para mais informações sobre a configuração
seu Podfile
.
Modelo
A tarefa do segmentador de imagens do MediaPipe requer um modelo treinado que seja compatível a essa tarefa. Para mais informações sobre os modelos treinados disponíveis para Segmentador de imagens, consulte a visão geral da tarefa Modelos .
Selecione e faça o download de um modelo e adicione-o ao diretório do projeto usando o Xcode. Para instruções sobre como adicionar arquivos ao seu projeto Xcode, consulte Como gerenciar arquivos e pastas no seu Xcode projeto.
Use a propriedade BaseOptions.modelAssetPath
para especificar o caminho para o modelo.
no seu pacote de apps. Para conferir um exemplo de código, consulte a próxima seção.
Criar a tarefa
É possível criar a tarefa "Segmento de imagem" chamando um dos inicializadores. O
O inicializador ImageSegmenter(options:)
aceita valores para a configuração.
.
Se você não precisa que um segmento de imagem seja inicializado com configuração personalizada
você pode usar o inicializador ImageSegmenter(modelPath:)
para criar um
Segmentação de imagens com as opções padrão. Para mais informações sobre configurações
opções, consulte Visão geral da configuração.
A tarefa Segmentador de imagens é compatível com três tipos de dados de entrada: imagens estáticas e arquivos de vídeo.
e transmissões de vídeo ao vivo. Por padrão, ImageSegmenter(modelPath:)
inicializa uma
para imagens estáticas. Se você quiser que sua tarefa seja inicializada para processar vídeos
arquivos ou streams de vídeo ao vivo, use ImageSegmenter(options:)
para especificar o
ou no modo de corrida ao vivo. O modo de transmissão ao vivo também requer
imageSegmenterLiveStreamDelegate
, que ativa
O segmentador de imagens para fornecer resultados de segmentação de imagens ao delegado
de forma assíncrona.
Escolha a guia correspondente ao modo de corrida para saber como criar a tarefa e executar inferência.
Swift
Imagem
import MediaPipeTasksVision let modelPath = Bundle.main.path(forResource: "model", ofType: "tflite") let options = ImageSegmenterOptions() options.baseOptions.modelAssetPath = modelPath options.runningMode = .image options.shouldOutputCategoryMask = true options.shouldOutputConfidenceMasks = false let imageSegmenter = try ImageSegmenter(options: options)
Vídeo
import MediaPipeTasksVision let modelPath = Bundle.main.path(forResource: "model", ofType: "tflite") let options = ImageSegmenterOptions() options.baseOptions.modelAssetPath = modelPath options.runningMode = .video options.shouldOutputCategoryMask = true options.shouldOutputConfidenceMasks = false let imageSegmenter = try ImageSegmenter(options: options)
Transmissão ao vivo
import MediaPipeTasksVision // Class that conforms to the `imageSegmenterLiveStreamDelegate` protocol and // implements the method that the image segmenter calls once it finishes // performing segmentation of each input frame. class ImageSegmenterResultProcessor: NSObject, ImageSegmenterLiveStreamDelegate { func imageSegmenter( _ imageSegmenter: ImageSegmenter, didFinishSegmentation result: ImageSegmenterResult?, timestampInMilliseconds: Int, error: Error?) { // Process the image segmentation result or errors here. } } let modelPath = Bundle.main.path(forResource: "model", ofType: "tflite") let options = ImageSegmenterOptions() options.baseOptions.modelAssetPath = modelPath options.runningMode = .liveStream options.shouldOutputCategoryMask = true options.shouldOutputConfidenceMasks = false // Set `imageSegmenterLiveStreamDelegate` to the object of the class that // confirms to the `ImageSegmenterLiveStreamDelegate` protocol. let processor = ImageSegmenterResultProcessor() options.imageSegmenterLiveStreamDelegate = processor let imageSegmenter = try ImageSegmenter(options: options)
Objective-C
Imagem
@import MediaPipeTasksVision; NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"model" ofType:@"tflite"]; MPPImageSegmenterOptions *options = [[MPPImageSegmenterOptions alloc] init]; options.baseOptions.modelAssetPath = modelPath; options.runningMode = MPPRunningModeImage; options.shouldOutputCategoryMask = YES; options.shouldOutputConfidenceMasks = NO; MPPImageSegmenter *imageSegmenter = [[MPPImageSegmenter alloc] initWithOptions:options error:nil];
Vídeo
@import MediaPipeTasksVision; NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"model" ofType:@"tflite"]; MPPImageSegmenterOptions *options = [[MPPImageSegmenterOptions alloc] init]; options.baseOptions.modelAssetPath = modelPath; options.runningMode = MPPRunningModeVideo; options.shouldOutputCategoryMask = YES; options.shouldOutputConfidenceMasks = NO; MPPImageSegmenter *imageSegmenter = [[MPPImageSegmenter alloc] initWithOptions:options error:nil];
Transmissão ao vivo
@import MediaPipeTasksVision; // Class that conforms to the `MPPImageSegmenterLiveStreamDelegate` protocol // and implements the method that the image segmenter calls once it finishes // performing segmentation of each input frame. @interface APPImageSegmenterResultProcessor : NSObject@end @implementation APPImageSegmenterResultProcessor - (void)imageSegmenter:(MPPImageSegmenter *)imageSegmenter didFinishSegmentationWithResult:(MPPImageSegmenterResult *)imageSegmenterResult timestampInMilliseconds:(NSInteger)timestampInMilliseconds error:(NSError *)error { // Process the image segmentation result or errors here. } @end NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"model" ofType:@"tflite"]; MPPImageSegmenterOptions *options = [[MPPImageSegmenterOptions alloc] init]; options.baseOptions.modelAssetPath = modelPath; options.runningMode = MPPRunningModeLiveStream; options.shouldOutputCategoryMask = YES; options.shouldOutputConfidenceMasks = NO; // Set `imageSegmenterLiveStreamDelegate` to the object of the class that // confirms to the `MPPImageSegmenterLiveStreamDelegate` protocol. APPImageSegmenterResultProcessor *processor = [APPImageSegmenterResultProcessor new]; options.imageSegmenterLiveStreamDelegate = processor; MPPImageSegmenter *imageSegmenter = [[MPPImageSegmenter alloc] initWithOptions:options error:nil];
A implementação de código de exemplo do segmentador de imagens permite que o usuário alterne entre os modos de processamento. A abordagem torna o código de criação da tarefa mais complicado podem não ser adequados para seu caso de uso.
Opções de configuração
Esta tarefa tem as seguintes opções de configuração para apps iOS:
Nome da opção | Descrição | Intervalo de valor | Valor padrão |
---|---|---|---|
runningMode |
Define o modo de execução da tarefa. Existem três
modos: IMAGEM: o modo para entradas de imagem única. VÍDEO: o modo para frames decodificados de um vídeo. LIVE_STREAM: o modo de transmissão ao vivo da entrada dados de uma câmera, por exemplo. Neste modo, ImageSegmenterLiveStreamDelegate
precisa ser definido como uma instância de uma classe que implemente o
ImageSegmenterLiveStreamDelegate para receber a segmentação.
resultados de forma assíncrona.
|
{RunningMode.image, RunningMode.video, RunningMode.liveStream } |
RunningMode.image |
shouldOutputCategoryMask |
Se definido como True , a saída incluirá uma máscara de segmentação
como uma imagem uint8, em que cada valor de pixel indica a categoria vencedora
. |
{True, False } |
False |
shouldOutputConfidenceMasks |
Se definido como True , a saída incluirá uma máscara de segmentação
como uma imagem de valor flutuante, em que cada valor flutuante representa a confiança
mapa de pontuação da categoria. |
{True, False } |
True |
displayNamesLocale |
Define o idioma dos rótulos a serem usados para os nomes de exibição fornecidos no
metadados do modelo da tarefa, se disponíveis. O padrão é en para
inglês. É possível adicionar rótulos localizados aos metadados de um modelo personalizado
usando a API Metadata Writer do TensorFlow Lite; |
Código da localidade | en |
result_callback |
Define o listener de resultados para receber os resultados da segmentação.
de forma assíncrona quando o segmentador de imagens está no modo LIVE_STREAM .
Só pode ser usado quando o modo de corrida está definido como LIVE_STREAM |
N/A | N/A |
Quando o modo de execução é definido como LIVE_STREAM
, o segmentador de imagem exige o
opção de configuração imageSegmenterLiveStreamDelegate
adicional, que
permite que o segmentador de imagens forneça resultados de segmentação de imagens de forma assíncrona.
O delegado deve implementar o
método imageSegmenter(_:didFinishSegmentation:timestampInMilliseconds:error:)
,
que o segmentador de imagens chama depois de processar os resultados da execução
em cada frame.
Nome da opção | Descrição | Intervalo de valor | Valor padrão |
---|---|---|---|
imageSegmenterLiveStreamDelegate |
Permite que o segmentador de imagens receba os resultados da imagem de performance
a segmentação de maneira assíncrona no modo de transmissão ao vivo. A classe cuja instância é
definida nessa propriedade precisa implementar o
imageSegmenter(_:didFinishSegmentation:timestampInMilliseconds:error:)
. |
Não relevante | Não definido |
Preparar dados
É necessário converter a imagem ou o frame de entrada em um objeto MPImage
antes
passando-a para o segmentador de imagens. MPImage
oferece suporte a diferentes tipos de imagens do iOS
formatos e pode usá-los em qualquer modo em execução para inferência. Para mais
informações sobre MPImage
, consulte
API MPImage
Escolha um formato de imagem iOS com base no seu caso de uso e no modo de execução que seu
exigido pelo aplicativo.MPImage
aceita UIImage
, CVPixelBuffer
e
CMSampleBuffer
formatos de imagem do iOS.
UIImage
O formato UIImage
é adequado para os seguintes modos de execução:
Imagens: imagens de um pacote de apps, galeria do usuário ou sistema de arquivos formatados como
UIImage
imagens podem ser convertidas em um objetoMPImage
.Vídeos: use AVAssetImageGenerator para extrair frames de vídeo CGImage formato e converta-as em imagens
UIImage
.
Swift
// Load an image on the user's device as an iOS `UIImage` object. // Convert the `UIImage` object to a MediaPipe's Image object having the default // orientation `UIImage.Orientation.up`. let image = try MPImage(uiImage: image)
Objective-C
// Load an image on the user's device as an iOS `UIImage` object. // Convert the `UIImage` object to a MediaPipe's Image object having the default // orientation `UIImageOrientationUp`. MPImage *image = [[MPPImage alloc] initWithUIImage:image error:nil];
O exemplo inicializa um MPImage
com o
UIImage.Orientation.Up
orientação. É possível inicializar um MPImage
com qualquer um dos
UIImage.Orientation
e a distribuição dos valores dos dados. O segmentador de imagem não oferece suporte a orientações espelhadas como .upMirrored
,
.downMirrored
, .leftMirrored
e .rightMirrored
.
Para mais informações sobre o UIImage
, consulte a página do desenvolvedor de imagens de usuário
Documentação.
CVPixelBuffer
O formato CVPixelBuffer
é adequado para aplicativos que geram frames
e usar a interface CoreImage do iOS
para processamento.
O formato CVPixelBuffer
é adequado para os seguintes modos de execução:
Imagens: apps que geram imagens de
CVPixelBuffer
após algum processamento. usando a estruturaCoreImage
do iOS podem ser enviadas ao segmentador de imagens na modo de execução de imagem.Vídeos: os quadros podem ser convertidos para o formato
CVPixelBuffer
para e enviados ao segmentador de imagens no modo de vídeo.Transmissão ao vivo: apps que usam a câmera do iOS para gerar frames podem ser convertidos no formato
CVPixelBuffer
para processamento antes de ser enviado ao Segmentação de imagens no modo de transmissão ao vivo.
Swift
// Obtain a CVPixelBuffer. // Convert the `CVPixelBuffer` object to a MediaPipe's Image object having the default // orientation `UIImage.Orientation.up`. let image = try MPImage(pixelBuffer: pixelBuffer)
Objective-C
// Obtain a CVPixelBuffer. // Convert the `CVPixelBuffer` object to a MediaPipe's Image object having the // default orientation `UIImageOrientationUp`. MPImage *image = [[MPPImage alloc] initWithUIImage:image error:nil];
Para mais informações sobre o CVPixelBuffer
, consulte a documentação da Apple CVPixelBuffer
Desenvolvedor
Documentação.
CMSampleBuffer
O formato CMSampleBuffer
armazena amostras de mídia de um tipo uniforme de mídia e é
adequado para o modo de transmissão ao vivo. Os frames ao vivo das câmeras do iOS são
enviados de forma assíncrona no formato CMSampleBuffer
pelo iOS
AVCaptureVideoDataOutput.
Swift
// Obtain a CMSampleBuffer. // Convert the `CMSampleBuffer` object to a MediaPipe's Image object having the default // orientation `UIImage.Orientation.up`. let image = try MPImage(sampleBuffer: sampleBuffer)
Objective-C
// Obtain a `CMSampleBuffer`. // Convert the `CMSampleBuffer` object to a MediaPipe's Image object having the // default orientation `UIImageOrientationUp`. MPImage *image = [[MPPImage alloc] initWithSampleBuffer:sampleBuffer error:nil];
Para mais informações sobre o CMSampleBuffer
, consulte a documentação da Apple do CMSampleBuffer
Desenvolvedor
Documentação.
Executar a tarefa
Para executar o segmentador de imagens, use o método segment()
específico do
modo de corrida:
- Imagem estática:
segment(image:)
- Vídeo:
segment(videoFrame:timestampInMilliseconds:)
- Transmissão ao vivo:
segmentAsync(image:timestampInMilliseconds:)
Os exemplos de código a seguir mostram exemplos simples de como executar o segmentador de imagens no estes diferentes modos de execução:
Swift
Imagem
let result = try imageSegmenter.segment(image: image)
Vídeo
let result = try imageSegmenter.segment( videoFrame: image, timestampInMilliseconds: timestamp)
Transmissão ao vivo
try imageSegmenter.segmentAsync( image: image, timestampInMilliseconds: timestamp)
Objective-C
Imagem
MPPImageSegmenterResult *result = [imageSegmenter segmentImage:image error:nil];
Vídeo
MPPImageSegmenterResult *result = [imageSegmenter segmentVideoFrame:image timestampInMilliseconds:timestamp error:nil];
Transmissão ao vivo
BOOL success = [imageSegmenter segmentAsyncImage:image timestampInMilliseconds:timestamp error:nil];
O exemplo de código do segmentador de imagens mostra as implementações de cada um desses modos
em mais detalhes segment(image:)
,
segment(videoFrame:timestampInMilliseconds:)
e
segmentAsync(image:timestampInMilliseconds:)
Observe o seguinte:
Ao executar no modo de vídeo ou de transmissão ao vivo, você também precisa fornecer os carimbo de data/hora do frame de entrada para a tarefa do Segmentador de imagens.
Ao ser executada no modo de imagem ou vídeo, a tarefa Segmentador de imagem bloqueia linha de execução atual até terminar de processar a imagem ou frame de entrada. Para evite o bloqueio da linha de execução atual, execute o processamento em segundo plano conversa usando iOS Dispatch ou NSOperation frameworks.
Quando executada no modo de transmissão ao vivo, a tarefa do segmentador de imagens retorna imediatamente e não bloqueia a linha de execução atual. Ele invoca
imageSegmenter(_:didFinishSegmentation:timestampInMilliseconds:error:)
com o segmentador de imagens depois de processar cada frame de entrada. O O segmentador de imagem invoca esse método de forma assíncrona em um número de série dedicado fila de despacho. Para exibir resultados na interface do usuário, envie o para a fila principal após o processamento dos resultados. Se o A funçãosegmentAsync
é chamada quando a tarefa do segmentador de imagens está ocupada. processar outro frame, o segmentador de imagens ignora o novo frame de entrada.
Gerenciar e exibir resultados
Ao executar a inferência, a tarefa do segmentador de imagens retorna um ImageSegmenterResult
.
que contém os resultados da tarefa de segmentação. O conteúdo do
depende do tipo de saída que você definiu ao
configurado
a tarefa.
As imagens a seguir mostram uma visualização da saída da tarefa para uma categoria
máscara de valor. O intervalo da máscara de categoria é [0, 255]
, e cada valor de pixel
representa o índice de categoria vencedora da saída do modelo. A categoria vencedora
tem a pontuação mais alta entre as categorias que o modelo pode reconhecer.
Imagem original e saída de máscara de categoria. Imagem de origem do Pascal VOC 2012 (em inglês) no conjunto de dados.
O código de exemplo do segmentador de imagens demonstra como exibir o segmentador de imagens resultados, consulte o código exemplo para mais detalhes.