見出し画像

iOS による画像分類

以下の記事を参考にして書いてます。

Classifying Images with Vision and Core ML

1. はじめに

Core ML は、訓練済みの機械学習モデルを使用して入力データを分類できます。Visionフレームワーク は Core ML と連携して分類モデルを画像に適用し、それらの画像を前処理して機械学習タスクをより簡単で信頼性の高いものにします。

このサンプルは、いくつかの利用可能な分類モデルの1つである MobileNet を使用して、以下のスクリーンショットにあるように、1000種類の画像分類を行います。

画像1

2. サンプルの概要

このサンプルの動作確認を行うには、プロジェクトをビルドして実行し、サンプルのツールバーのボタンを使用して写真を撮るか、フォトライブラリから画像を選択します。 次にVisionを使用してCore MLモデルを画像に適用して、結果となる「分類ラベル」と「信頼度」を表示します。上位2つの分類ラベルが信頼度順に表示されます。

3. Core MLモデルとVisionの設定

Core ML は、MLモデルへの簡単なアクセスを提供するSwiftクラスを自動生成します。このサンプルでは、Core ML は MobileNet から MobileNetクラス を自動生成します。モデルを使用して Visionリクエスト を設定するには、そのクラスのインスタンスを作成し、そのモデルプロパティを使用して VNCoreMLRequest を作成します。リクエストオブジェクトの完了ハンドラを使用して、リクエスト実行後にモデルから結果を受け取るメソッドを指定します。

let model = try VNCoreMLModel(for: MobileNet().model)

let request = VNCoreMLRequest(model: model, completionHandler: { [weak self] request, error in
    self?.processClassifications(for: request, error: error)
})
request.imageCropAndScaleOption = .centerCrop
return request

MLモデルは固定アスペクト比で入力画像を処理しますが、入力画像は任意のアスペクト比を持つ可能性があるため、Visionは画像を拡大縮小およびトリミングでフィットさせる必要があります。最良の結果を得るには、リクエストの imageCropAndScaleOptionプロパティ を、モデルの訓練に使用された画像レイアウトと一致するように設定します。使用可能な分類モデルについては、特に明記されていない限り、 NImageCropAndScaleOption.centerCrop が適切です。

4. Visionリクエストの実行

処理する画像を使用して VNImageRequestHandler を作成し、リクエストをそのオブジェクトの perform(_:) に渡します。このメソッドは同期的に実行されます。リクエストの実行中にメインキューがブロックされないように、バックグラウンドキューを使用します。

DispatchQueue.global(qos: .userInitiated).async {
    let handler = VNImageRequestHandler(ciImage: ciImage, orientation: orientation)
    do {
        try handler.perform([self.classificationRequest])
    } catch {
        print("Failed to perform classification.\n\(error.localizedDescription)")
    }
}

ほとんどのモデルは、表示用にすでに正しい向きになっている画像で訓練されます。任意の向きの入力画像を適切に処理するには、画像の向きを画像リクエストハンドラに渡します。(このサンプルは、UIImage.Orientationの向きの値から変換するため、init(_:) にCGImagePropertyOrientationを指定します。)

5. 画像分類結果の処理

Visionリクエストの完了ハンドラは、リクエストが成功とエラーのどちらかを示します。成功した場合、その resultsプロパティ には、MLモデルによって識別された可能な分類を説明する VNClassificationObservation が含まれます。

func processClassifications(for request: VNRequest, error: Error?) {
    DispatchQueue.main.async {
        guard let results = request.results else {
            self.classificationLabel.text = "Unable to classify image.\n\(error!.localizedDescription)"
            return
        }
        // 結果は常に VNClassificationObservation になる
        let classifications = results as! [VNClassificationObservation]


この記事が気に入ったらサポートをしてみませんか?