この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
Vision で QR コードを読み取る
今回は iOS 11 からの新フレームワーク Vision を利用して QR コードを読み取ってみようと思います。
Vision の概要に関しては以下の記事をご覧ください。
[iOS 11] 画像解析フレームワークVisionで顔認識を試した結果
実行動画
QR コードを検出すると画面中央にその内容を表示するアプリを作りました。
どういうわけかプログラムを実行しながらの動画撮影が上手くできませんでした。
画像処理で負荷がかかっているため処理落ちしているのでしょうか?
実際はスムーズに QR コードが検知できているので、その動作を見てみたい場合は以下を参考にアプリを作成してみてください。
サンプルコード
ほとんどは以前書いたコードの流用です。
変更点のみを記載します。
private var textLayer: CATextLayer! = nil
private func setupTextLayer() {
let textLayer = CATextLayer()
textLayer.contentsScale = UIScreen.main.scale
textLayer.fontSize = 20
textLayer.alignmentMode = kCAAlignmentCenter
textLayer.frame = CGRect(x: 0, y: 0, width: 300, height: 24)
textLayer.cornerRadius = 4
textLayer.backgroundColor = UIColor(white: 0.25, alpha: 0.5).cgColor
textLayer.position = self.view.center
textLayer.isHidden = true
self.previewLayer.addSublayer(textLayer)
self.textLayer = textLayer
}
QR コード検出時に画面中央に表示されるテキストレイヤーです。
viewDidLoad()
で一度だけ呼び出します。
override func viewDidLoad() {
super.viewDidLoad()
setup()
}
private func setup() {
setupVideoProcessing()
setupCameraPreview()
setupTextLayer()
}
setupVideoProcessing()
と setupCameraPreview()
は AVFoundation フレームワークでカメラを起動するための初期化処理を行っています。
内部の処理は こちら の サンプルコード(オブジェクトトラッキング) を参照してください。
func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
guard let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else {
return
}
let handler = VNSequenceRequestHandler()
let barcodesDetectionRequest = VNDetectBarcodesRequest(completionHandler: self.handleBarcodes)
try? handler.perform([barcodesDetectionRequest], on: pixelBuffer)
}
こちらは新たなビデオフレームが書き込むたびに呼び出されるデリゲートメソッドです。
バーコード検出用のハンドラとリクエスト(VNDetectBarcodesRequest)を作成し、解析処理を実行しています。
private func handleBarcodes(request: VNRequest, error: Error?) {
guard let barcode = request.results?.first as? VNBarcodeObservation else {
DispatchQueue.main.async {
self.textLayer.isHidden = true
}
return
}
if let value = barcode.payloadStringValue {
DispatchQueue.main.async {
self.textLayer.string = value
self.textLayer.isHidden = false
}
}
}
リクエスト生成時の第二引数に渡すクロージャです。
バーコードを検出した際に呼び出されます。
ここで、VNBarcodeObservation から検出した文字列 payloadStringValue
を画面中央に表示するという処理を行っています。
以上です。
やはり重要なのは Request, RequestHandler, Observation という 3 つのクラスで、これらの基本さえおさえておけば応用のプログラムを書くのは簡単ですね。
リンク
- [iOS 11] 画像解析フレームワークVisionで顔認識を試した結果
- VNDetectBarcodesRequest | Apple Developer Documentation
- VNBarcodeObservation | Apple Developer Documentation
ミレニアム・ファルコン製作日記 #88
88 号 表紙
パーツ
成果
今回の作業は以下の 2 つでした。
- ドライブ・ハウジングを組み立てる
- ドライブ・ハウジングを取り付ける
ドライブ・ハウジングの組み立てと亜光速ドライブ LED ストリップの取り付け、作動テストを行いました。
船体後方に取り付け、問題なく LED が点灯することを確認しました。
おそらくここには青色のカバーを取り付けることになると思います。
これで初めてタトゥイーンから飛び立ったときのように、このミレニアム・ファルコンも優雅にエンジン光を輝かせるでしょう。
それではまた次回。
May the Force be with you!