CreateML+Visionミニマムサンプル

はじめに

Create MLとVisionを使った画像認識がたくさんありますが大抵カメラでキャプチャして画像処理を行っています。

カメラの処理が入っていると実際に画像処理をどこでやっているのかわかりにくかったので1枚の画像に対して認識を行ってみました。

Create MLでモデルの作成

Modelはカロリーメイトそれ以外の2種類を追加して作成を行いました。判定したい対象以外のものを入れておくと認識精度が上がるみたいです。

Playgroundで以下のようにコードを記述し実行します。

import CreateMLUI

let builder = MLImageClassifierBuilder()
builder.showInLiveView()

⚠️注意点

  • イメージフォルダをドロップする画面は2画面表示で表示されます
  • platformが治らない時はプロジェクトを作り直した方が良いです
  • フォルダの一つ階層下に学習用の画像を入れたイメージフォルダを任意の数作成します。

この階層になっているimagesフォルダをドラックアンドドロップします。

コード

VNImageRequestHandlerメソッドを実行すると.performで指定したリクエストに処理が飛びます。

requestの中に登録した学習モデルの分だけ値が入っているのでそこからデータを引っ張ります。類似度が高い物から順番に配列に格納されているようです。

import UIKit
import Vision

class ViewController: UIViewController {
    //画面に表示している画像
    let img: CGImage = (UIImage(named: "sample")!.cgImage)!
    
    @IBOutlet weak var label: UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // CreateMLで作ったモデルの初期化
        guard let model = try? VNCoreMLModel(for: ImageClassifier().model) else {
            print("モデルの初期化に失敗しました")
            return
        }
        // 画像認識リクエストを作成(引数はモデルとハンドラ)
        let request = VNCoreMLRequest(model: model) { [weak self] (request: VNRequest, error: Error?) in
            guard let results = request.results as? [VNClassificationObservation] else { return }
            print(results.description)

            let name = results.first!.identifier
            let parcentage = Int(results.first!.confidence * 100)
            self?.label.text = name + " " + String(parcentage) + "%"
        }
        
        // 画像認識リクエストを指定して実行!
        try? VNImageRequestHandler(cgImage: img, options: [:]).perform([request])
    }
}

スクリーンショット

こんな感じに表示されます。学習用にCalorieMateの画像を使ったんですが99%でした。

参考文献

Create MLとVisionで画像認識

画像クラスの違い(UIImage vs CGImage vs CIImage)