アニメ画像の昼/夜認識システムの作成：(2/3) そのモデルと「Vision」フレームワークを用いて新規画像からラベルを取得する。

## 本シリーズの記事一覧:

1.[「Core ML」モデルを「Create ML」で既存のラベル付けされたアニメ画像を入力として用いてトレーニングする。](https://qiita.com/MaShunzhe/items/9933eab603781154232f)
2. （本記事）そのモデルと「Vision」フレームワークを用いて新規画像からラベルを取得する。
3. それをもとに時間帯に合わせてmacOSの壁紙を変更する

## 意図：

Mac OSの壁紙として、時刻に合わせてさまざまなアニメ画像を設定するアプリの開発。

機械学習を使用して、アニメ画像に自動的に昼または夜としてのマーク付けを行う。

アニメ画像から昼夜の状態を認識する必要があるため、機械学習を取り入れます。
このアプリは、例えば日中には昼の場面のさまざまなアニメ画像を壁紙として設定します。そして夜間には、夜の場面のさまざまなアニメ画像を壁紙に設定します。

## 本記事

[前項では、トレーニング済みの`.mlmodel`ファイルを取り上げましたが](https://qiita.com/MaShunzhe/items/9933eab603781154232f)、本項では、作成されたモデルを使用して画像にラベルを付ける方法を学習します。

## Vision フレームワークについて

[Vision](https://developer.apple.com/documentation/vision) は、コンピュータビジョンアルゴリズムを応用して、入力画像や動画に対してさまざまなタスクを実行するために使用されるフレームワークです。また、テキスト、レクタングル、顔、QRコードの領域を抽出するなど、多くの優れた機能を実行することができます。

`Vision`フレームワーク内では関数 `VNCoreMLRequest `を使用します。

```swift

init(model: VNCoreMLModel, completionHandler: VNRequestCompletionHandler?)
```

ご覧のとおり、`VNCoreMLRequest `は機械学習モデルを取り込み、`VNRequestCompletionHandler `に結果を通知します。

`VNRequestCompletionHandler `の構造はこちらです:

```swift

typealias VNRequestCompletionHandler = (VNRequest, Error?) -> Void
```

`VNRequest` の構造を掘り下げると、そこにも結果が含まれていることがわかります。

https://developer.apple.com/documentation/vision/vnrequest/2867238-results

## 実装

それではコードに取り掛かりましょう！

### ステップ１．機械学習モデルの読み込み

上で学んだように、「VNCoreMLRequest」にはモデルインプット「VNCoreMLModel」が必要です。

まず、訓練済みのモデルファイル「.ml」をプロジェクトにコピーしなければなりません。確実にアプリケーションターゲットにコピーするようにしてください。そのファイルの名前を仮に「AnimeDayNight.mlmodel」としましょう。もちろん、「Apple」はすでに訓練済みのモデルを次の場所でたくさん提供しています： https://developer.apple.com/machine-learning/models/

今すぐモデルを読み込む：

```swift

// 生成済みのクラスを通してMLモデルを読み込んでください
guard let model = try? VNCoreMLModel(for: モデルファイルの名前().model) else {
    fatalError("MLモデルを読み込めません")
}

```

### Step 2. `VNCoreMLRequest` のセットアップ

`VNCoreMLRequest` は画像を送る場所ではなく、画像認識からの結果を受け取る場所ですのでご注意ください。つまり、システムに実行すべきアクションを伝えるためのものです。

```swift

let request = VNCoreMLRequest(model: model) { [weak self] request, error in
    guard let results = request.results as? [VNClassificationObservation],
          let topResult = results.first else {
              fatalError("結果がありません")
           }
    let detectedResult = topResult.identifier
    if detectedResult == "昼間"{
        //TODO
    } else if detectedResult == "夜"{
        //TODO
    }
}
```

### Step 3. 画像データの提供

[`VNImageRequestHandler`](https://developer.apple.com/documentation/vision/vnimagerequesthandler) はリクエストに対して画像データを供給し、分析を実行するために使われます。

機械学習分析には「ciImage」、「cgImage」、または「CVPixelBuffer」が必要になります。

```swift
init(cgImage: CGImage, options: [VNImageOption : Any])
```

```swift
init(ciImage: CIImage, options: [VNImageOption : Any])
```

```swift
init(cvPixelBuffer: CVPixelBuffer, options: [VNImageOption : Any])
```

機能に対して「orientation 方向性」プロパティの活用も可能であことにもご留意ください。これは画像の方向性になります。画像の方向性を渡すことは好ましいです。本記事ではこれについては詳しくは言及しません。

次のものを使うことで「UIImage」から「ciImage」を取得することができます：

```swift
let ciImage = UIImage(named: "test.png")!.ciImage
```

これでリクエストを実行できます：

```swift

let handler = VNImageRequestHandler(ciImage: image)
DispatchQueue.global(qos: .userInteractive).async {
    do {
        try handler.perform([request])
    } catch {
         print(error)
    }
}

```

分析が終われば、リクエストハンドラーがステップ2で宣言されます。

## 他の機械学習モデル

他の機械学習モデルを使用している場合は、結果処理の部分のみ変更が必要です。

Xcode内の機械学習モデルのファイルをクリックすると、モデルに入力すべきデータと、モデルから出力されてくると思われるデータの詳細が表示されます。

<img width="1575" alt="Screen Shot 2020-05-15 at 17.21.17.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635330/4dfd1f89-17d2-6c8c-5f0b-04585c3ff7a8.png">

## デモアプリケーション

### 私がトレーニングした機械学習モデルは、わずか15枚ほどの画像を学習したものです。非常に正確性が低いので、手順の紹介目的のみで使用しています。

### iOS version (画像ギャラリーから画像を選択)

**コードファイル**： https://github.com/mszopensource/SwiftVision/blob/master/iOS%20画像/iOS%20画像/ViewController.swift

**プロジェクト全体**： https://github.com/mszopensource/SwiftVision/tree/master/iOS%20画像


<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635330/27dce403-5a08-1c62-fd3b-e811856e70c5.gif" alt="Smiley face" height="600">

### macOS version (画像ギャラリーから画像を選択)

**コードファイル**： https://github.com/mszopensource/SwiftVision/blob/master/MacOS%20機械学習/MacOS%20機械学習/ViewController.swift

**プロジェクト全体**： https://github.com/mszopensource/SwiftVision/tree/master/MacOS%20機械学習

## 今後の記事について

本シリーズの次回の記事では、時刻に基づいて異なるアニメ画像を壁紙に自動的に設定するMac OSアプリの開発について紹介します。前回と今回の記事に基づいた内容となっています。

---

:relaxed: [Twitter @MszPro](https://twitter.com/MszPro)

:sunny: [私の公開されているQiita記事のリストをカテゴリー別にご覧いただけます。](http://mszpro.com/ioskiji/)
<img width="150" src="https://cdn.mszmagic.com/static-web-content/AppClipImage_small.png">