Обнаружение изображений ARKit и добавление изображений из Assets.xcassets - PullRequest
1 голос
/ 16 июня 2020

Я играюсь с кодом, который я загрузил с сайта разработчиков Apple на сайте AR Image Detection. Я пытаюсь изменить его, чтобы после обнаружения изображения отображалось конкретное изображение c в папке ресурсов AR в Resources / Assets.xcassets. Я вижу, что аналогичный вопрос был задан 2 года go, и я попробовал один-единственный ответ на него, но безуспешно. Кто-нибудь может помочь? Спасибо!

импорт ARKit импорт SceneKit импорт UIKit

класс ViewController: UIViewController, ARSCNViewDelegate {

@IBOutlet var sceneView: ARSCNView!

@IBOutlet weak var blurView: UIVisualEffectView!

/// The view controller that displays the status and "restart experience" UI.
lazy var statusViewController: StatusViewController = {
    return children.lazy.compactMap({ $0 as? StatusViewController }).first!
}()

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

    // Hook up status view controller callback(s).
    statusViewController.restartExperienceHandler = { [unowned self] in
        self.restartExperience()
    }
}

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
    session.run(configuration, options: [.resetTracking, .removeExistingAnchors])

    statusViewController.scheduleMessage("Look around to detect images", inSeconds: 7.5, messageType: .contentPlacement)
}

// MARK: - ARSCNViewDelegate (Image detection results)
/// - Tag: ARImageAnchor-Visualizing
func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
    guard let imageAnchor = anchor as? ARImageAnchor else { return }
    let referenceImage = imageAnchor.referenceImage
    updateQueue.async {

        // Create a plane to visualize the initial position of the detected image.
        let plane = SCNPlane(width: referenceImage.physicalSize.width,
                             height: referenceImage.physicalSize.height)
        let planeNode = SCNNode(geometry: plane)
        planeNode.opacity = 0.25

        /*
         `SCNPlane` is vertically oriented in its local coordinate space, but
         `ARImageAnchor` assumes the image is horizontal in its local space, so
         rotate the plane to match.
         */
        planeNode.eulerAngles.x = -.pi / 2

        /*
         Image anchors are not tracked after initial detection, so create an
         animation that limits the duration for which the plane visualization appears.
         */
        planeNode.runAction(self.imageHighlightAction)
        plane.materials = [SCNMaterial()]
        plane.materials[0].diffuse.contents = UIImage(named: "Macbook 12-inch")

        // Add the plane visualization to the scene.
        node.addChildNode(planeNode)



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


}

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),
        .fadeOut(duration: 0.5),
        .removeFromParentNode()
    ])
}

}

1 Ответ

0 голосов
/ 16 июня 2020

Если вы хотите узнать, как использовать ресурсы изображений в Xcode, используйте официальный веб-ресурс .

В вашем случае папку для эталонных изображений или объектов (хранящихся в .png или .jpg формат) должен иметь расширение .arresourcegroup. Нет необходимости помещать в эту папку изображения Hi-Res. Надежное разрешение для каждого изображения составляет 1Kx1K.


Чтобы создать свою собственную папку, содержащую эталонные изображения, просто выполните следующие действия:

  • В левой панели навигации Xcode выберите папку Assets.xcassets
  • В поле «Группа ресурсов AR» нажмите + и создайте новую папку DetectionImg
  • Поместите туда все изображения, которые необходимо обнаружить в приложении AR

Вот и все.

guard let images = ARReferenceImage.referenceImages(inGroupNamed: "DetectionImg",
                                                          bundle: nil)
else { return }

let config = ARWorldTrackingConfiguration()
config.detectionImages = images
config.maximumNumberOfTrackedImages = 3

arView.session.run(config, options: [])
...