Как обнаружить одни и те же изображения в комнате на нескольких стенах, используя ARKit Image Detection - PullRequest
0 голосов
/ 05 февраля 2020

Я работаю над проектом по обнаружению изображений в комнате. Но проблема заключалась в том, что я должен был обнаружить одно и то же изображение в нескольких стенах.

Я могу определить изображение с помощью этих кодов

class DetectImageVC: UIViewController, ARSCNViewDelegate, ARSessionDelegate {

@IBOutlet var sceneView: ARSCNView!
@IBOutlet weak var blurView: UIVisualEffectView!

let fadeDuration: TimeInterval = 0.3
let rotateDuration: TimeInterval = 3
let waitDuration: TimeInterval = 7200.0

var imageHighlightAction: SCNAction {
    return .sequence([
        .wait(duration: 0.25),
        .fadeOpacity(to: 0.85, duration: 0.25),
        .fadeOpacity(to: 0.15, duration: 0.25),
        .fadeOpacity(to: 0.85, duration: 0.25),
        .wait(duration: waitDuration),
        .fadeOut(duration: 0.5),
        .removeFromParentNode()
    ])
}

/// A serial queue for thread safety when modifying the SceneKit node graph.
let updateQueue = DispatchQueue(label: Bundle.main.bundleIdentifier! +
    ".serialSceneKitQueue")

/// Convenience accessor for the session owned by ARSCNView.
var session: ARSession {
    return sceneView.session
}

// MARK: - View Controller Life Cycle

override func viewDidLoad() {
    super.viewDidLoad()


    sceneView.delegate = self
    sceneView.session.delegate = self

    sceneView.showsStatistics = true
    sceneView.debugOptions = [ .showFeaturePoints ]
}

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    // Prevent the screen from being dimmed to avoid interuppting the AR experience.
    UIApplication.shared.isIdleTimerDisabled = true

    // Start the AR experience
    resetTracking()
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)

    session.pause()
}

// MARK: - Session management (Image detection setup)

/// Prevents restarting the session while a restart is in progress.
var isRestartAvailable = true

/// Creates a new AR configuration to run on the `session`.
/// - Tag: ARReferenceImage-Loading
func resetTracking() {

    guard let referenceImages = ARReferenceImage.referenceImages(inGroupNamed: "AR Resources", bundle: nil) else {
        fatalError("Missing expected asset catalog resources.")
    }

    let configuration = ARWorldTrackingConfiguration()
    configuration.detectionImages = referenceImages
    if #available(iOS 12.0, *) {
        configuration.maximumNumberOfTrackedImages = 1
    } else {
        // Fallback on earlier versions
    }


    session.run(configuration, options: [.resetTracking, .removeExistingAnchors])

}

// MARK: - ARSCNViewDelegate (Image detection results)
/// - Tag: ARImageAnchor-Visualizing
func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {

    print("Anchor name is: \(anchor.name ?? "NoAnchorName")")

    guard let imageAnchor = anchor as? ARImageAnchor else { return }
    let referenceImage = imageAnchor.referenceImage
    updateQueue.async {

        // TODO: Comment out code
        let planeNode = self.getPlaneNode(withReferenceImage: referenceImage, withImageName: referenceImage.name ?? "")
        planeNode.opacity = 0.15
        planeNode.eulerAngles.x = -.pi / 2
        planeNode.runAction(self.imageHighlightAction)
        node.addChildNode(planeNode)
    }

    DispatchQueue.main.async {
        let imageName = referenceImage.name ?? ""
        print("Detected image “\(imageName)”")
    }
}


func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {
    let trackedNode = node
    if let imageAnchor = anchor as? ARImageAnchor{

    if (imageAnchor.isTracked) {
        trackedNode.isHidden = false
    }else {
        trackedNode.isHidden = true
        print("No image in view")

        }
    }
}


func getPlaneNode(withReferenceImage image: ARReferenceImage, withImageName imageName: String) -> SCNNode {
    let plane = SCNPlane(width: image.physicalSize.width,
                         height: image.physicalSize.height)
    let node = SCNNode(geometry: plane)

    let overlayNode = self.getNode(withImageName: imageName)
    node.addChildNode(overlayNode)

    return node
}

func getNode(withImageName name: String) -> SCNNode {
    var node = SCNNode()
    switch name {
    case "Road":
        print("We will load the Road SCNNode for this image")
    case "NoticeBoard":
        print("We will load the Noticeboard SCNNode for this image")
    case "PhotoFrame":
        print("We will load the Photoframe SCNNode for this image")
    default:
        break
    }

    return node
}}

Из этого кода я могу обнаружить изображение и разместить SCNNode на этой обнаруженной плоскости. Но проблема возникает, когда я попытаюсь обнаружить то же изображение, но фон стены будет другим. Я получаю одно и то же имя изображения и одно и то же имя привязки.

Есть ли возможность обнаружить одно и то же изображение, в то время как фон или стена будут отличаться для этого изображения.

Я недавно начал разработку приложений в ARKit. Поэтому я буду очень благодарен, если кто-нибудь сможет дать некоторые варианты / идеи, чтобы сделать это возможным. Заранее спасибо.

...