ios - ARkit图像识别和图像的AR可视化

标签 ios swift xcode arkit image-recognition

在我工作的公司,我需要做这个申请。我必须识别一幅画的图像,并在识别后在 AR 中将其可视化(实际上我在 AR 中找到真实的图片和绘画上方)我将文本或具有相关图片的各种特征的可选点可视化。目前,我有这段 AR 代码可以识别有问题的图像,并且我在其上方可视化了一个计划。你能帮我用上面列出的功能在图片上方创建一个 View 吗?

import ARKit
import SceneKit
import UIKit

class 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 childViewControllers.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)

            // 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()
        ])
    }
}

最佳答案

解决您的问题的一种方法是创建一个 SKScene 并将其呈现为 SCNMaterial

这是一个为您提供的完整注释示例,它使用了以下 ARSCNViewDelegate 方法:

//--------------------------
// MARK: - ARSCNViewDelegate
//--------------------------

extension ViewController: ARSCNViewDelegate {

    func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {

        //1. Check We Have An ARImageAnchor And Have Detected Our Reference Image
        guard let imageAnchor = anchor as? ARImageAnchor else { return }

        let referenceImage = imageAnchor.referenceImage

        //2. Get The Physical Width & Height Of Our Reference Image
        let width = CGFloat(referenceImage.physicalSize.width)
        let height = CGFloat(referenceImage.physicalSize.height)

        //3. Create An SKScene Which We Will Display Above Our Target
        let overlayNode = SCNNode()

        let spriteKitScene = SKScene(size: CGSize(width: 600, height: 300))
        spriteKitScene.backgroundColor = .clear

        let imageName = SKLabelNode(text: "Line Friends")
        imageName.position = CGPoint(x: 600/2, y: 240)
        imageName.horizontalAlignmentMode = .center
        imageName.fontSize = 60
        imageName.fontName = "San Fransisco"
        spriteKitScene.addChild(imageName)

        let artistName = SKLabelNode(text: "By Line Coorporation")
        artistName.position = CGPoint(x: 600/2, y: 180)
        artistName.horizontalAlignmentMode = .center
        artistName.fontSize = 60
        artistName.fontName = "San Fransisco"
        spriteKitScene.addChild(artistName)

        let creationDate = SKLabelNode(text: "Created 2011")
        creationDate.position = CGPoint(x: 600/2, y: 120)
        creationDate.horizontalAlignmentMode = .center
        creationDate.fontSize = 60
        creationDate.fontName = "San Fransisco"
        spriteKitScene.addChild(creationDate)

        let planeHeight = height/2
        let overlayGeometry = SCNPlane(width: width, height: planeHeight)
        overlayNode.geometry = overlayGeometry

        //4. Add The SpriteKit Scene As The SCNPlane's Geometry
        overlayGeometry.firstMaterial?.diffuse.contents = spriteKitScene

        //5. Rotate The Material Contents So It Isn't Backwards
        overlayGeometry.firstMaterial?.diffuse.contentsTransform = SCNMatrix4Translate(SCNMatrix4MakeScale(1, -1, 1), 0, 1, 0)

        //6. Rotate The Node
        overlayNode.transform = SCNMatrix4MakeRotation(-Float.pi / 2, 1, 0, 0)

        //7. Place It About The Target
        let zPosition = height - (planeHeight/2)
        overlayNode.position = SCNVector3(0, 0, -zPosition)

        //8. Add It To The Scene
        node.addChildNode(overlayNode)
    }

}

这会产生如下内容:

enter image description here

显然,如果您有多个图像目标,您将创建一个 func 来动态创建您的“信息”覆盖...

希望它能为您指明正确的方向...并对 corporation 令人发指的拼写表示歉意! ^________*

关于ios - ARkit图像识别和图像的AR可视化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51186463/

相关文章:

ios - 新生成的图像质量低 ios swift

ios - Swift 类中的静态数组错误

ios - ApplePay 'requiredShippingAddressFields' 在 iOS 11.0 中被弃用

ios - xcode 上的模拟器仅显示 iPhone 的一部分

ios - uiimageview切面填充问题

ios - 背景大小 : cover not working on iOS

swift - 使用 flutter 的 iPhone XS ideviceinstaller 需要 UDID 验证 - 它不再是 40 位数字并且有破折号

swift - 每天更改重复提醒的内容

ios - 如何在Swift中从输入音频文件生成反相音频文件?

objective-c - 在 uisplitviewcontroller 中关闭 NavigationController 后如何重新加载 tableView?