iOS 向け画像セグメンテーション ガイド

Image Segmenter タスクでは、事前定義されたリソースに基づいて画像を複数のリージョンに分割できます。 背景のぼかしなどの視覚効果を適用できます。これらの では、iOS アプリで画像セグメンタを使用する方法を説明しています。

この手順で説明するコードサンプルは、 GitHub

このタスクの動作を確認するには、 デモをご覧ください。 機能、モデル、構成オプションの詳細については、 詳細については、 概要

サンプルコード

MediaPipe Tasks のコードサンプルには、 iOS 向け画像セグメンテーション アプリ

この例では、カテゴリマスクを出力する画像セグメンタを実装しています。使用される 実際の iOS デバイスのカメラで、ライブ カメラで画像セグメンテーションを実行します。 カメラフィード、デバイスのギャラリーからの画像や動画で表示できます。

独自の iOS アプリの出発点としてアプリを使用することも、アプリ自体に言及することもできます。 変更する際の注意点があります。イメージ セグメンテーション サンプルコードは GitHub

コードをダウンロードする

次の手順では、サンプルのローカルコピーを作成する方法を示します。 git コマンドライン ツールを使用してコードを実行します。

サンプルコードをダウンロードするには:

  1. 次のコマンドを使用して Git リポジトリのクローンを作成します。

    git clone https://github.com/google-ai-edge/mediapipe-samples/
    
  2. 必要に応じて、スパース チェックアウトを使用するように Git インスタンスを構成し、 Image Segmenter サンプルアプリのファイルのみを表示します。

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

ローカル バージョンのサンプルコードを作成したら、 MediaPipe タスク ライブラリで、Xcode を使用してプロジェクトを開き、アプリを実行します。対象 手順については、iOS の設定ガイドをご覧ください。

主要コンポーネント

次のファイルには、画像セグメンタのサンプルに必要なコードが含まれています。 アプリケーション:

  • ImageSegmenterService.swift: 画像セグメンテーションを初期化し、モデル選択を処理して 入力データに対する推論です。
  • CameraViewController.swift: ライブカメラフィード入力モードの UI を実装し、 表示されます。
  • MediaLibraryViewController.swift 静止画像ファイルと動画ファイル入力モードの UI を実装します。 結果を可視化します。

セットアップ

このセクションでは、開発環境をセットアップする主な手順と 画像セグメンテーション アプリを使用できます設定に関する一般的な情報については、 MediaPipe タスクを使用するための開発環境(プラットフォーム バージョンを含む) iOS の設定ガイドをご覧ください。

依存関係

イメージ セグメンタは MediaPipeTasksVision ライブラリを使用します。このライブラリをインストールする必要があります。 構築しましたこのライブラリは Swift アプリと Objective-C アプリの両方と互換性がある 言語固有の追加の設定は不要です

macOS に CocoaPods をインストールする手順については、CocoaPods インストール ガイドをご覧ください。 必要な Pod を使用して Podfile を作成する方法については、 詳しくは、 CocoaPods

次のコードを使用して、Podfile に MediaPipeTasksVision Pod を追加します。

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

アプリに単体テスト ターゲットが含まれている場合は、 iOS をご覧ください。 あなたのPodfile

モデル

MediaPipe Image Segmenter タスクには、互換性のあるトレーニング済みモデルが必要 見ていきましょう。利用可能なトレーニング済みモデルについて詳しくは、 画像セグメンテーションについては、タスクの概要をご覧ください。モデル セクションをご覧ください

モデルを選択してダウンロードし、Xcode を使用してプロジェクト ディレクトリに追加します。 Xcode プロジェクトにファイルを追加する方法については、 Xcode 内のファイルとフォルダ プロジェクトです。

BaseOptions.modelAssetPath プロパティを使用してモデルのパスを指定する 追加できますコード例については、次のセクションをご覧ください。

タスクを作成する

Image Segmenter タスクを作成するには、そのイニシャライザのいずれかを呼び出します。「 ImageSegmenter(options:) イニシャライザが構成の値を受け入れる 。

カスタマイズした設定で初期化する画像セグメンタが不要な場合 ImageSegmenter(modelPath:) イニシャライザを使用して、 デフォルトのオプションを含む画像セグメンテーションリソースの構成について 構成の概要をご覧ください。

