圖片分類器工作可讓您對圖片執行分類。您可以使用這項工作,識別圖片在訓練期間定義的一組類別中代表什麼。以下操作說明將說明如何在 iOS 應用程式中使用圖片分類器。您可在 GitHub 取得本操作說明中所述的程式碼範例。
您可以查看此網路示範,瞭解此工作的實際執行情況。如要進一步瞭解此工作的功能、模型和設定選項,請參閱「總覽」一文。
程式碼範例
MediaPipe Tasks 範例程式碼是 iOS 版 Image Classifier 應用程式的基本實作方式。這個範例使用實體 iOS 裝置上的相機持續分類物件,您也可以使用裝置圖片庫中的圖片和影片,將物件靜態分類。
您可以使用該應用程式做為 iOS 應用程式的起點,也可以在修改現有應用程式時參照這個應用程式。Image Classifier 程式碼範例在 GitHub 上。
下載程式碼
下列操作說明說明如何使用 git 指令列工具建立程式碼範例的本機副本。
如要下載範例程式碼,請按照下列步驟操作:
使用下列指令複製 git 存放區:
git clone https://github.com/google-ai-edge/mediapipe-samples
您也可以選擇設定 git 執行個體以使用稀疏結帳功能,這樣就只會使用 Image Classifier 範例應用程式的檔案:
cd mediapipe git sparse-checkout init --cone git sparse-checkout set examples/image_classification/ios/
建立範例程式碼的本機版本後,您可以安裝 MediaPipe 工作程式庫,使用 Xcode 開啟專案,並執行應用程式。如需操作說明,請參閱 iOS 設定指南。
重要元件
下列檔案包含 Image Classifier 範例應用程式的重要程式碼:
- ImageClassifierService.swift:初始化 Image Classifier、處理模型選取作業,並根據輸入資料執行推論。
- CameraViewController.swift:實作用於即時鏡頭畫面輸入模式的 UI,並以視覺化方式呈現結果。
- MediaLibraryViewController.swift 為靜態圖片和影片檔案輸入模式實作使用者介面,並以視覺化方式呈現結果。
設定
本節說明設定開發環境,以及的程式碼專案使用 Image Classifier 的重要步驟。如需使用 MediaPipe 工作設定開發環境的一般資訊 (包括平台版本要求),請參閱 iOS 設定指南。
依附元件
圖片分類器會使用 MediaPipeTasksVision
程式庫,這個程式庫必須使用 CocoaPods 進行安裝。這個程式庫與 Swift 和 Objective-C 應用程式相容,因此不需要任何其他特定語言設定。
如需在 macOS 上安裝 CocoaPods 的操作說明,請參閱 CocoaPods 安裝指南。如需為應用程式建立包含必要 Pod 的 Podfile
的操作說明,請參閱使用 CocoaPods。
使用下列程式碼在 Podfile
中新增 MediaPipeTasksVision Pod:
target 'MyImageClassifierApp' do
use_frameworks!
pod 'MediaPipeTasksVision'
end
如果您的應用程式包含單元測試目標,請參閱 iOS 設定指南,進一步瞭解如何設定 Podfile
。
模型
MediaPipe Image Classifier 工作需要與這項工作相容的已訓練模型。如要進一步瞭解圖片分類器可用的已訓練模型,請參閱工作總覽的「模型」一節。
選取並下載模型,然後透過 Xcode 將模型加入專案目錄。 如需將檔案新增至 Xcode 專案的操作說明,請參閱管理 Xcode 專案中的檔案和資料夾。
使用 BaseOptions.modelAssetPath
屬性指定應用程式套件中的模型路徑。如需程式碼範例,請參閱下一節。
建立工作
您可以呼叫其中一個初始化器來建立圖片分類器工作。ImageClassifier(options:)
初始化器會設定設定選項的值,包括執行模式、顯示名稱語言代碼、結果數量上限、可信度門檻、類別許可清單和拒絕清單。
如果不需要透過自訂設定選項初始化的圖片分類器,可以使用 ImageClassifier(modelPath:)
初始化器,透過預設選項建立圖片分類器。如要進一步瞭解設定選項,請參閱設定總覽。
圖片分類器工作支援 3 種輸入資料類型:靜態圖片、影片檔案和即時影片串流。根據預設,ImageClassifier(modelPath:)
會初始化靜態圖片的工作。如要初始化工作以處理影片檔案或直播影片串流,請使用 ImageClassifier(options:)
指定影片或即時串流執行模式。直播模式也需要額外的 imageClassifierLiveStreamDelegate
設定選項,讓圖片分類器能夠以非同步方式將圖片分類結果傳送給委派代表。
選擇執行模式對應的分頁,瞭解如何建立工作並執行推論。
Swift
圖片
import MediaPipeTasksVision let modelPath = Bundle.main.path(forResource: "model", ofType: "tflite") let options = ImageClassifierOptions() options.baseOptions.modelAssetPath = modelPath options.runningMode = .image options.maxResults = 5 let imageClassifier = try ImageClassifier(options: options)
影片
import MediaPipeTasksVision let modelPath = Bundle.main.path(forResource: "model", ofType: "tflite") let options = ImageClassifierOptions() options.baseOptions.modelAssetPath = modelPath options.runningMode = .video options.maxResults = 5 let imageClassifier = try ImageClassifier(options: options)
直播
import MediaPipeTasksVision // Class that conforms to the `ImageClassifierLiveStreamDelegate` protocol and // implements the method that the image classifier calls once it // finishes performing classification on each input frame. class ImageClassifierResultProcessor: NSObject, ImageClassifierLiveStreamDelegate { func imageClassifier( _ imageClassifier: ImageClassifier, didFinishClassification result: ImageClassifierResult?, timestampInMilliseconds: Int, error: Error?) { // Process the image classifier result or errors here. } } let modelPath = Bundle.main.path( forResource: "model", ofType: "tflite") let options = ImageClassifierOptions() options.baseOptions.modelAssetPath = modelPath options.runningMode = .liveStream options.maxResults = 5 // Assign an object of the class to the `imageClassifierLiveStreamDelegate` // property. let processor = ImageClassifierResultProcessor() options.imageClassifierLiveStreamDelegate = processor let imageClassifier = try ImageClassifier(options: options)
Objective-C
圖片
@import MediaPipeTasksVision; NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"model" ofType:@"tflite"]; MPPImageClassifierOptions *options = [[MPPImageClassifierOptions alloc] init]; options.baseOptions.modelAssetPath = modelPath; options.runningMode = MPPRunningModeImage; options.maxResults = 5; MPPImageClassifier *imageClassifier = [[MPPImageClassifier alloc] initWithOptions:options error:nil];
影片
@import MediaPipeTasksVision; NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"model" ofType:@"tflite"]; MPPImageClassifierOptions *options = [[MPPImageClassifierOptions alloc] init]; options.baseOptions.modelAssetPath = modelPath; options.runningMode = MPPRunningModeVideo; options.maxResults = 5; MPPImageClassifier *imageClassifier = [[MPPImageClassifier alloc] initWithOptions:options error:nil];
直播
@import MediaPipeTasksVision; // Class that conforms to the `MPPImageClassifierLiveStreamDelegate` protocol // and implements the method that the image classifier calls once it finishes // performing classification on each input frame. @interface APPImageClassifierResultProcessor : NSObject@end @implementation APPImageClassifierResultProcessor - (void)imageClassifier:(MPPImageClassifier *)imageClassifier didFinishClassificationWithResult:(MPPImageClassifierResult *)imageClassifierResult timestampInMilliseconds:(NSInteger)timestampInMilliseconds error:(NSError *)error { // Process the image classifier result or errors here. } @end NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"model" ofType:@"tflite"]; MPPImageClassifierOptions *options = [[MPPImageClassifierOptions alloc] init]; options.baseOptions.modelAssetPath = modelPath; options.runningMode = MPPRunningModeLiveStream; options.maxResults = 5; // Assign an object of the class to the `imageClassifierLiveStreamDelegate` // property. APPImageClassifierResultProcessor *processor = [APPImageClassifierResultProcessor new]; options.imageClassifierLiveStreamDelegate = processor; MPPImageClassifier *imageClassifier = [[MPPImageClassifier alloc] initWithOptions:options error:nil];
設定選項
這項工作有下列 iOS 應用程式設定選項:
選項名稱 | 說明 | 值範圍 | 預設值 |
---|---|---|---|
runningMode |
設定任務的執行模式。有三種模式: 圖片:單一圖片輸入模式。 影片:影片已解碼影格的模式。 LIVE_STREAM:串流輸入資料的模式,例如相機。在這個模式下,您必須呼叫 resultListener,才能設定以非同步方式接收結果的事件監聽器。 |
{RunningMode.image, RunningMode.video, RunningMode.liveStream } |
RunningMode.image |
displayNamesLocale |
設定工作模型中繼資料提供的顯示名稱 (如有) 要使用的標籤語言。預設值為 en (英文)。您可以使用 TensorFlow Lite Metadata Writer API,將本地化的標籤新增至自訂模型的中繼資料 |
語言代碼 | en |
maxResults |
設定要傳回的最高分數分類結果數量上限。如果小於 0,會傳回所有可用的結果。 | 任何正數 | -1 |
scoreThreshold |
設定預測分數門檻,以覆寫模型中繼資料 (如有) 中提供的分數值。低於這個值的結果遭到拒絕。 | 任何浮點值 | 未設定 |
categoryAllowlist |
設定允許使用的類別名稱清單 (選用)。如果非空白,則不在這個集合中的類別名稱分類結果會被篩除。系統會忽略重複或不明的類別名稱。這個選項與 categoryDenylist 互斥,且使用兩者都會導致錯誤。 |
任何字串 | 未設定 |
categoryDenylist |
設定不允許使用的類別名稱清單 (選填)。如果非空白,則會篩除這個集中的類別名稱的分類結果。系統會忽略重複或不明的類別名稱。這個選項與 categoryAllowlist 互斥,且同時使用這兩種做法會導致錯誤。 |
任何字串 | 未設定 |
resultListener |
設定結果事件監聽器,以便在圖片分類器處於直播模式時,以非同步方式接收分類結果。只有在執行模式設為「LIVE_STREAM 」時才能使用 |
不適用 | 未設定 |
直播設定
將執行模式設為即時串流時,圖片分類器需要額外的 imageClassifierLiveStreamDelegate
設定選項,讓分類器能夠以非同步方式傳送分類結果。委派會實作 imageClassifier(_:didFinishClassification:timestampInMilliseconds:error:)
方法,圖片分類器在處理每個影格的分類結果後就會呼叫此方法。
選項名稱 | 說明 | 值範圍 | 預設值 |
---|---|---|---|
imageClassifierLiveStreamDelegate |
啟用圖片分類器,在直播模式中以非同步方式接收分類結果。將例項設為此屬性的類別必須實作 imageClassifier(_:didFinishClassification:timestampInMilliseconds:error:) 方法。 |
不適用 | 未設定 |
準備資料
您必須先將輸入圖片或影格轉換為 MPImage
物件,才能將其傳遞至圖片分類器。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];
本範例使用預設的 UIImage.Orientation.Up 方向初始化 MPImage
。您可以使用任何支援的 UIImage.Orientation 值初始化 MPImage
。圖片分類器不支援鏡像方向,例如 .upMirrored
、.downMirrored
、.leftMirrored
、.rightMirrored
。
如要進一步瞭解 UIImage
,請參閱「UIImage Apple 開發人員說明文件」。
CVPixelBuffer
CVPixelBuffer
格式非常適合用於產生影格和使用 iOS CoreImage 架構處理的應用程式。
CVPixelBuffer
格式非常適合下列執行模式:
圖片:如果應用程式在使用 iOS 的
CoreImage
架構處理之後產生CVPixelBuffer
圖片,即可在圖片執行模式中傳送至圖片分類器。影片:影片影格可以轉換成
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 AVCaptureVideoDataOutput 以 CMSampleBuffer
格式傳送。
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 開發人員說明文件。
執行工作
如要執行圖片分類器,請使用已指派的執行模式專用的 classify()
方法:
- 靜態圖片:
classify(image:)
- 影片:
classify(videoFrame:timestampInMilliseconds:)
- 直播:
classifyAsync(image:timestampInMilliseconds:)
圖片分類器會在輸入圖片或頁框中傳回物件的可能類別。
以下程式碼範例顯示如何在不同的執行模式下執行圖片分類器:
Swift
圖片
let result = try imageClassifier.classify(image: image)
影片
let result = try imageClassifier.classify( videoFrame: image, timestampInMilliseconds: timestamp)
直播
try imageClassifier.classifyAsync( image: image, timestampInMilliseconds: timestamp)
Objective-C
圖片
MPPImageClassifierResult *result = [imageClassifier classifyImage:image error:nil];
影片
MPPImageClassifierResult *result = [imageClassifier classifyVideoFrame:image timestampInMilliseconds:timestamp error:nil];
直播
BOOL success = [imageClassifier classifyAsyncImage:image timestampInMilliseconds:timestamp error:nil];
圖片分類器程式碼範例會透過 classify(image:)
、classify(videoFrame:timestampInMilliseconds:)
和 classifyAsync(image:timestampInMilliseconds:)
詳細說明這些模式的實作方式。程式碼範例可讓使用者切換不同處理模式,但某些處理模式可能不適用於您的用途。
注意事項:
以影片模式或直播模式執行時,您也必須為 Image Classifier 工作提供輸入影格的時間戳記。
在圖片或影片模式中執行時,圖片分類器工作會封鎖目前的執行緒,直到處理完成輸入圖片或影格為止。為避免封鎖目前的執行緒,請使用 iOS Dispatch 或 NSOperation 架構在背景執行緒中執行處理作業。
在直播模式下執行時,圖片分類器工作會立即傳回,但不會封鎖目前的執行緒。處理每個輸入影格後,它會以分類結果叫用
imageClassifier(_:didFinishClassification:timestampInMilliseconds:error:)
方法。圖片分類器會在專屬的序列分派佇列上,以非同步方式叫用這個方法。如要在使用者介面上顯示結果,請在處理結果後將結果分派至主要佇列。如果在圖片分類器工作忙於處理其他影格時呼叫classifyAsync
函式,圖片分類器會忽略新的輸入影格。
處理及顯示結果
執行推論時,圖片分類器工作會傳回 ImageClassifierResult
物件,其中包含輸入圖片或頁框中物件的可能類別清單。
以下範例顯示這項工作的輸出資料範例:
ImageClassifierResult:
Classifications #0 (single classification head):
head index: 0
category #0:
category name: "/m/01bwb9"
display name: "Passer domesticus"
score: 0.91406
index: 671
category #1:
category name: "/m/01bwbt"
display name: "Passer montanus"
score: 0.00391
index: 670
以下裝置會執行 Bird Classifier 來取得這個結果:
圖片分類器程式碼範例示範如何顯示工作傳回的分類結果,詳情請參閱程式碼範例。