Guida alla segmentazione delle immagini per iOS

L'attività Segmentazione delle immagini ti consente di dividere le immagini in regioni in base a categorie e applicare effetti visivi come la sfocatura dello sfondo. Questi istruzioni mostrano come utilizzare lo strumento di segmentazione delle immagini con le app per iOS.

L'esempio di codice descritto in queste istruzioni è disponibile su GitHub.

Puoi vedere questa attività in azione visualizzando la una demo. Per ulteriori informazioni su funzionalità, modelli e opzioni di configurazione di questa attività, controlla Panoramica.

Esempio di codice

L'esempio di codice Attività MediaPipe contiene una semplice implementazione di un App di segmentazione delle immagini per iOS.

L'esempio implementa uno strumento di segmentazione delle immagini che restituisce maschere di categoria. Utilizza la fotocamera di un dispositivo iOS fisico per eseguire la segmentazione delle immagini su un feed della videocamera o su immagini e video della galleria del dispositivo.

Puoi utilizzare l'app come punto di partenza per la tua app per iOS o fare riferimento all'app quando modifichi un'app esistente. Il codice di esempio del segmento di immagini è ospitato su GitHub.

Scarica il codice

Le seguenti istruzioni mostrano come creare una copia locale dell'esempio utilizzando lo strumento a riga di comando git.

Per scaricare il codice di esempio:

  1. Clona il repository git utilizzando il comando seguente:

    git clone https://github.com/google-ai-edge/mediapipe-samples/
    
  2. Facoltativamente, configura la tua istanza Git per l'utilizzo di un pagamento sparso, in modo da avere solo i file per l'app di esempio dello strumento di segmentazione delle immagini:

    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/image_segmentation/ios/
    

Dopo aver creato una versione locale del codice di esempio, puoi installare nella libreria di attività MediaPipe, apri il progetto con Xcode ed esegui l'app. Per istruzioni, vedi la Guida alla configurazione per iOS.

Componenti chiave

I seguenti file contengono il codice fondamentale per l'esempio della funzionalità di segmentazione delle immagini applicazione:

  • ImageSegmenterService.swift: Inizializza il Segmenter di immagini, gestisce la selezione del modello ed esegue l'inferenza sui dati di input.
  • CameraViewController.swift: Implementa l'interfaccia utente per la modalità di immissione del feed della videocamera in diretta e visualizza la che consentono di analizzare i dati e visualizzare i risultati.
  • MediaLibraryViewController.swift Implementa l'interfaccia utente per la modalità di immissione di file di immagini e video e per visualizzare i risultati.

Configurazione

Questa sezione descrive i passaggi chiave per configurare l'ambiente di sviluppo e di codice per usare la segmentazione delle immagini. Per informazioni generali sulla configurazione dell'ambiente di sviluppo per l'uso di attività MediaPipe, inclusa la versione della piattaforma consulta la Guida alla configurazione per iOS.

Dipendenze

La funzionalità di segmentazione delle immagini utilizza la libreria MediaPipeTasksVision, che deve essere installata utilizzando CocoaPods. La raccolta è compatibile con le app Swift e Objective-C e non richiede alcuna configurazione aggiuntiva specifica per la lingua.

Per istruzioni su come installare CocoaPods su macOS, consulta l'articolo CocoaPods Guida all'installazione. Per istruzioni su come creare un elemento Podfile con i pod necessari per il tuo consulta la sezione Utilizzo CocoaPods.

Aggiungi il pod MediaPipeTasksVision in Podfile utilizzando il seguente codice:

target 'MyImageSegmenterApp' do
  use_frameworks!
  pod 'MediaPipeTasksVision'
end

Se la tua app include target dei test delle unità, consulta la Guida alla configurazione per iOS per ulteriori informazioni sulla configurazione il tuo Podfile.

Modello

L'attività Segmenter immagini MediaPipe richiede un modello addestrato compatibile con questa attività. Per saperne di più sui modelli addestrati disponibili Segmenter immagini; consulta la panoramica dell'attività Modelli .

Seleziona e scarica un modello, quindi aggiungilo alla directory del progetto utilizzando Xcode. Per istruzioni su come aggiungere file al progetto Xcode, consulta Gestione i file e le cartelle in Xcode progetto.

Utilizza la proprietà BaseOptions.modelAssetPath per specificare il percorso del modello nel tuo app bundle. Per un esempio di codice, consulta la sezione successiva.

Crea l'attività

Puoi creare l'attività Segmentazione delle immagini richiamando uno dei suoi inizializzatori. La L'inizializzazione di ImageSegmenter(options:) accetta valori per la configurazione le opzioni di CPU e memoria disponibili.

Se non ti occorre un Segmenter di immagini inizializzato con una configurazione personalizzata puoi usare l'inizializzatore ImageSegmenter(modelPath:) per creare Segmentazione di immagini con le opzioni predefinite. Per ulteriori informazioni sulla configurazione vedi Panoramica della configurazione.

