首页 > 其他分享 >【iOS ARKit】人形提取

【iOS ARKit】人形提取

时间:2024-02-06 19:33:40浏览次数:23  
标签:return viewModel iOS 人形 ARKit let 缓冲区 import

 

     为解决人形分离和深度估计问题,ARKit 新增加了 Segmentation Buffer(人体分隔缓冲区)和Estimated Depth Data Buffer(深度估计缓冲区)两个缓冲区。人体分隔缓冲区作用类似于图形渲染管线中的 Stencil Buffer(模板缓冲区),用于区分人形区域与背景区域,它是一个像素级的缓冲区,用于精确地描述人形区域。

    人体分隔缓冲区用于标识人形区域,所以可以使用非常简单的结构,如使用1标识该像素是人形区域,而用。标识该像素为背景区。人体分隔缓冲区每帧都更新,所以可以动态地追踪摄像头采集的人形变化。

     既然人体分隔缓冲区标识了人形区域,我们也就可以利用该缓冲区提取出场景中的人形以便后续应用,如将人形图像通过网络传输到其他AR设备中,实现类似虚拟会议的效果;或者将人形图像放入虚拟世界中,营造更绚酷的体验;或者对提取的人形图像进行模糊和打马赛克等处理,实现以往只能使用绿幕才能实现的实时人形捕捉效果。

     为简单起见,本节我们直接获取人体分隔缓冲区数据并将其保存为图像,关键代码如代码如下所示。

//
//  HumanExtraction.swift
//  ARKitDeamo
//
//  Created by zhaoquan du on 2024/2/4.
//

import SwiftUI
import ARKit
import RealityKit
import Combine
import VideoToolbox
import AVFoundation

struct HumanExtraction: View {
    
    var viewModel = HumanExtractionViewModel()
    
    var arView: ARView {
        let arView = ARView(frame: .zero)
        
        return arView
    }
    
    var body: some View {
        HumanExtractionContainer(viewModel: viewModel)
            .overlay(
            VStack{
                Spacer()
                Button(action:{viewModel.catchHuman()}) {
                    Text("截取人形")
                        .frame(width:120,height:40)
                        .font(.body)
                        .foregroundColor(.black)
                        .background(Color.white)
                        .opacity(0.6)
                }
                .offset(y:-30)
                .padding(.bottom, 30)
            }
    )
        .edgesIgnoringSafeArea(.all)
    }
}

struct HumanExtractionContainer : UIViewRepresentable{
   
    var viewModel: HumanExtractionViewModel
    
    
    func makeUIView(context: Context) -> some ARView {
        let arView = ARView(frame: .zero)
        
      
        
        return arView
    }
    
    func updateUIView(_ uiView: UIViewType, context: Context) {
        guard ARWorldTrackingConfiguration.supportsFrameSemantics(.personSegmentation) else {
            return
        }
        
        let config = ARWorldTrackingConfiguration()
        config.frameSemantics = .personSegmentation
        uiView.session.delegate = viewModel
        uiView.session.run(config)
    }
    
    
    
}

class HumanExtractionViewModel: NSObject,ARSessionDelegate {
    var arFrame: ARFrame? = nil
    func session(_ session: ARSession, didUpdate frame: ARFrame) {
        arFrame = frame
    }
    func catchHuman(){
        if let segmentationBuffer = arFrame?.segmentationBuffer {
            
            if let uiImage = UIImage(pixelBuffer: segmentationBuffer)?.rotate(radians: .pi / 2) {
                UIImageWriteToSavedPhotosAlbum(uiImage, self, #selector(imageSaveHandler(image:didFinishSavingWithError:contextInfo:)), nil)
            }
        }
    }
    @objc func imageSaveHandler(image:UIImage,didFinishSavingWithError error:NSError?,contextInfo:AnyObject) {
        if error != nil {
            print("保存图片出错")
        } else {
            print("保存图片成功")
        }
    }
    
}



extension UIImage {
    public convenience init?(pixelBuffer:CVPixelBuffer) {
        var cgimage: CGImage?
        
        VTCreateCGImageFromCVPixelBuffer(pixelBuffer, options: nil, imageOut: &cgimage)
        
        if let cgimage = cgimage{
            
            self.init(cgImage: cgimage)
            
        }else{
            return nil
        }
    }
    
    func rotate(radians: CGFloat) -> UIImage {
        let rotatedSize = CGRect(origin: .zero, size: size).applying(CGAffineTransform(rotationAngle: CGFloat(radians))).integral.size
        UIGraphicsBeginImageContext(rotatedSize)
        if let context = UIGraphicsGetCurrentContext() {
            let origin = CGPoint(x: rotatedSize.width / 2.0, y: rotatedSize.height / 2.0)
            context.translateBy(x: origin.x, y: origin.y)
            context.rotate(by: radians)
            
            draw(in: CGRect(x: -origin.y, y: -origin.x, width: size.width, height: size.height))
            
            let rotateImage = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
            
            return rotateImage ?? self
            
        }
        
        return self
    }
}

