「圖片分割工具」工作可讓您根據預先定義的不同區域將圖片區分成多個區域 然後將背景模糊處理等視覺效果這些 指示將說明如何在 iOS 應用程式中使用圖片區隔工具。
如需上述指示中所述的程式碼範例,請前往 GitHub。
如要查看這項工作的實際運作情形,請前往網頁版 示範。 進一步瞭解功能、模型和設定選項 請參閱 總覽:
程式碼範例
MediaPipe 工作程式碼範例包含 iOS 版 Image Segmenter 應用程式。
這個範例會實作一個圖片分段器,輸出類別遮罩。使用 使用實體 iOS 裝置的相機,在即時影像上分割影像 攝影機畫面或裝置圖片庫中的圖片和影片。
你可以將這個應用程式做為起點,開始使用 iOS 應用程式,也可以參照這個應用程式 做出決定Image Segmenter 範例程式碼 GitHub。
下載程式碼
以下說明如何建立範例的本機副本 git 指令列工具編寫程式碼。
如要下載範例程式碼,請按照下列步驟操作:
使用下列指令複製 git 存放區:
git clone https://github.com/google-ai-edge/mediapipe-samples/
您也可以設定 Git 執行個體來使用稀疏結帳功能, 只有 Image Segmenter 範例應用程式的檔案:
cd mediapipe git sparse-checkout init --cone git sparse-checkout set examples/image_segmentation/ios/
建立範例程式碼的本機版本後,您可以安裝 MediaPipe 工作程式庫,使用 Xcode 開啟專案,然後執行應用程式。適用對象 操作說明,請參閱 iOS 設定指南。
重要元件
下列檔案包含 Image Segmenter 範例的重要程式碼 應用程式:
- ImageSegmenterService.swift: 初始化圖片區隔器、處理模型選取作業,然後執行 所做出的推論
- CameraViewController.swift: 實作用於即時攝影機畫面輸入模式的 UI,並以視覺化方式呈現 也就是預測結果
- MediaLibraryViewController.swift 實作靜態圖片和影片檔案輸入模式的 UI。 以視覺方式呈現結果
設定
本節說明設定開發環境的重要步驟,以及 程式碼專案使用 Image Segmenter。如需設定 使用 MediaPipe 工作 (包括平台版本) 的開發環境 規定,請參閱 iOS 設定指南。
依附元件
Image Segmenter 使用 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
設定選項,以便啟用
Image Segmenter 將圖片區隔結果傳送給委派代表
以非同步方式載入物件
選擇與執行中模式對應的分頁,瞭解如何建立工作 然後執行推論
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];
導入 Image Segmenter 程式碼範例後,使用者可在 處理模式這種方法使得工作建立程式碼變得更加複雜, 可能會不適合您的用途
設定選項
這項工作有下列 iOS 應用程式設定選項:
選項名稱 | 說明 | 值範圍 | 預設值 |
---|---|---|---|
runningMode |
設定任務的執行模式。在架構中
模式: 圖片:單一圖片輸入模式。 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
設定選項
讓 Image Segmenter 以非同步方式提供圖片區隔結果。
委派項目必須執行
imageSegmenter(_:didFinishSegmentation:timestampInMilliseconds:error:)
方法,
圖片區隔工具在處理完執行結果後
每個影格的區隔
選項名稱 | 說明 | 值範圍 | 預設值 |
---|---|---|---|
imageSegmenterLiveStreamDelegate |
啟用圖片區隔工具以取得執行圖片的結果
以非同步的方式在直播模式下進行其例項所屬的類別
必須導入
imageSegmenter(_:didFinishSegmentation:timestampInMilliseconds:error:)
方法。 |
不適用 | 未設定 |
準備資料
您必須先將輸入圖片或影格轉換為 MPImage
物件。
並傳到 Image Segmenter (圖片區隔工具) 中MPImage
支援不同類型的 iOS 圖片
並且可在任何執行模式中使用,以便進行推論。如要
關於「MPImage
」的資訊,請參閱
MPImage API
根據您的用途和執行模式,選擇 iOS 圖片格式
應用程式需要。MPImage
接受 UIImage
、CVPixelBuffer
和
CMSampleBuffer
iOS 圖片格式。
UIImage
UIImage
格式非常適合下列執行模式:
圖片:應用程式套件、使用者圖片庫或檔案系統的圖片,格式為
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 開發人員
說明文件:
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:)
以下程式碼範例顯示如何在 不同的跑步模式
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 工作輸入框的時間戳記。
在圖片或影片模式中執行時,圖片區隔工具工作會封鎖 直到完成處理輸入圖片或影格為止。目的地: 為避免封鎖目前的執行緒,請在背景執行處理作業 使用 iOS 的執行緒 調度或 NSOperation 架構。
以直播模式執行時,Image Segmenter 工作會立即傳回 但不會封鎖目前的執行緒該函式會叫用
imageSegmenter(_:didFinishSegmentation:timestampInMilliseconds:error:)
方法與圖片分段器處理每個輸入影格 Image Segmenter 可在專屬序列以非同步方式叫用這個方法 調度佇列。為了在使用者介面顯示結果,請調度 結果傳送到主要佇列。如果 圖片區隔工具工作忙碌時,系統會呼叫segmentAsync
函式 處理另一個影格時,Image Segmenter 會忽略新的輸入框。
處理及顯示結果
在執行推論時,Image Segmenter 工作會傳回 ImageSegmenterResult
物件,其中包含區隔工作的結果。當內容
輸出內容取決於您在
已設定
執行工作
下圖顯示特定類別的工作輸出圖表
值遮罩。類別遮罩範圍是 [0, 255]
,每個像素值
代表模型輸出的獲勝類別索引。優勝獎項
索引是模型能辨識的類別分數最高。
原始圖片和類別遮罩輸出內容。來源映像檔 2012 年 Pascal VOC 資料集。
「圖片區隔」程式碼範例示範如何顯示圖片區隔 結果,請參閱程式碼 示例 。