画像セグメンテーション タスクは、静止画像と動画ファイルの 3 つの入力データタイプをサポートします。 ストリーミング動画にも対応していますデフォルトでは、ImageSegmenter(modelPath:) は 行います。動画を処理するためにタスクを初期化する場合は、 ファイルまたはライブ動画ストリームの場合は、ImageSegmenter(options:) を使用して動画を指定します 配信モードを選択できますライブ配信モードでは、 imageSegmenterLiveStreamDelegate 構成オプションを使用すると、 画像セグメンテーションの結果を委任ユーザーに配信するための画像セグメンテーション 使用できます。

ランニングモードに対応するタブを選択すると、タスクの作成方法を確認できます 推論を実行できます

Swift

画像

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)
    

動画

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)
    

ライブ配信

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

画像

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

動画

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

ライブ配信

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

画像セグメンタのコード実装例では、 処理モードを選択できますこのアプローチでは、タスク作成コードが複雑になり、 ユースケースに適さない場合があります

構成オプション

このタスクには、iOS アプリの場合、次の構成オプションがあります。

オプション名 説明 値の範囲 デフォルト値
runningMode タスクの実行モードを設定します。3 つの モード:

IMAGE: 単一画像入力のモード。

VIDEO: 動画のデコードされたフレームのモード。

LIVE_STREAM: 入力のライブ配信のモード カメラからのデータなどです。 このモードでは、ImageSegmenterLiveStreamDelegate を実装しているクラスのインスタンスに設定する必要があります。 ImageSegmenterLiveStreamDelegate: セグメンテーションを受け取る 非同期で実行できます
{RunningMode.image, RunningMode.video, RunningMode.liveStream} RunningMode.image
shouldOutputCategoryMask True に設定すると、出力にはセグメンテーション マスクが含まれます。 uint8 イメージとして。各ピクセル値は落札カテゴリを示します。 あります。 {True, False} False
shouldOutputConfidenceMasks True に設定すると、出力にはセグメンテーション マスクが含まれます。 浮動小数点値の画像として格納され、各浮動小数点値は カテゴリのスコアマップ。 {True, False} True
displayNamesLocale 指定された表示名に使うラベルの言語を設定します。 タスクのモデルのメタデータ(利用可能な場合)。デフォルトは en です。 英語。カスタムモデルのメタデータにローカライズされたラベルを追加できます。 TensorFlow Lite Metadata Writer API を使用 言語 / 地域コード en
result_callback セグメンテーション結果を受け取るように結果リスナーを設定します。 LIVE_STREAM モードの場合、非同期で実行できます。 実行モードが LIVE_STREAM に設定されている場合にのみ使用できます なし なし

実行モードが LIVE_STREAM に設定されている場合、イメージ セグメンタは 追加の imageSegmenterLiveStreamDelegate 構成オプションを使用すると、 画像セグメンテーションの結果が非同期で提供されます。 委譲は、 imageSegmenter(_:didFinishSegmentation:timestampInMilliseconds:error:) メソッド、 これは、実行結果を処理した後で、 分割します。

オプション名 説明 値の範囲 デフォルト値
imageSegmenterLiveStreamDelegate 画像セグメンタが画像の実行結果を受け取れるようにします 非同期で作成できますインスタンスが属するクラス このプロパティは、 imageSegmenter(_:didFinishSegmentation:timestampInMilliseconds:error:) メソッドを呼び出します。 該当なし 未設定

データの準備

事前に入力画像またはフレームを MPImage オブジェクトに変換する必要があります。 それを画像セグメンタに渡しますMPImage はさまざまな種類の iOS 画像をサポートしています 形式があり、任意の実行モードで推論に使用できます。詳細 MPImage の詳細については、 MPImage API

ユースケースと実行モードに基づいて、iOS 画像形式を選択してください MPImage は、UIImageCVPixelBuffer、および CMSampleBuffer 件の iOS 画像形式。

UIImage

UIImage 形式は、次の実行モードに適しています。

  • 画像: App Bundle、ユーザー ギャラリー、ファイル システムの UIImage の画像は MPImage オブジェクトに変換できます。

  • 動画: AVAssetImageGenerator を使用 動画フレームを抽出して CGImage 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];
    