     在代码 中,人体分隔缓冲区数据每帧都会更新,所以我们需要从 ARFrame 中实时获取值,然后将缓冲区中的数据转换成图像,由于缓冲区中的数据是直接对应硬件摄像头采集的图像数据,为与屏幕显示保持一致,需要对图像进行90°旋转,保存的图像如下右图所示。

     进行人形提取时,只是提取屏幕空间中的人形图像,无须使用深度信息,因此无须使用personSegmentation WithDepth 语义,只使用 personSegmentation 语义有助于提高应用性能。

     具体代码地址:https://github.com/duzhaoquan/ARkitDemo.git

标签:return,viewModel,iOS,人形,ARKit,let,缓冲区,import
From: https://www.cnblogs.com/duzhaoquan/p/18010220

相关文章

  • 【iOS ARKit】人形遮挡
    人形遮挡简介    在AR系统中,计算机通过对设备摄像头采集的图像进行视觉处理和组织,建立起实景空间,然后将生成的虚拟对象依据几何一致性原理嵌入到实景空间中,形成虚实融合的增强现实环境,再输出到显示系统中呈现给使用者。   正确实现虚拟物体与真实环境的遮挡关系,需......
  • axios 使用
    官网https://axios-http.com/安装npminstallaxios使用格式axios.method({configs}).then(function(response){//}).catch(function(error){//handleerrorconsole.log(error);}).finally(function(){//alwaysexecuted});axios函数axi......
  • 打包 iOS 的 IPA 文件
    摘要本篇博客将为您介绍如何打包iOS的IPA文件。从APP提交、创建应用程序、设置应用程序标识和证书、配置构建设置到构建应用程序、导出IPA,以及签名和导出等方面进行详细讲解。此外,我们还将介绍一些实用的代码案例,帮助您更好地理解和操作。引言打包iOS的IPA文件是发布应用程序的......
  • axios导出Excel或word
    axios导出Excel或word1.通用方法书写importaxiosfrom'axios'import{saveAs}from'file-saver'//创建axios实例constrequest=axios.create({baseURL:'http://192.168.0.101:8081/zj_travel',//所有的请求地址前缀部分(没有后端请求不用写)timeout:80......
  • 极狐 GitLab 和 Xcode Cloud 集成,实现 iOS 的自动打包
    一直以来,iOS/macOS开发者面临一个难题:大部分云厂商只提供Linux/Windows服务器,而不提供Mac,如果想实现「持续集成自动打包」就需要绑定自己的Mac作为构建机。如果用个人Mac,一旦关机,小组同事就无法构建;如果再买一台公共Mac,又造成浪费。2022年6月,Apple在WWDC(全球开发者......
  • 【iOS ARKit】3D人体姿态估计实例
    ​   与2D人体姿态检测一样,在ARKit中,我们不必关心底层的人体骨骼关节点检测算法,也不必自己去调用这些算法,在运行使用ARBodyTrackingConfiguration配置的ARSession之后,基于摄像头图像的3D人体姿态估计任务也会启动,我们可以通过session(_session:ARSession,didUpdatea......
  • 【iOS ARKit】3D 人体姿态估计
       与基于屏幕空间的2D人体姿态估计不同,3D人体姿态估计是尝试还原人体在三维世界中的形状与姿态,包括深度信息。绝大多数的现有3D人体姿态估计方法依赖2D人体姿态估计,通过获取2D人体姿态后再构建神经网络算法,实现从2D到3D人体姿态的映射。   在ARKit中,由于是采......
  • iOS应用提交上架的最新流程
    摘要本篇博客介绍了iOS应用程序上架的最新流程。包括上架基本需求资料、证书的创建和使用、测试设备的添加、描述文件的创建、打包、审核等步骤。 引言在开发完iOS应用程序后,我们需要将其提交到AppStore上架。然而,随着技术的不断发展,上架流程也会不断更新。本文将介绍最新......
  • nodejs+axios调用第三方接口返回数据给前端
    nodejsaxios调用第三方接口返回数据给前端后端koalas前端vue0.内容和前后端框架本项目为前端执行时间段和航班,后端利用指定信息查询第三方航班信息接口并返回给前端。1.koajs+axiosapp.js文件中引入koa、添加初始化中间件并启动项目。1.1引入koa并添加初始化bodyPars......
  • 【iOS ARKit】2D肢体动作捕捉
       人体肢体动作捕捉在动漫影视制作、游戏CG动画、实时模型驱动中有着广泛的应用,利用ARKit,无须额外的硬件设备即可实现2D和3D人体一系列关节和骨骼的动态捕捉,由于移动AR的便携性及低成本,必将促进相关产业的发展。ARBodyTrackingConfiguration   ARKit配置类AR......