学习ios Metal(9)—iphone X真实感深度相机True Depth Camera的调用和metal GPGPU
metal的基础知识入门,首推Metal By Example系列:http://metalbyexample.com/。博主的相关文章,主要给出工程实际遇到的典型问题及其解决方案。
本节源码:https://github.com/sjy234sjy234/Learn-Metal/tree/master/TrueDepthStreaming。从第7节开始,渲染统一采用该节介绍的工程化渲染框架:https://blog.csdn.net/sjy234sjy234/article/details/82497799。
这一次,主要介绍两个内容:1)iphone X的真实感深度相机调用,获取实时深度帧;2)利用metal的通用计算kernel核函数将深度帧可视化为纹理。如图所示,是实时获取的彩色帧和深度帧的可视化效果。注意这个项目只能在iphone X平台上才可以运行,目前只有iphone X支持真实感深度相机。
1、iphone X的真实感深度相机调用:
参考博主封装的FrontCamera类,要获取最高的深度图像帧率,需要设置如下:
if(isDepthEnabled){[self.avCaptureSession setSessionPreset: AVCaptureSessionPreset640x480];self.videoDevice=[AVCaptureDevice defaultDeviceWithDeviceType:AVCaptureDeviceTypeBuiltInTrueDepthCamera mediaType:AVMediaTypeVideo position:AVCaptureDevicePositionFront];}
这里的preset,有一些支持深度,有一些不支持深度。但是只有AVCaptureSessionPreset640x480支持最高的帧率和最大的深度利用率。但是这个设置下,得到的彩色帧的分辨率也只有640x480,可以尝试用其他的preset。调用真实感深度相机的主要坑点是在AVCaptureDeviceTypeBuiltInTrueDepthCamera这个配置上,当时没有搜到demo,博主自己尝试出来的。其余的AVCaptureSession、AVCaptureVideoDataOutput、AVCaptureDepthDataOutput、AVCaptureDataOutputSynchronizer这些都非常常规,而且iphone双摄支持深度图像,官方有demo可以参考的。
2、metal通用计算GPGPU的kernel函数
对于从相机获取的彩色帧,直接调用VideoRenderer类进行纹理的渲染即可,里面封装了TextureRendererEncoder。而对于深度帧,是不能直接进行纹理渲染的,DepthRenderer类里面封装了DisparityToTextureEncoder和TextureRendererEncoder。首先,在DepthRenderer中,把深度帧转化为16进制的id<MTLBuffer>,作为kernel函数的输入:
id<MTLBuffer> inDisparityBuffer = [_metalContext bufferWithF16PixelBuffer: depthPixelBuffer];
然后调用DisparityToTextureEncoder类,把id<MTLBuffer>格式的深度帧转化为可视化的纹理id<MTLTexture>,这里实现了一个非常简单的GPGPU的kernel函数的封装,首先是encode函数:
- (void)encodeToCommandBuffer: (id<MTLCommandBuffer>) commandBuffer inDisparityBuffer:(const id<MTLBuffer>)inDisparityBuffer outTexture: (id<MTLTexture>) outTexture
{if(!commandBuffer){NSLog(@"invalid commandBuffer");return ;}if(!inDisparityBuffer){NSLog(@"invalid disparity buffer");return ;}if(!outTexture){NSLog(@"invalid out texture");return ;}const NSUInteger width = 8;const NSUInteger height = 8;const NSUInteger depth = 1;_threadgroupSize = MTLSizeMake((width), (height), depth);_threadgroupCount.width = (outTexture.width + _threadgroupSize.width - 1) / _threadgroupSize.width;_threadgroupCount.height = (outTexture.height + _threadgroupSize.height - 1) / _threadgroupSize.height;_threadgroupCount.depth = depth;id<MTLComputeCommandEncoder> computeEncoder = [commandBuffer computeCommandEncoder];[computeEncoder setComputePipelineState:_computePipeline];[computeEncoder setBuffer: inDisparityBuffer offset:0 atIndex:0];[computeEncoder setTexture: outTexture atIndex:0];[computeEncoder dispatchThreadgroups:_threadgroupCountthreadsPerThreadgroup:_threadgroupSize];[computeEncoder endEncoding];
}
encode函数中,首先根据纹理尺寸,配置kernel的thread group size和thread group count,然后分配computeEncoder(这里区别于渲染时分配的renderEncoder),并对其进行程序编码。然后是DisparityToTextureEncoder.metal文件中的kernel函数:
#include <metal_stdlib>
using namespace metal;// disparityToTexture compute kernel
kernel void
disparityToTexture(constant half* currentDisparityBuffer [[buffer(0)]],texture2d<float, access::write> outTexture [[texture(0)]],uint2 gid [[thread_position_in_grid]],uint2 tspg [[threads_per_grid]])
{uint invid = gid.y * tspg.x + gid.x;half inDisparity = currentDisparityBuffer[invid];half inDepth = 1.0 / inDisparity;float4 outColor = {inDepth, inDepth, inDepth, inDepth};outTexture.write(outColor, gid);
}
这里,tspg是整个kernel的size,等于输入帧的尺寸。gid是当前执行线程在kernel中的位置,用于数据的重定位。在这个kernel中,gid即纹理坐标,但是对于MTLBuffer来说,不能用纹理方式读取数据,只能用重新计算的方式定位,它们在内存中是行优先存储的,有重定位计算式 —— invid = gid.y * tspg.x + gid.x。
在调用完DisparityToTextureEncoder类得到可以渲染的可视化纹理以后,再调用TextureRendererEncoder类进行视图渲染即可。
PS:
(1)说tspg等于输入帧的尺寸是不准确的,只有输入帧的尺寸整除thread group size的时候这才是成立的,实际上tspg等于thread group size * thread group count。但在这个demo中是成立的,因为输入帧的尺寸是640x480,可以整除8。因此这个DisparityToTextureEncoder只支持分辨率尺寸能整除8的帧作为输入,否则需要修改kernel的重定位算式。
(2)iphone X获取的实时深度帧是以float16的格式存储的,并且存储的值叫做disparity,它的单位是(1/m),因此换算成深度值是:inDepth = 1.0 / inDisparity。
(3)metal的GPGPU计算,和其他语言的GPGPU是相似的,如Cuda,可以学习Cuda进行入门。Metal的学习资料比较有限,基本上只能靠查官方文档,并且官方文档也有一些过时,有时靠自己试错。
学习ios Metal(9)—iphone X真实感深度相机True Depth Camera的调用和metal GPGPU相关推荐
- 谈谈基于深度相机的三维重建
三维重建(3D Reconstruction)技术一直是计算机图形学和计算机视觉领域的一个热点课题.早期的三维重建技术通常以二维图像作为输入,重建出场景中的三维模型.但是,受限于输入的数据,重建出的三 ...
- 基于深度相机的三维重建技术
/*************************************************************************************************** ...
- 升级iOS 15后iPhone相机无法正常使用怎么办?
iOS 15发布已经有一段时间了,相信不少果粉已经将设备更新到iOS 15.升级iOS 15后,iPhone相机是否无法正常工作? 如果你遇到相机无法正常打开.在加载时显示黑屏.镜头模糊或应用闪退等问 ...
- 【深度相机系列四】深度相机分类之结构光法
说明:文中所举例的产品比较早,读者把重点放在学习原理上就好. 一.结构光法:为解决双目匹配问题而生 上一篇<[深度相机系列三]深度相机分类之双目立体视觉法>中提到基于双目立体视觉的深度相机 ...
- 大盘点!国内外深度相机汇总
作者丨凳子花❀@CSDN 来源丨https://blog.csdn.net/qq_42759162/article/details/123519276 编辑丨3D视觉工坊 读前须知 本文只是学习笔记, ...
- 【深度相机系列五】深度相机分类:TOF、RGB双目、结构光比较
说明:文中所举例的产品比较早,读者把重点放在学习原理上就好. 目前的深度相机根据其工作原理可以分为三种:TOF.RGB双目.结构光. 一.三种相机的参数对比 从分辨率.帧率.软件复杂度.功耗等方面来考 ...
- 深度相机原理和优势对比
目前的深度相机根据其工作原理可以分为三种:TOF.RGB双目.结构光 TOF简介 TOF是Time of flight的简写,直译为飞行时间的意思.所谓飞行时间法3D成像,是通过给目标连续发送光脉冲, ...
- 深度相机分类:TOF、RGB双目、结构光 对比分析
目前的深度相机根据其工作原理可以分为三种:TOF.RGB双目.结构光 一.RGB双目 RGB双目相机因为非常依赖纯图像特征匹配,所以在光照较暗或者过度曝光的情况下效果都非常差,另外如果被测场景本身缺乏 ...
- ROS进行深度相机的标定
前言 自己使用标定板对深度相机进行标定. 参考:http://wiki.ros.org/camera_calibration/Tutorials/MonocularCalibration 一.准备标定 ...
最新文章
- TODO: ping和telnet
- VC6解决托盘菜单不消失
- 【视频】详解HDFS的HA高可用原理
- std::thread 不 join
- [团队项目3.0]Scrum团队成立
- 如何使用1Password,Authy和Privacy.com外包您的在线安全性
- mathematica在linux上运行,Mathematica在Ubuntu中的表现及修正
- LeetCode 1353. 最多可以参加的会议数目(排序+贪心,优先队列,难)
- js本页导出Excel,下载
- 自学python怎么转行_没有基础的想转行学习Python怎么学
- python 3.8.0版本的skimage库是什么_python的skimage库 图像读取显示
- 【IT】Asp.Net MVC
- windows和linux通过网线连接,用网线连接Windows和Linux台式机,并实现Linux共享Windows的WiFi网络...
- Mybatis原理解析(三)--getMapper动态获取接口实现类
- python简易病毒制作
- 中秋祝福代码,中秋快乐代码,采用H5制作的中秋动画祝福
- 2017河南省第四届互联网大会圆满落幕 云计算大数据创新成热点
- 实现JSON在线美化(格式化)、JSON转CSV、CSV转XML工具-toolfk程序员工具网
- 《雍正皇帝》文化专有词泰译研究(选题缘由)
- 阿里智能运维平台的演进:从自动化到无人化(附PPT)
热门文章
- 线性方程组在计算机方面的应用,在线性方程组的简单应用》(安顺学院数学和计算机科.doc...
- 超宽带 DW1000 API --- dwt_configure (频道,脉冲重复频率,数据速率等)
- Ubuntu 配置亚马逊 aws cli 上传文件文件夹至 亚马逊 AWS S3
- 图解在EXCEL中,通过身份证自动获得出生日期和性别。
- SC-Lego-LOAM解析(下)
- 麒麟电脑linux微信版本过低,Ubuntu安装微信,解决deepin“版本过低”或NO_PUBKEY问题...
- java性能调优(转载)
- 适合打游戏用的蓝牙耳机有哪些?吃鸡无延迟的蓝牙耳机推荐
- 二级计算机vf里的sql,计算机二级考试vf常用sql语句
- 树莓派sensehat画图游戏 Etch a sketch