ARSCNView利用
- 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 自己上去找模型
加载这个模型到场景中
- sceneView.scene = SCNScene(named: "ship.scn", inDirectory: "models.scnassets/ship") ?? SCNScene()
复制代码 2 识别图片
- 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识别
- //获取当前会话帧数据
- 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()
- }
- }
- }
- }
- }
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |