カメラ(ビデオ)で取得した画像データから、iOS11
で導入されたCoreML
とその上位レイヤーのVision
を使用して画像検出するサンプルです。
Xcode9
と、カメラを使用しますのでiOS11
をインストールした実機が必要です。
先日のWWDC2017
のセッションのこんな雰囲気のものです。ちなみにアメリカのドラマ シリコンバレーに登場したホットドック🌭 かそうでないか
を判定するアプリがギャグで流行ったため、ここでもバナナを写し not 🌭
でウケています。
元ネタはBrian
さんのこちらのYouTubeビデオです。(彼に了承済み)
短いのでソースコードをざっと載せます。(ストーリボードは未使用)
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)が必要です。
CoreMLのモデルファイルをダウンロードします。Inception v3
を選んでください。
ダウンロードしたモデルファイルをプロジェクトにコピーします。
モデルファイルを選択し、File Inspector > Target Membership
にチェックを入れます。すると、自動的にクラスファイルが生成されます。(数秒かかります)
実機を繋いで実行します。こんな感じになります。
学習モデルを変えたい場合
CoreML
に対応した出来合えの学習モデルファイルはこちらからもダウンロードできます。
MNIST、ランドマークから緯度経度を返したり、車の車種、果物、花に特化した学習モデルなどもあります。
基本的には、以下のVNCoreMLModel
の引数を書き換えるだけで動きます。
CoreML自体は推論機能だけなので、KerasやCaffeなどで学習モデルを作成し、コンバージョンツールでCoreML
の学習モデルファイルに変換する必要があります。