iOS
機械学習
画像認識
Swift
coreML

iOS11 カメラとCoreML(Vision)で画像検出

More than 1 year has passed since last update.

カメラ(ビデオ)で取得した画像データから、iOS11で導入されたCoreMLとその上位レイヤーのVisionを使用して画像検出するサンプルです。
Xcode9と、カメラを使用しますのでiOS11をインストールした実機が必要です。
先日のWWDC2017のセッションのこんな雰囲気のものです。ちなみにアメリカのドラマ シリコンバレーに登場したホットドック🌭 かそうでないかを判定するアプリがギャグで流行ったため、ここでもバナナを写し not 🌭 でウケています。

元ネタはBrianさんのこちらのYouTubeビデオです。(彼に了承済み)

短いのでソースコードをざっと載せます。(ストーリボードは未使用)

ViewController.swift
import UIKit
import AVKit
import Vision

class ViewController: UIViewController, AVCaptureVideoDataOutputSampleBufferDelegate {
    override func viewDidLoad() {
        super.viewDidLoad()

        let captureSession = AVCaptureSession()
        captureSession.sessionPreset = .photo

        guard let captureDevice = AVCaptureDevice.default(for: .video) else { return }
        guard let input = try? AVCaptureDeviceInput(device: captureDevice) else { return }

        captureSession.addInput(input)
        captureSession.startRunning()

        let previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
        view.layer.addSublayer(previewLayer)
        previewLayer.frame = view.frame

        let dataOutput = AVCaptureVideoDataOutput()
        dataOutput.setSampleBufferDelegate(self, queue: DispatchQueue(label: "videoQueue"))
        captureSession.addOutput(dataOutput)
    }

    func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
        guard let pixelBuffer: CVPixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else { return }

        guard let model = try? VNCoreMLModel(for: Inceptionv3().model) else { return }

        let request = VNCoreMLRequest(model: model) { (finishedReq, err) in
            guard let results = finishedReq.results as? [VNClassificationObservation] else { return }
            guard let firstObservation = results.first else { return }
            print(firstObservation.identifier, firstObservation.confidence)
        }

        try? VNImageRequestHandler(cvPixelBuffer: pixelBuffer, options: [:]).perform([request])
    }
}

その他に、CoreMLの学習モデルファイル(Inceptionv3.mlmodel)とカメラの使用許可設定(Info.plist)が必要です。

HelloSwift4_xcodeproj.png

CoreMLのモデルファイルをダウンロードします。Inception v3を選んでください。
12Machine_Learning_-_Apple_Developer.png

ダウンロードしたモデルファイルをプロジェクトにコピーします。
モデルファイルを選択し、File Inspector > Target Membership にチェックを入れます。すると、自動的にクラスファイルが生成されます。(数秒かかります)
Inceptionv3.png

実機を繋いで実行します。こんな感じになります。

学習モデルを変えたい場合

CoreMLに対応した出来合えの学習モデルファイルはこちらからもダウンロードできます。
MNIST、ランドマークから緯度経度を返したり、車の車種、果物、花に特化した学習モデルなどもあります。
基本的には、以下のVNCoreMLModelの引数を書き換えるだけで動きます。
89ViewController_swift.png

CoreML自体は推論機能だけなので、KerasやCaffeなどで学習モデルを作成し、コンバージョンツールCoreMLの学習モデルファイルに変換する必要があります。