L'attività Segmentazione delle immagini supporta tre tipi di dati di input: immagini fisse e file video e video stream in diretta. Per impostazione predefinita, ImageSegmenter(modelPath:) inizializza una per le immagini statiche. Se vuoi che l'attività venga inizializzata per elaborare il video file o stream video in diretta, usa ImageSegmenter(options:) per specificare il video modalità di corsa o live streaming. La modalità live streaming richiede anche di configurazione di imageSegmenterLiveStreamDelegate, che attiva Segmentazione di immagini per fornire al delegato i risultati di segmentazione delle immagini in modo asincrono.

Scegli la scheda corrispondente alla tua modalità di corsa per vedere come creare l'attività ed eseguire l'inferenza.

Swift

Immagine

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)
    

Video

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)
    

Live streaming

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

Immagine

@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];
    

Video

@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];
    

Live streaming

@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];
    

L'implementazione del codice di esempio del segmento di immagini consente all'utente di passare da di elaborazione. L'approccio rende il codice di creazione delle attività più complicato potrebbero non essere appropriati per il tuo caso d'uso.

Opzioni di configurazione

Questa attività include le seguenti opzioni di configurazione per le app per iOS:

Nome opzione Descrizione Intervallo di valori Valore predefinito
runningMode Imposta la modalità di esecuzione per l'attività. Esistono tre tipi di modalità:

IMAGE: la modalità per gli input di immagini singole.

VIDEO: la modalità per i fotogrammi decodificati di un video.

LIVE_STREAM: la modalità per un live streaming di input dati, ad esempio quelli di una videocamera. In questa modalità, ImageSegmenterLiveStreamDelegate deve essere impostato su un'istanza di una classe che implementa ImageSegmenterLiveStreamDelegate per ricevere la segmentazione i risultati in modo asincrono.
{RunningMode.image, RunningMode.video, RunningMode.liveStream} RunningMode.image
shouldOutputCategoryMask Se impostato su True, l'output include una maschera di segmentazione come un'immagine uint8, in cui ogni valore di pixel indica la categoria vincente valore. {True, False} False
shouldOutputConfidenceMasks Se impostato su True, l'output include una maschera di segmentazione come immagine con valore in virgola mobile, in cui ogni valore in virgola mobile rappresenta la confidenza la mappa dei punteggi della categoria. {True, False} True
displayNamesLocale Imposta la lingua delle etichette da utilizzare per i nomi visualizzati forniti nel metadati del modello dell'attività, se disponibili. Il valore predefinito è en per Inglese. Puoi aggiungere etichette localizzate ai metadati di un modello personalizzato Utilizzando l'API TensorFlow Metadata Writer Codice impostazioni internazionali it
result_callback Imposta il listener di risultati per ricevere i risultati della segmentazione in modo asincrono quando il segmento di immagini è in modalità LIVE_STREAM. Può essere utilizzato solo quando la modalità di corsa è impostata su LIVE_STREAM N/D N/D

Quando la modalità di esecuzione è impostata su LIVE_STREAM, il segmento di immagini richiede il parametro un'opzione di configurazione imageSegmenterLiveStreamDelegate aggiuntiva, consente al segmento di immagini di fornire i risultati di segmentazione delle immagini in modo asincrono. Il delegato deve implementare imageSegmenter(_:didFinishSegmentation:timestampInMilliseconds:error:) metodo, che il segmento di pubblico chiama dopo l'elaborazione dei risultati dell'esecuzione la segmentazione in ogni frame.

Nome opzione Descrizione Intervallo di valori Valore predefinito
imageSegmenterLiveStreamDelegate Consente allo strumento di segmentazione delle immagini di ricevere i risultati dell'immagine in corso la segmentazione in modo asincrono in modalità live streaming. La classe la cui istanza è impostata su questa proprietà deve implementare imageSegmenter(_:didFinishSegmentation:timestampInMilliseconds:error:) . Non applicabile Non impostato

Preparazione dei dati

Devi convertire l'immagine o il frame di input in un oggetto MPImage prima e passarlo al Segmenter di immagini. MPImage supporta diversi tipi di immagini iOS e possono utilizzarli in qualsiasi modalità di esecuzione per l'inferenza. Per ulteriori informazioni informazioni su MPImage, consulta le API MPImage

Scegli un formato dell'immagine iOS in base al tuo caso d'uso e alla modalità di corsa richiede l'applicazione.MPImage accetta UIImage, CVPixelBuffer e CMSampleBuffer formati dell'immagine per iOS.

UIImage

Il formato UIImage è adatto alle seguenti modalità di corsa:

  • Immagini: immagini da un app bundle, una galleria utente o un file system formattato come UIImage immagini possono essere convertite in un oggetto MPImage.

  • Video: utilizza AVAssetImageGenerator per estrarre i fotogrammi video CGImage , quindi convertili in UIImage immagini.

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];
    

L'esempio inizializza un MPImage con il valore predefinito UIImage.Orientation.Up orientamento. Puoi inizializzare MPImage con uno qualsiasi dei UIImage.Orientation e i relativi valori. La segmentazione delle immagini non supporta gli orientamenti speculari come .upMirrored, .downMirrored, .leftMirrored e .rightMirrored.

