0

I want to detect QR codes in the vertical plane and place a node on top of the detected QR. For QR detection, I used Vision framework and Arkit to place the nodes as below code. Whenever placing the node, it is not attached to the QR code and placed somewhere else.

image

Could someone help to figure out what I have done wrong?

class ViewController: UIViewController, ARSCNViewDelegate,ARSessionDelegate{

    @IBOutlet var sceneView: ARSCNView!

    var qrRequests = [VNRequest]()
    var detectedDataAnchor: ARAnchor?
    var processing = false

    let configuration = ARWorldTrackingConfiguration()

    override func viewDidLoad() {
        super.viewDidLoad()
        self.sceneView.delegate = self
        self.sceneView.session.delegate = self
        self.sceneView.session.run(configuration)

        startQrCodeDetection()

    }

    func startQrCodeDetection() {
        let request = VNDetectBarcodesRequest(completionHandler: self.requestHandler)
        self.qrRequests = [request]
    }

    public func session(_ session: ARSession, didUpdate frame: ARFrame) {
        DispatchQueue.global(qos: .userInitiated).async {
            do {
                if self.processing {
                  return
                }
                self.processing = true
                let imageRequestHandler = VNImageRequestHandler(cvPixelBuffer: frame.capturedImage,
                                                                options: [:])
                try imageRequestHandler.perform(self.qrRequests)
            } catch {

            }
        }
    }

    func requestHandler(request: VNRequest, error: Error?) {
        if let results = request.results, let result = results.first as? VNBarcodeObservation {
            guard let payload = result.payloadStringValue else {return}
            var rect = result.boundingBox
    
            let center = CGPoint(x: rect.midX, y: rect.midY)

            DispatchQueue.main.async {
                self.hitTestQrCode(center: center)
                self.processing = false
            }
        } else {
            self.processing = false
        }
    }

    func hitTestQrCode(center: CGPoint) {
        print("Hit Test")
        if let hitTestResults = self.sceneView?.hitTest(center, types: [.featurePoint, .existingPlaneUsingExtent] ),
            let hitTestResult = hitTestResults.first {
            if let detectedDataAnchor = self.detectedDataAnchor,
                let node = self.sceneView.node(for: detectedDataAnchor) {
                node.transform = SCNMatrix4(hitTestResult.worldTransform)

            } else {
                self.detectedDataAnchor = ARAnchor(transform: hitTestResult.worldTransform)
                self.sceneView.session.add(anchor: self.detectedDataAnchor!)
            }
        }
    }

    func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode? {
        if self.detectedDataAnchor?.identifier == anchor.identifier {
            let sphere = SCNSphere(radius: 0.02)
            sphere.firstMaterial?.diffuse.contents = UIColor.red
            let sphereNode = SCNNode(geometry: sphere)
            sphereNode.transform = SCNMatrix4(anchor.transform)
            return sphereNode
        }
        return nil
    }

}
James Z
  • 12,209
  • 10
  • 24
  • 44
  • Your `center` is a super tiny number (it's a percentage in terms of your `capturedImage`'s size). You need to [convert it first](https://stackoverflow.com/a/66110582/14351818). – aheze Sep 05 '21 at 06:42
  • What does placing a node on top of a QR code mean? What you are saying does not make sense. – El Tomato Sep 05 '21 at 08:12

0 Answers0