[iOS 11] Vision.Frameworkで画像の識別を試してみました #WWDC2017

2017.08.08

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

1 はじめに

iOS 11で追加された Vision.Framework では、CoreMLを利用した画像解析を、一貫性のあるインターフェイスで簡単にアプリに組み込むことが出来ます。

Vision.Frameworkには、顔追跡・検出・ランドマーク、テキスト検出、矩形検出、バーコード検出、オブジェクト追跡など各種の機能が提供されていますが、今回は、画像の識別について試してみました。

画像の識別では、CoreML用に機械学習のモデル(CoreML用に作成された.mlmodelファイル)が必要ですが、こちらは、Appleの開発者ページでダウンロードに可能なっている下記の5種類を使用させて頂きました。

  • SqueezeNet
  • Places205-GoogLeNet
  • ResNet50
  • Inception v3
  • VGG16

001
https://developer.apple.com/machine-learning/より

本記事は Apple からベータ版として公開されているドキュメントを情報源としています。 そのため、正式版と異なる情報になる可能性があります。ご留意の上、お読みください。

2 登場するオブジェクト

Vision.Frameworkを利用した画像処理では、大きく3つのオブジェクトが登場します。

  • Requests
  • RequestHandler
  • Observations


002
WWDC 2017 Session 506 Vision Framework Building on Core MLより

Requestsオブジェクトは、画像処理タスクをシステムに要求するためのオブジェクトで、解析の種類(画像識別、矩形認識、顔認識など)によって違ったものになります。

RequestHandlerは、実際のイメージを用意して、上記のリクエストをハンドルします。これは、全ての処理で共通です。

最後に、Observationsですが、こちらは、Requestの保持しているクロージャーに渡され解析結果を処理します。解析の種類によって違ってくるので、Requestとセットになっています。(例えば、顔認識では、顔認識用のObservationとなる)

3 画像解析処理

先出の3つのオブジェクトを使用して、画像の識別を行うコードは以下のとおりです。

画像の識別ということで、リクエストオブジェクトは、VNCoreMLRequestを使用し、その解析結果の処理用のオブザーバーは、VNClassificationObservationとなっています。

func coreMLRequest(image:UIImage) {
    // モデルの作成        
    guard let model = try? VNCoreMLModel(for: Inceptionv3().model) else {
        fatalError("Error create VMCoreMLModel")
    }

    // リクエスト(VNCoreMLRequest)の生成とハンドラ処理
    let request = VNCoreMLRequest(model: model) { request, error in
        // オブザーバ(VNClassificationObservation)による解釈
        guard let results = request.results as? [VNClassificationObservation] else {
            fatalError("Error results")
        }
        if let classification = results.first {
            print("identifier = \(classification.identifier)")
            print("confidence = \(classification.confidence)")
        } else {
            print("error")
        }
    }

    // CIImageへの変換
    guard let ciImage = CIImage(image: image) else {
        fatalError("Error convert CIImage")
    }

    // ハンドラの生成と実行
    let handler = VNImageRequestHandler(ciImage: ciImage, options: [:])
    guard (try? handler.perform([request])) != nil else {
        fatalError("Error handler.perform")
    }
}

Modelを生成する際のVNCoreMLModelの第1引数には、使用するモデルを指定しますが、ここを変更することで、各種のモデルに置き換える事ができます。

//Inception v3 を GoogLeNetPlaces.mlmodel に変更する
//let model = try? VNCoreMLModel(for: Inceptionv3().model)
let model = try? VNCoreMLModel(for: GoogLeNetPlaces().model)

4 やってみた

実際にやってみたところ、下記のような結果を得ることが出来ました。

sizeは、モデル(.mlmodel)のサイズ(MByte)であり、timeは、解析にかかった時間です。モデルごとに少し差があったようなので、秒単位で雑に計測してみました。

下記の結果ですが、処理時間などは、もちろん実機の性能に大きく依存するでしょうし、確かめたサンプル数も非常に限られたものですので、あくまで「解析の一例」程度の意味しか無いことを予めご了承下さい。

003

size identifier confidence time
SqueezeNet 4.7 snowmobile 0.508154 2.0
Places205-GoogLeNet 24.8 river 0.2156 4.0
Inception v3 94.7 lakeside, lakeshore 0.854758 4.0
ResNet50 102.6 lakeside, lakeshore 0.373168 4.0
VGG16 553.5 lakeside, lakeshore 0.38961 4.0

004

size identifier confidence time
SqueezeNet 4.7 eggnog 0.970777 3.0
Places205-GoogLeNet 24.8 supermarket 0.172011 3.0
Inception v3 94.7 bakery, bakeshop, bakehouse 0.10947 3.0
ResNet50 102.6 grocery store, grocery, food market, market 0.181952 4.0
VGG16 553.5 packet 0.117755 4.0

005

size identifier confidence time
SqueezeNet 4.7 studio couch, day bed 0.242885 3.0
Places205-GoogLeNet 24.8 boat_deck 0.644138 3.0
Inception v3 94.7 wing 0.239884 3.0
ResNet50 102.6 missile 0.541719 3.0
VGG16 553.5 missile 0.385286 3.0

006

size identifier confidence time
SqueezeNet 4.7 gasmask, respirator, gas helmet 0.326393 2.0
Places205-GoogLeNet 24.8 aquarium 0.319852 3.0
Inception v3 94.7 pop bottle, soda bottle, 0.512668 3.0
ResNet50 102.6 projectile, missile 0.108452 3.0
VGG16 553.5 pop bottle, soda bottle 0.179419 4.0

007

size identifier confidence time
SqueezeNet 4.7 nipple 0.806034 2.0
Places205-GoogLeNet 24.8 clothing_store 0.136114 3.0
Inception v3 94.7 Appenzeller 0.27724 3.0
ResNet50 102.6 kelpie 0.343134 4.0
VGG16 553.5 kelpie 0.178468 4.0

008

size identifier confidence time
SqueezeNet 4.7 handkerchief, hankie, hanky, hankey 0.914462 2.0
Places205-GoogLeNet 24.8 herb_garden 0.290646 3.0
Inception v3 94.7 sulphur butterfly, sulfur butterfly 0.289349 3.0
ResNet50 102.6 pot, flowerpot 0.443367 3.0
VGG16 553.5 pot, flowerpot 0.107249 4.0

009

size identifier confidence time
SqueezeNet 4.7 window screen 0.390035 2.0
Places205-GoogLeNet 24.8 shower 0.195312 3.0
Inception v3 94.7 fountain 0.398686 3.0
ResNet50 102.6 fountain 0.368908 4.0
VGG16 553.5 fountain 0.129674 3.0

5 最後に

ちなみに、「やってみた」のところで写真に写っていた犬は、「黒柴」なのですが、解析結果に出ていた Appenzeller とか kelpieは、google画像検索で見ると、次のような感じでした。 雰囲気、黒柴!?

010 011

コードは、下記に起きました。モデルは含まれておりませんので、別途ダウンロードが必要です。
github [GitHub] https://github.com/furuya02/CoreMLSample

↓こちらで、Vision.Frameworkを使用しない場合との比較も行っております。興味があれば是非!
[iOS 11] CoreMLで画像の識別を試してみました(Vision.Frameworkを使わないパターン) #WWDC2017

6 参考リンク


WWDC 2017 Vision Framework: Building on Core ML
Apple Document > Vision Framework
Build more intelligent apps with machine learning.