我们如何使用hitTest处理多个QR码检测并在其上添加一个节点

时间:2019-02-01 11:04:45

标签: swift qr-code arkit vision-api

我正在尝试检测屏幕中的多个QR代码,并使用ARKit在其顶部添加信息。

我使用Vision API进行多个QR码检测,并且运行完全正常,但是在一次对多个QR码进行命中测试时,HitTestResults始终为nil。如果检测到单个QR码,则可以在hittest上正常工作,并且我将其位置添加到节点上,即hittest.worldtransform,但是当我尝试对多个检测到的QR码边界框进行测试时,它始终会失败/变为nil。谁能遇到同样的问题或帮助我解决这个问题?

我使用Vision API进行多个QR码检测,并且运行完全正常,但是在一次对多个QR码进行命中测试时,HitTestResults始终为nil。如果检测到单个QR码,则可以在hittest上正常工作,并且我将其位置添加到节点上,即hittest.worldtransform,但是当我尝试对多个检测到的QR码边界框进行测试时,它始终会失败/变为nil。

func startQrCodeDetection() {

    self.names.removeAll()

    // Create a Barcode Detection Request
    let request = VNDetectBarcodesRequest(completionHandler: self.requestHandler)

    request.symbologies = [.QR]
    self.qrRequests = [request]
}

func requestHandler(request: VNRequest, error: Error?) {
    // Get the result out of the results, if there are any

    if let results = request.results, let result = results.first as? VNBarcodeObservation {


        // Get the bounding box for the bar code and find the center


        DispatchQueue.main.async {
            for each in results {
                guard let observer = each as? VNBarcodeObservation else { return }

                 let name = observer.payloadStringValue

                var rect = observer.boundingBox
                // Flip coordinates
                rect = rect.applying(CGAffineTransform(scaleX: 1, y: -1))
                rect = rect.applying(CGAffineTransform(translationX: 0, y: 1))
                // Get center
                let center = CGPoint(x: rect.midX, y: rect.midY)
                print(name!)
                self.hitTestQrCode(center: center , result: name ?? "default" )
                self.processing = false
            }

        }
    } else {
        self.processing = false
    }
}


func hitTestQrCode(center: CGPoint , result : String) {

    if let hitTestResults = self.scnView?.hitTest(center, types: [.featurePoint] ) , let camera = session.currentFrame?.camera, case .normal = camera.trackingState , let hittestResult = hitTestResults.first {

        if hittestResult.distance < 0.8 {
            // Add a new anchor to the session

            let statusForName = names.contains(where: { (name) -> Bool in
                name == result
            })
            if statusForName {
                print("Already Loaded")
            } else {


                let detectedAnchor = ARAnchor(transform: hittestResult.worldTransform)
                self.detectedDataAnchor = detectedAnchor
              self.detectedDataAnchor!.setValue(result, forKeyPath:"name")
                self.session.add(anchor: detectedAnchor)



                names.append(result)

            }

        }
    }
}



//Adding the node after the QR is detected

func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode? {
    let node = SCNNode()
    // If this is our anchor, create a node
    if self.detectedDataAnchor?.identifier == anchor.identifier {

        let name : String = self.detectedDataAnchor!.value(forKey: "name") as! String
        let plane = SCNPlane(width: 0.2, height: 0.2)
        plane.cornerRadius = plane.width / 8
        let skScene = SKScene(size: CGSize(width: 200, height: 200))
        skScene.backgroundColor = UIColor.white.withAlphaComponent(0.5)

        let rectangle = SKShapeNode(rect: CGRect(x: 0, y: 0, width: 200, height: 200), cornerRadius: 10)
        rectangle.fillColor = #colorLiteral(red: 0.807843148708344, green: 0.0274509806185961, blue: 0.333333343267441, alpha: 1.0)
        rectangle.strokeColor = #colorLiteral(red: 0.439215689897537, green: 0.0117647061124444, blue: 0.192156866192818, alpha: 1.0)
        rectangle.lineWidth = 5
        rectangle.alpha = 0.4
        let labelNode = SKLabelNode(text: name)
        labelNode.fontSize = 30
        labelNode.run(SKAction.repeat(SKAction.rotate(byAngle: .pi, duration: 1), count: 1))
        labelNode.fontName = "San Fransisco"
        labelNode.position = CGPoint(x:100,y:100)
        skScene.addChild(rectangle)
        skScene.addChild(labelNode)
        let action = SCNAction.repeatForever(SCNAction.rotate(by: .pi, around: SCNVector3(0, 1, 0), duration: 3))
        plane.firstMaterial?.isDoubleSided = true
        plane.firstMaterial?.diffuse.contents = skScene

        let planeNode = SCNNode(geometry: plane)
         planeNode.runAction(action)
        print(planeNode.position)

        planeNode.physicsBody?.isAffectedByGravity = false
        node.addChildNode(planeNode)

    }
    return node
}

我试图找到如何使用hitTest处理多个QR码并在其上添加节点

0 个答案:

没有答案