Per ulteriori informazioni su UIImage, fai riferimento a UIImage Apple Developer Documentazione.

CVPixelBuffer

Il formato CVPixelBuffer è adatto per le applicazioni che generano frame e utilizza la classe CoreImage per iOS per l'elaborazione dei dati.

Il formato CVPixelBuffer è adatto alle seguenti modalità di corsa:

  • Immagini: app che generano CVPixelBuffer immagini dopo un'elaborazione utilizzando il framework CoreImage di iOS possono essere inviate al modalità di esecuzione delle immagini.

  • Video: i fotogrammi possono essere convertiti nel formato CVPixelBuffer per durante l'elaborazione e poi inviate al segmento di immagini in modalità video.

  • live streaming: le app che utilizzano una fotocamera iOS per generare fotogrammi possono essere convertite nel formato CVPixelBuffer per l'elaborazione prima di essere inviati al Segmentazione di immagini in modalità live streaming.

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];
    

Per ulteriori informazioni su CVPixelBuffer, consulta CVPixelBuffer Apple Sviluppatore Documentazione.

CMSampleBuffer

Il formato CMSampleBuffer archivia campioni multimediali di un tipo di supporto uniforme e Si adatta alla modalità di corsa in live streaming. I fotogrammi in diretta delle fotocamere iOS sono pubblicato in modo asincrono nel formato CMSampleBuffer da 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];
    

Per ulteriori informazioni su CMSampleBuffer, consulta l'articolo CMSampleBuffer Apple Sviluppatore Documentazione.

Esegui l'attività

Per eseguire lo strumento di segmentazione delle immagini, utilizza il metodo segment() specifico per modalità di corsa:

  • Immagine statica: segment(image:)
  • Video: segment(videoFrame:timestampInMilliseconds:)
  • Live streaming: segmentAsync(image:timestampInMilliseconds:)

I seguenti esempi di codice mostrano semplici esempi di come eseguire la segmentazione delle immagini in diverse modalità di corsa:

Swift

Immagine

let result = try imageSegmenter.segment(image: image)
    

Video

let result = try imageSegmenter.segment(
  videoFrame: image,
  timestampInMilliseconds: timestamp)
    

Live streaming

try imageSegmenter.segmentAsync(
  image: image,
  timestampInMilliseconds: timestamp)
    

Objective-C

Immagine

MPPImageSegmenterResult *result =
  [imageSegmenter segmentImage:image error:nil];
    

Video

MPPImageSegmenterResult *result =
  [imageSegmenter segmentVideoFrame:image
            timestampInMilliseconds:timestamp
                              error:nil];
    

Live streaming

BOOL success =
  [imageSegmenter segmentAsyncImage:image
            timestampInMilliseconds:timestamp
                              error:nil];
    

L'esempio di codice del Segmenter di immagini mostra le implementazioni di ciascuna di queste modalità in modo più dettagliato segment(image:), segment(videoFrame:timestampInMilliseconds:) e segmentAsync(image:timestampInMilliseconds:).

Tieni presente quanto segue:

  • Quando utilizzi la modalità video o live streaming, devi fornire anche del frame di input all'attività Segmentazione delle immagini.

  • Quando è in modalità immagine o video, l'attività Segmentazione delle immagini blocca il thread corrente finché non termina l'elaborazione dell'immagine o del frame di input. A evitare di bloccare il thread corrente, esegui l'elaborazione in background thread utilizzando iOS Dispatch o NSOperation i modelli di machine learning.

  • Quando viene eseguita in modalità live streaming, l'attività Segmentazione delle immagini restituisce immediatamente e non blocca il thread corrente. Richiamo imageSegmenter(_:didFinishSegmentation:timestampInMilliseconds:error:) con lo strumento di segmentazione delle immagini dopo l'elaborazione di ogni frame di input. La Image Segmenter richiama questo metodo in modo asincrono su un numero seriale dedicato di tracciamento delle chiamate. Per visualizzare i risultati sull'interfaccia utente, invia il metodo i risultati alla coda principale dopo l'elaborazione dei risultati. Se La funzione segmentAsync viene chiamata quando l'attività Segmentazione delle immagini è occupata durante l'elaborazione di un altro frame, il Segmenter di immagini ignora il nuovo frame di input.

Gestire e visualizzare i risultati

Dopo l'esecuzione dell'inferenza, l'attività Segmentazione delle immagini restituisce un ImageSegmenterResult contenente i risultati dell'attività di segmentazione. I contenuti del dipende dal tipo di output impostato quando configurato l'attività.

Le seguenti immagini mostrano una visualizzazione dell'output dell'attività per una categoria come maschera del valore. L'intervallo della maschera di categoria è [0, 255] e il valore di ogni pixel rappresenta l'indice della categoria vincente dell'output del modello. La categoria vincente ha il punteggio più alto tra le categorie che il modello può riconoscere.

Output della maschera di categoria e dell'immagine originale. Immagine di origine dalla VOC Pascal 2012 del set di dati.

Il codice di esempio della funzionalità di segmentazione delle immagini mostra come visualizzare la funzionalità di ricerca, consulta il codice esempio per maggiori dettagli.