iOS 圖片分類指南

圖片分類器工作可讓您對圖片執行分類。別擔心!您可以使用 這項工作能找出圖片在一組定義的類別中代表什麼內容 以訓練資料為準以下操作說明會示範如何在 iOS 應用程式。如需上述指示中所述的程式碼範例,請前往 GitHub

如要查看這項工作的實際運作情形,請參閱這個網頁 示範。適用對象 進一步瞭解 請參閱 總覽

程式碼範例

MediaPipe Tasks 範例程式碼是圖片分類器的基本實作 App Engine 應用程式這個範例使用實體 iOS 裝置的相機 持續分類物件,也能使用 可將物件靜態分類

你可以將這個應用程式做為起點,開始使用 iOS 應用程式,也可以參照這個應用程式 做出決定Image Classifier 範例程式碼 GitHub

下載程式碼

以下說明如何建立範例的本機副本 git 指令列工具編寫程式碼。

如要下載範例程式碼,請按照下列步驟操作:

  1. 使用下列指令複製 git 存放區:

    git clone https://github.com/google-ai-edge/mediapipe-samples
    
  2. 您也可以設定 Git 執行個體來使用稀疏結帳功能, 只有 Image Classifier 範例應用程式的檔案:

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

建立範例程式碼的本機版本後,您可以安裝 MediaPipe 工作程式庫,使用 Xcode 開啟專案,然後執行應用程式。適用對象 操作說明,請參閱 iOS 設定指南

重要元件

下列檔案包含 Image Classifier 範例的重要程式碼 應用程式:

設定

本節說明設定開發環境的重要步驟,以及 程式碼專案使用 Image Classifier。如需設定 使用 MediaPipe 工作 (包括平台版本) 的開發環境 規定,請參閱 iOS 設定指南

依附元件

圖片分類器會使用必須安裝的 MediaPipeTasksVision 程式庫 開發應用程式這個程式庫同時與 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 設定任務的執行模式。在架構中 模式:

圖片:單一圖片輸入模式。

VIDEO:影片已解碼的影格模式。

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 設定用來接收分類結果的結果監聽器 當 Image Classifier 出現在直播時,並以非同步的方式顯示 模式。只有在執行模式設為「LIVE_STREAM」時才能使用 不適用 未設定

直播設定

將跑步模式設為即時串流時,圖片分類器會要求 額外的 imageClassifierLiveStreamDelegate 設定選項 讓分類器以非同步方式提供分類結果。 則會導入 imageClassifier(_:didFinishClassification:timestampInMilliseconds:error:) 方法,圖片分類器在處理分類後會呼叫這個方法 顯示每個影格的結果

選項名稱 說明 值範圍 預設值
imageClassifierLiveStreamDelegate 啟用圖片分類器,以非同步方式接收分類結果 。類別的執行個體必須設為此屬性 實作 imageClassifier(_:didFinishClassification:timestampInMilliseconds:error:) 方法。 不適用 未設定

準備資料

您必須先將輸入圖片或影格轉換為 MPImage 物件。 並傳送給 Image ClassifierMPImage 支援不同類型的 iOS 圖片 並且可在任何執行模式中使用,以便進行推論。如要 關於「MPImage」的資訊,請參閱 MPImage API

根據您的用途和執行模式,選擇 iOS 圖片格式 應用程式需要。MPImage 接受 UIImageCVPixelBufferCMSampleBuffer 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 顯像組件 說明文件

執行工作

如要執行圖片分類器,請使用已指派的 classify() 方法 執行模式:

  • 靜態圖片:classify(image:)
  • 影片:classify(videoFrame:timestampInMilliseconds:)
  • 直播:classifyAsync(image:timestampInMilliseconds:)

Image Classifier 會為 輸入圖片或影格

以下程式碼範例顯示如何在 不同的跑步模式

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 的執行緒 調度NSOperation 架構。

  • 在直播模式下執行時,圖片分類器工作會立即傳回 但不會封鎖目前的執行緒該函式會叫用 imageClassifier(_:didFinishClassification:timestampInMilliseconds:error:) 方法,產生分類結果。 Image Classifier 會在專屬序列以非同步方式叫用這個方法 調度佇列。為了在使用者介面顯示結果,請調度 結果傳送到主要佇列。如果 圖片分類器工作忙碌時,系統會呼叫 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 取得 已開啟:

圖片分類器程式碼範例示範如何顯示分類 查看工作傳回的結果,請參閱 示例