質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

1363閲覧

visionによるQRコード認識

destiny_

総合スコア4

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2021/11/02 09:37

Visionフレームワークを使ってQRコードの認識を行ってみたのですが、QRCodeの中心座標は取得できるのですが端4点の座標を取得する方法がわかりません。
調べてみても出てこないのでvisionでは4点を追うことはできないのでしょうか?

swift

1import UIKit 2import AVFoundation 3import Vision 4 5class ViewController: UIViewController { 6 7 @IBOutlet weak var previewImageView: UIImageView! 8 9 override func viewDidLoad() { 10 super.viewDidLoad() 11 setupCamera() 12 } 13 override func viewDidAppear(_ animated: Bool) { 14 super.viewDidAppear(animated) 15 } 16 17 override func viewDidDisappear(_ animated: Bool) { 18 super.viewDidDisappear(animated) 19 self.avCaptureSession.stopRunning() 20 } 21 22 /// カメラのセットアップ 23 private func setupCamera() { 24 self.avCaptureSession.sessionPreset = .photo 25 26 let device = AVCaptureDevice.default(.builtInUltraWideCamera,for: .video, position: .back) 27 let input = try! AVCaptureDeviceInput(device: device!) 28 self.avCaptureSession.addInput(input) 29 30 let videoDataOutput = AVCaptureVideoDataOutput() 31 videoDataOutput.videoSettings = [kCVPixelBufferPixelFormatTypeKey as String : Int(kCVPixelFormatType_32BGRA)] 32 videoDataOutput.alwaysDiscardsLateVideoFrames = true 33 videoDataOutput.setSampleBufferDelegate(self, queue: .global()) 34 35 self.avCaptureSession.addOutput(videoDataOutput) 36 self.avCaptureSession.startRunning() 37 } 38 39 /// コンテキストに矩形を描画 40 private func drawRect(_ rect: CGRect, context: CGContext) { 41 context.setLineWidth(4.0) 42 context.setStrokeColor(UIColor.green.cgColor) 43 context.stroke(rect) 44 45 } 46 47 /// QR識情報の配列取得 (非同期) 48 private func getQRObservations(pixelBuffer: CVPixelBuffer, completion: @escaping (([VNBarcodeObservation])->())) { 49 let request = VNDetectBarcodesRequest { (request, error) in 50 guard let results = request.results as? [VNBarcodeObservation] else { 51 completion([]) 52 return 53 } 54 completion(results) 55 } 56 let handler = VNImageRequestHandler(cvPixelBuffer: pixelBuffer, options: [:]) 57 try? handler.perform([request]) 58 59 } 60 61 /// 正規化された矩形位置を指定領域に展開 62 private func getQRUnfoldRect(normalizedRect: CGRect, targetSize: CGSize) -> CGRect { 63 return CGRect( 64 x: normalizedRect.minX * targetSize.width, 65 y: normalizedRect.minY * targetSize.height, 66 width: normalizedRect.width * targetSize.width, 67 height: normalizedRect.height * targetSize.height 68 69 ) 70 } 71 /// QR出位置に矩形を描画した image を取得 72 private func getQRRectsImage(sampleBuffer :CMSampleBuffer, barcodeObservations: [VNBarcodeObservation]) -> UIImage? { 73 74 guard let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else { 75 return nil 76 } 77 78 CVPixelBufferLockBaseAddress(imageBuffer, CVPixelBufferLockFlags(rawValue: 0)) 79 80 guard let pixelBufferBaseAddres = CVPixelBufferGetBaseAddressOfPlane(imageBuffer, 0) else { 81 CVPixelBufferUnlockBaseAddress(imageBuffer, CVPixelBufferLockFlags(rawValue: 0)) 82 return nil 83 } 84 85 let width = CVPixelBufferGetWidth(imageBuffer) 86 let height = CVPixelBufferGetHeight(imageBuffer) 87 let bitmapInfo = CGBitmapInfo(rawValue: 88 (CGBitmapInfo.byteOrder32Little.rawValue | CGImageAlphaInfo.premultipliedFirst.rawValue) 89 ) 90 91 guard let newContext = CGContext( 92 data: pixelBufferBaseAddres, 93 width: width, 94 height: height, 95 bitsPerComponent: 8, 96 bytesPerRow: CVPixelBufferGetBytesPerRow(imageBuffer), 97 space: CGColorSpaceCreateDeviceRGB(), 98 bitmapInfo: bitmapInfo.rawValue 99 ) else 100 { 101 CVPixelBufferUnlockBaseAddress(imageBuffer, CVPixelBufferLockFlags(rawValue: 0)) 102 return nil 103 } 104 105 let imageSize = CGSize(width: width, height: height) 106 let faseRects = barcodeObservations.compactMap { 107 getQRUnfoldRect(normalizedRect: $0.boundingBox, targetSize: imageSize) 108 } 109 faseRects.forEach{ self.drawRect($0, context: newContext) } 110 111 CVPixelBufferUnlockBaseAddress(imageBuffer, CVPixelBufferLockFlags(rawValue: 0)) 112 113 guard let imageRef = newContext.makeImage() else { 114 return nil 115 } 116 let image = UIImage(cgImage: imageRef, scale: 1.0, orientation: UIImage.Orientation.right) 117 118 return image 119 } 120} 121 122extension ViewController : AVCaptureVideoDataOutputSampleBufferDelegate{ 123 /// カメラからの映像取得デリゲート 124 func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) { 125 126 guard let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else { 127 return 128 } 129 130 getQRObservations(pixelBuffer: pixelBuffer) { [weak self] barcodeObservations in 131 guard let self = self else { return } 132 let image = self.getQRRectsImage(sampleBuffer: sampleBuffer, barcodeObservations: barcodeObservations) 133 DispatchQueue.main.async { [weak self] in 134 self?.previewImageView.image = image 135 } 136 } 137 138 } 139}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

VNBarcodeObservation クラスの親クラス VNRectangleObservation には、検出したオブジェクトの四隅の座標に対応するプロパティ bottomLeft , bottomRight , topLeft , topRight があるので、それらを使うのがよさそうです。

VNBarcodeObservation | Apple Developer Documentation
VNRectangleObservation | Apple Developer Documentation

下記リンク先のコードが参考になるかもしれません。
Vision.framework を使って QR コードを読む - ユニファ開発者ブログ

投稿2021/11/02 20:51

__k_san__

総合スコア177

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

destiny_

2021/11/03 08:59

ありがとうございました。解決しました
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問