IOS 关于ARKi使用

ARSCNView使用

swift 复制代码
var sceneView: ARSCNView = ARSCNView(frame: UIScreen.main.bounds)
 let configuartion = ARWorldTrackingConfiguration()
    //会话session ARSessionDelegate 会话状态更新相关代理方法
        sceneView.session.delegate = self
        //ARSCNViewDelegate 节点场景管理相关代理方法
        sceneView.delegate = self
        
        // 自动对焦开启
        configuartion.isAutoFocusEnabled = true
        //平面检测方向
        configuartion.planeDetection = .horizontal
        //光线估计
        configuartion.isLightEstimationEnabled = true
        /*
         使用提供的配置运行会话,
         resetTracking 移动到新环境重新扫描追踪
         */
        sceneView.session.run(configuartion, options: [.resetTracking,.removeExistingAnchors])
         //调试参数
        sceneView.debugOptions = [SCNDebugOptions.showFeaturePoints]

1 加载立体模型

3d模型网站

https://sketchfab.com/3d-models/coin-d41feb2c10ed4c06ad4b8134ccaba516 自己上去找模型

加载这个模型到场景中

kotlin 复制代码
sceneView.scene = SCNScene(named: "ship.scn", inDirectory: "models.scnassets/ship") ?? SCNScene()

2 识别图片

kotlin 复制代码
     var images :[UIImage] = []
        for i in 1...19{
            let image = UIImage(named: "AR\(i)")
            images.append(image!)
        }
        configuartion.detectionImages = loadedImagesFromDirectoryContents(images)
  
  
  //其实可以直接加载图片文件的,这样图片直接转ARSet更直接一点
   func loadedImagesFromDirectoryContents(_ images: [UIImage]) -> Set<ARReferenceImage>{

        var index = 0
        var customReferenceSet = Set<ARReferenceImage>()

        images.forEach { (downloadedImage) in

            //1. Convert The UIImage To A CGImage
            guard let cgImage = downloadedImage.cgImage else { return }

            //2. Get The Width Of The Image
            let imageWidth = CGFloat(cgImage.width)

            //3. Create A Custom AR Reference Image With A Unique Name
            let customARReferenceImage = ARReferenceImage(cgImage, orientation: CGImagePropertyOrientation.up, physicalWidth: imageWidth)
            customARReferenceImage.name = "MyCustomARImage\(index)"

            //4. Insert The Reference Image Into Our Set
            customReferenceSet.insert(customARReferenceImage)

            print("ARReference Image == \(customARReferenceImage)")

            index += 1


        }


        //5. Return The Set
        return customReferenceSet

    }
    
    
    
    //在ARSCNViewDelegate方法里
    
     func renderer(_ renderer: any SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
     
        if let imageAnchor = anchor as? ARImageAnchor{
            let image = imageAnchor.referenceImage

            if let imagename = image.name, imagename.hasPrefix("AR"){
               print("识别出来图片")
            }
        }
        
        //加载3d数据识别出来立体物体,具体如下
         if let objectAnchor = anchor as? ARObjectAnchor {
              print("Detected object: \(objectAnchor.referenceObject.name ?? "Unknown")")
              
             }
     }      
        

视觉算法 Vision识别

kotlin 复制代码
//获取当前会话帧数据
    func getCurrentFrameImage(from session: ARSession) -> UIImage? {
        guard let currentFrame = session.currentFrame else {
            print("当前没有 ARFrame")
            return nil
        }
        let pixelBuffer = currentFrame.capturedImage
        let ciImage = CIImage(cvPixelBuffer: pixelBuffer)
        let context = CIContext()
        guard let cgImage = context.createCGImage(ciImage, from: ciImage.extent) else {
            return nil
        }
        return UIImage(cgImage: cgImage)
    }
    
    
     func matchImages(image1: UIImage, image2: UIImage, completion: @escaping (Bool) -> Void) {
        guard let cgImage1 = image1.cgImage, let cgImage2 = image2.cgImage else {
            completion(false)
            return
        }
        let request1 = VNGenerateImageFeaturePrintRequest()
        let request2 = VNGenerateImageFeaturePrintRequest()
        
        let request3 = VNDetectRectanglesRequest()
            request3.minimumConfidence = 0.8
            request3.minimumAspectRatio = 0.1
            request3.maximumAspectRatio = 1.0
            request3.quadratureTolerance = 10
        
        let handler1 = VNImageRequestHandler(cgImage: cgImage1, options: [:])
        let handler2 = VNImageRequestHandler(cgImage: cgImage2, options: [:])
        let handler3 = VNImageRequestHandler(cgImage: cgImage1, options: [:])

        do {
            try handler1.perform([request1])
            try handler2.perform([request2])
            try handler3.perform([request3])

            guard let featurePrint1 = request1.results?.first as? VNFeaturePrintObservation,
                  let featurePrint2 = request2.results?.first as? VNFeaturePrintObservation else {
                completion(false)
                return
            }
            
            if let observations = request3.results as? [VNRectangleObservation], !observations.isEmpty{
                // 假设目标区域是第一个匹配的矩形
                let boundingBox = observations.first?.boundingBox
                print("boundRext: \(boundingBox)")
            }

            var distance: Float = 0
            try featurePrint1.computeDistance(&distance, to: featurePrint2)
            print("匹配值 \(distance)")
            completion(distance < 0.8) // 设定相似度阈值
        } catch {
            print("匹配失败:\(error)")
            completion(false)
        }
    }
    
    //当前数据和所有图片集对比
    func handleFrame(session: ARSession,frame: ARFrame){
        let i = frame.timestamp - (self.currentFrmae?.timestamp ?? 0)
//        print("time i\(i)")
        if i < 1{
            return
        }
        self.currentFrmae = frame
        guard let frameImg = getCurrentFrameImage(from: session) else{return}
        var isMatched:Bool = false
        for img in self.images{
//            if compareImages(image1: frameImg, image2: img) == 1{
//                isMatched = true
//                break
//            }
            let im1 = frameImg
            let im2 = img
            matchImages(image1: frameImg, image2: img) { [weak self]isok in
                if isok{
                    DispatchQueue.main.async {
                        self?.showToast()
                    }
                }
            }
        }
    }
相关推荐
坏小虎2 小时前
Expo 快速创建 Android/iOS 应用开发指南
android·ios·rn·expo
光影少年3 小时前
Android和iOS原生开发的基础知识对RN开发的重要性,RN打包发布时原生端需要做哪些配置?
android·前端·react native·react.js·ios
北京自在科技4 小时前
Find My 修复定位 BUG,AirTag 安全再升级
ios·findmy·airtag
Digitally4 小时前
如何不用 USB 线将 iPhone 照片传到电脑?
ios·电脑·iphone
Sim148017 小时前
iPhone将内置本地大模型,手机端AI实现0 token成本时代来临?
人工智能·ios·智能手机·iphone
Digitally18 小时前
如何将 iPad 上的照片传输到 U 盘(4 种解决方案)
ios·ipad
报错小能手21 小时前
ios开发方向——swift并发进阶核心 @MainActor 与 DispatchQueue.main 解析
开发语言·ios·swift
LcGero21 小时前
Cocos Creator 业务与原生通信详解
android·ios·cocos creator·游戏开发·jsb
ii_best21 小时前
lua语言开发脚本基础、mql命令库开发、安卓/ios基础开发教程,按键精灵新手工具
android·ios·自动化·编辑器
用户223586218202 天前
WebKit WebPage API 的引入尝试与自研实现
ios