Unity 深度图片获取

1、  在Unity中,要得到深度缓存(Depthbuffer),就需要用到一个RenderTexture纹理。

2、  深度缓存,或者深度纹理,其实就是一个包含有场景里物体离照相机的距离值的一张纹理图。

3、  为了让摄像机生成一张深度纹理,只需要设置Camera.depthTextureMode即可。但这个时候生成了纹理,还需要我们去获取。所以我们需要把它传到一个shader中,于是就用到OnRenderImage这个函数。

 

于是我们得出下面一个例子:

using UnityEngine;
using System.Collections;

//so that we can see changes we make without having to run the game

[ExecuteInEditMode]
public class PostProcessDepthGrayscale : MonoBehaviour {

   public Material mat;

   void Start () {
//设置Camera的depthTextureMode,使得摄像机能生成深度图。
      Camera.main.depthTextureMode = DepthTextureMode.Depth;
   }

   void OnRenderImage (RenderTexture source, RenderTexture destination){
      Graphics.Blit(source,destination,mat);
      //mat就是包含shader的一个材质球,而这个shader就是我们要把
             //destination这个render纹理传进去的shader。Shader的写法如下所示。
   }
}


 

接下来这个shader代码如下:

Shader "Custom/DepthGrayscale" {
SubShader {
Tags { "RenderType"="Opaque" }

Pass{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"

sampler2D _CameraDepthTexture;

struct v2f {
   float4 pos : SV_POSITION;
   float4 scrPos:TEXCOORD1;
};

//Vertex Shader
v2f vert (appdata_base v){
   v2f o;
   o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
   o.scrPos=ComputeScreenPos(o.pos);
   //for some reason, the y position of the depthtexture comes out inverted
   //o.scrPos.y = 1 - o.scrPos.y;
   return o;
}

//Fragment Shader
half4 frag (v2f i) : COLOR{
   float depthValue =Linear01Depth (tex2Dproj(_CameraDepthTexture,UNITY_PROJ_COORD(i.scrPos)).r);
   half4 depth;

   depth.r = depthValue;
   depth.g = depthValue;
   depth.b = depthValue;

   depth.a = 1;
   return depth;
}
ENDCG
}
}
FallBack "Diffuse"
}


 

前面都好理解,而且需要注意的是,_CameraDepthTexture这个变量的值是Unityshader内部传进去的。

float depthValue =Linear01Depth (tex2Dproj(_CameraDepthTexture,UNITY_PROJ_COORD(i.scrPos)).r);

Linear01Depth这个是将其中的值转换成深度的01之间的值,tex2Dproj采样得到的颜色值为何只取r值,而且取gb值是全黑的。这需要再考虑一下。(对于这个问题,现测得RenderTexture如果它的Format改成Depth的话,就只有红色这一个通道颜色了。所以会出现上面的这个情况。)

而且,这里的深度是受RenderQueue的值的影响,并不只z轴坐标。比如你的RenderQueue=3000,但是z轴坐标离摄像机很近,那它的深度值也是很大的。得到一幅深度图如下图:


可见,离摄像机越近,深度越小,颜色值越深。

### 如何在 Unity 中接入和应用深度学习模型及框架 #### 接入 TensorFlowSharp 插件 为了能够在 Unity 中使用深度学习技术,可以采用 TensorFlowSharp 插件。此插件允许开发者直接在 Unity 编辑器内以及构建的应用程序中运行 TensorFlow 模型[^3]。 对于 Mac 用户以及其他平台用户来说,安装过程相对简单: 1. **下载 TFSharpPlugin** 需要从指定链接获取适用于 Unity 的 `TFSharpPlugin.unitypackage` 文件,并将其导入至项目中。这个包不仅包含了 TensorFlowSharp 库还集成了 ML-Agents 工具套件,从而简化了开发流程并提高了兼容性和性能。 2. **配置 C# 项目** 对于非 Unity 的纯 C# 项目而言,在 Visual Studio 2019 或更高版本里通过 NuGet 包管理器来添加 TensorFlowSharp 是一种常见做法;然而当涉及到 Unity 时,则应优先考虑官方提供的 `.unitypackage` 方式来进行集成。 ```csharp // 导入库之后可以在脚本里面像下面这样加载已训练好的模型: using Tensorflow; using System; public class ModelLoader { private readonly string modelPath = "Assets/Resources/my_model.pb"; public void LoadModel() { var graph = new Graph(); using (var file = File.OpenRead(modelPath)) { graph.Import(file.ReadAllBytes()); } Console.WriteLine("Model loaded successfully."); } } ``` #### 使用预训练模型进行推理 一旦成功集成了上述组件,就可以利用预先训练过的神经网络模型来进行预测或分类任务。例如,假设有一个图像识别的任务,那么可以通过以下方式实现数据输入与输出处理逻辑: ```csharp // 假设我们已经有了一个名为 'session' 的 Session 实例用于执行计算图操作 byte[] imageData; // 图片二进制流 float[,] inputTensorData = PreprocessImage(imageData); // 将图片转换成适合喂给模型的形式 // 准备好输入张量和其他参数... var runner = session.GetRunner(); runner.AddInput(graph["input_node_name"][0], inputTensorData); runner.Fetch("output_node_name"); // 执行会话得到结果... var output = runner.Run(); // 解析输出... foreach(var item in output){ ProcessOutput(item); } void ProcessOutput(TFOutput result) { /* ... */ } float[,] PreprocessImage(byte[] img){ /* ... */} ``` 以上代码片段展示了如何准备输入数据、定义计算路径并通过 TensorFlowSharp API 来获得最终的结果。值得注意的是实际应用场景可能更加复杂,因此建议深入研究文档资料以适应具体需求。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值