この例では、MPImage をデフォルトの UIImage.Orientation.Up 方向です。MPImage は、サポートされているいずれかの方法で初期化できます。 UIImage.Orientation 使用できます。イメージ セグメンタは、.upMirrored などの画面の向きに対応していません。 .downMirrored.leftMirrored.rightMirrored

UIImage の詳細については、UIImage Apple Developer をご覧ください。 ドキュメントをご覧ください。

CVPixelBuffer

CVPixelBuffer 形式はフレームを生成するアプリに適している iOS の CoreImage を使用してください。 処理するためのフレームワークです。

CVPixelBuffer 形式は、次の実行モードに適しています。

  • 画像: なんらかの処理後に CVPixelBuffer の画像を生成するアプリ iOS の CoreImage フレームワークを使用すると、 構成されます

  • 動画: 動画フレームは CVPixelBuffer 形式に変換できます。 動画モードの画像セグメンタに送られます

  • ライブ ストリーム: iOS カメラを使用してフレームを生成するアプリは、 送信する前に、CVPixelBuffer 形式に変換する ライブストリーム モードの画像セグメント

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

CVPixelBuffer の詳細については、CVPixelBuffer Apple をご覧ください。 デベロッパー ドキュメントをご覧ください。

CMSampleBuffer

CMSampleBuffer 形式では、統一されたメディアタイプのメディア サンプルが保存されます。 ライブ配信の実行モードに適していますiOS カメラのライブフレームは、 iOS によって CMSampleBuffer 形式で非同期に配信されます。 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];
    

CMSampleBuffer の詳細については、CMSampleBuffer Apple をご覧ください。 デベロッパー ドキュメントをご覧ください。

タスクを実行する

イメージ セグメンテーションを実行するには、割り当てられたアプリケーションに固有の segment() メソッドを使用します。 実行モード:

  • 静止画像: segment(image:)
  • 動画: segment(videoFrame:timestampInMilliseconds:)
  • ライブ配信: segmentAsync(image:timestampInMilliseconds:)

次のコードサンプルは、Google Cloud で画像セグメンテーションを実行する簡単な例を示しています。 実行モードが 3 つあります

Swift

画像

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

動画

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

ライブ配信

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

Objective-C

画像

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

動画

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

ライブ配信

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

画像セグメンタのコード例は、これらの各モードの実装を示しています。 詳細 segment(image:)segment(videoFrame:timestampInMilliseconds:) segmentAsync(image:timestampInMilliseconds:)

次の点にご留意ください。

  • 動画モードまたはライブ配信モードで実行する場合は、 Image Segmenter タスクへの入力フレームのタイムスタンプ。

  • 画像モードまたは動画モードで実行している場合、画像セグメンタ タスクは 入力画像やフレームの処理が完了するまで待機しません。宛先 現在のスレッドをブロックせずにバックグラウンドで処理を実行 使用すると、 Dispatch または NSOperation 説明します。

  • ライブ ストリーム モードで実行すると、画像セグメンタ タスクがすぐに返されます。 現在のスレッドをブロックしません。このメソッドは、 imageSegmenter(_:didFinishSegmentation:timestampInMilliseconds:error:) メソッドを呼び出します。「 Image Segmenter は、専用シリアル ネットワークで非同期的にこのメソッドを呼び出します。 ディスパッチキューに格納されます。ユーザー インターフェースに結果を表示するには、 メインキューに送られます。もし イメージ セグメンタ タスクがビジー状態のときに、segmentAsync 関数が呼び出される 新しい入力フレームを無視します。

結果の処理と表示

推論を実行すると、画像セグメンタ タスクは ImageSegmenterResult を返します。 このオブジェクトには、セグメンテーション タスクの結果が含まれます。内容 出力は、作成時に設定した出力タイプによって異なります。 構成済み できます。

次の画像は、特定のカテゴリのタスク出力を可視化したものです。 あります。カテゴリマスクの範囲は [0, 255] で、各ピクセル値 モデル出力の成功カテゴリ インデックスを表します。受賞部門 モデルが認識できるカテゴリの中で、最も高いスコアになります。

元の画像とカテゴリマスクの出力。からのソース画像 Pascal VOC(2012 年) 見てみましょう。

画像セグメントツールのコード例は、画像セグメント機能を表示する方法を示しています 詳細については、コードの 例 をご覧ください。