0 Replies
      Latest reply on Feb 5, 2020 3:06 AM by developer@Tapas@iOS
      developer@Tapas@iOS Level 1 Level 1 (0 points)

        I am working on a project to detect images in a room. But the challenge was I have to detect the same image in multiple walls.

         

        I can detect the image using these codes

         

        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
        }}

         

        From this code, I can detect the image and place a SCNNode on that detected plane. But the problem occurs when I will try to detect that same image but the background wall will different. I am getting the same image name and the same anchor name.

        Is there any option to detect the same image while the background or wall will different for that image.

         

        I am newly started app development in ARKit. So It will be very much thankful if any one can give some options/ideas to make this possible. Thanks in advance.