渲染器中的变量(_:didAdd:for :)未更新

时间:2018-07-19 23:12:52

标签: ios swift arkit coreml

我正在开发同时使用CoreML和ARKit的iPhone应用程序。 CoreML应该识别一个数字,ARKit应该检测一个垂直平面(又称墙),并在同一壁上添加一些平面,其中内容取决于识别的数字显示在这些平面上。 因此,CoreML正在100%工作。每次我“更改”数字时,topPrediction变量都会自动更新(到目前为止很好)。问题是我的func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor中的变量没有更新!我的意思是,CoreML识别的第一个数字已正确发送到渲染器函数,并且它就像一个超级按钮一样工作,但是如果我将相机转到另一个数字,它仍然会假定它是第一个数字!您可能会在代码中看到,我什至尝试制作一个func getGabNum() -> Int,然后在renderer函数(var num = getGabNum())中调用它,但我继续收到警告:“变量'num'从来没有变异;请考虑更改为“让”常量”,这表示某些内容不正确。伙计们,这是我的代码!希望你能帮助我,谢谢你!

struct Room : Decodable {
let id : Int?
let num : Int?
//Adicionar Schedules
var horario = [Schedule]()
}

struct Schedule : Decodable  {
let id : Int?
let hora_ini : Date?
let hora_fim : Date?
let descr : String?

private enum CodingKeys: String, CodingKey {
    case id
    case hora_ini
    case hora_fim
    case descr
}
}

class ViewController: UIViewController, ARSCNViewDelegate {

@IBOutlet weak var debugLabel: UILabel!
@IBOutlet weak var debugTextView: UITextView!
@IBOutlet weak var sceneView: ARSCNView!

let dispatchQueueML = DispatchQueue(label: "com.hw.dispatchqueueml") // A Serial Queue
var visionRequests = [VNRequest]()

var room: Room?
var room_array: [[Int]] = [[17, 0], [43, 0], [120,0]]
var teste = 0
var num = -1

override func viewDidLoad() {
    super.viewDidLoad()
    sceneView.delegate = self
    sceneView.showsStatistics = true
    let scene = SCNScene()
    sceneView.scene = scene
    configureLighting()

    guard let selectedModel = try? VNCoreMLModel(for: SalasMLv6().model) else {
        fatalError("Could not load model.")
    }

    let classificationRequest = VNCoreMLRequest(model: selectedModel, completionHandler: classificationCompleteHandler)
    classificationRequest.imageCropAndScaleOption = VNImageCropAndScaleOption.centerCrop // Crop from centre of images and scale to appropriate size.
    visionRequests = [classificationRequest]
    loopCoreMLUpdate()
}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    setUpSceneView()
}

func setUpSceneView()
{
    let configuration = ARWorldTrackingConfiguration()
    configuration.planeDetection = .vertical
    sceneView.session.run(configuration)
    sceneView.debugOptions = [ARSCNDebugOptions.showFeaturePoints]
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    sceneView.session.pause()
}

func configureLighting()
{
    sceneView.automaticallyUpdatesLighting = true
    sceneView.autoenablesDefaultLighting = true
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}

// MARK: - ARSCNViewDelegate

func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) {
    DispatchQueue.main.async {
        // Do any desired updates to SceneKit here.
    }
}

func loopCoreMLUpdate() {
    dispatchQueueML.async {
        self.updateCoreML()
        self.loopCoreMLUpdate()
    }
}

func updateCoreML() {
    // Get Camera Image as RGB
    let pixbuff : CVPixelBuffer? = (sceneView.session.currentFrame?.capturedImage)
    if pixbuff == nil { return }
    let ciImage = CIImage(cvPixelBuffer: pixbuff!)

    // Prepare CoreML/Vision Request
    let imageRequestHandler = VNImageRequestHandler(ciImage: ciImage, options: [:])

    // Run Vision Image Request
    do {
        try imageRequestHandler.perform(self.visionRequests)
    } catch {
        print(error)
    }
}

func classificationCompleteHandler(request: VNRequest, error: Error?) {
    // Catch Errors
    if error != nil {
        print("Error: " + (error?.localizedDescription)!)
        return
    }
    guard let observations = request.results else {
        print("No results")
        return
    }

    // Get Classifications
    let classifications = observations[0...2] // top 3 results
        .compactMap({ $0 as? VNClassificationObservation })
        .map({ "\($0.identifier) \(String(format:" : %.2f", $0.confidence))" })
        .joined(separator: "\n")

    // Render Classifications
    DispatchQueue.main.async {

        // Display Debug Text on screen
        self.debugTextView.text = "TOP 3 PROBABILITIES: \n" + classifications

        // Display Top Symbol
        var symbol = "❌"
        var gabNum: Int?
        let topPrediction = classifications.components(separatedBy: "\n")[0]
        let topPredictionName = topPrediction.components(separatedBy: ":")[0].trimmingCharacters(in: .whitespaces)

        // Only display a prediction if confidence is above 90%
        let topPredictionScore:Float? = Float(topPrediction.components(separatedBy: ":")[1].trimmingCharacters(in: .whitespaces))
        if (topPredictionScore != nil && topPredictionScore! > 0.05) {
            if (topPredictionName == "120") {
                symbol = "1️⃣2️⃣0️⃣"
                gabNum = 120
                self.teste = gabNum!
                }
            if (topPredictionName == "43") {
                symbol = "4️⃣3️⃣"
                gabNum = 43
                self.teste = gabNum!
            }
            if (topPredictionName == "17") {
                symbol = "1️⃣7️⃣"
                gabNum = 17
                self.teste = gabNum!
            }
        }

        if let gn = gabNum {
            // get room from REST
            let jsonURL = "someURL\(gn)"
            guard let url = URL(string: jsonURL) else {
                return
            }
            URLSession.shared.dataTask(with: url) { (data, response, error) in
                if error != nil{
                    print("error)")
                    return
                }
                do {
                    self.room = try JSONDecoder().decode(Room.self, from: data!)
                }catch{
                    print(“Decoder Error”)
                }
                }.resume()
        }
        self.debugLabel.text = symbol
    }
}

// MARK: - HIDE STATUS BAR
   override var prefersStatusBarHidden : Bool { return true }

func getGabNum() -> Int {
    return self.teste
}

func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor)
{
    guard room != nil else  {
        print("room == nil")
        return
    }

    guard let planeAnchor = anchor as? ARPlaneAnchor else {
        return
    }

    num = getGabNum()

    if( num == room_array[0][0] && room_array[0][1] == 1 ){
        return
    }else{
        if( num == room_array[1][0] && room_array[1][1] == 1 ){
            return
        }else{
            if( num == room_array[2][0] && room_array[2][1] == 1 ){
                return
            }else{
                var i = 0
                for horario in (self.room?.horario)!{
                // Planes and Nodes Stuff Right Here
                }
                switch self.room?.num{
                case 17: room_array[0][1] = 1
                case 43: room_array[1][1] = 1
                case 120:room_array[2][1] = 1
                }
            }
        }
    }
}
}

0 个答案:

没有答案