unity制作点云相机

一、问题描述

通过unity相机的RGB和Depth信息生成点云。

二、符号说明

符号说明参考值
w图像宽1920px
h图像高1440px
cxx方向像素中心960px
cyy方向像素中心720px
sw传感器宽44mm
sh传感器高33mm
fl焦距50mm
n剪裁平面近处0.5m
f剪裁平面远处1m
fxx方向焦距w / sw * fl
fyy方向焦距h / sh * fl
d深度信息-
u遍历x方向的值-
v遍历y方向的值-
x坐标x(u - cx) / fx * z
y坐标y(v - cy) / fy * z
z坐标z(n * f) / (d * (f - n) + n)
r颜色r-
g颜色g-
b颜色b-

三、具体流程

从相机中获取RGB和Depth信息

1、创建一个名为Depth的camera,将phyical camera的选项勾选,设置focal length为50,sensor size x为44,sensor size y为33,clipping planes near为5,clipping planes far为10。
在这里插入图片描述
2、创建一个名为RGB的render texture,设置size为1920 * 1440。
3、创建一个名为RGB的material,设置shader为unlit/texture。
4、将名为RGB的render texture拖入名为RGB的material的base中。
5、将名为RGB的material拖入名为Depth的camera的target texture中。
6、创建一个名为Depth的render texture,设置size为1920 * 1440,color format为R16G16B16A16_SFLOAT。
请添加图片描述
7、创建一个名为Depth的C#脚本,内容为:

public Camera camera;
public RenderTexture renderTexture;
void Start()
{
    camera.depthTextureMode |= DepthTextureMode.Depth;
}
private void OnPostRender()
{
    Graphics.Blit(Shader.GetGlobalTexture("_CameraDepthTexture"), renderTexture);
}

8、将名为Depth的C#脚本拖入名为Depth的camera
9、将名为Depth的camera拖入名为Depth的C#脚本下的camera。
10、将名为Depth的render texture拖入名为Depth的C#脚本下的renderTexture。


此时相机的RGB和Depth信息被储存到名为RGB的render texture名为Depth的render texture中了。
在这里插入图片描述

通过RGB和Depth信息生成点云

1、创建一个名为CetPointClound的C#脚本,内容为:

public RenderTexture rgb;
public RenderTexture depth;
float fx = 1920 / 44 * 50;
float fy = 1440 / 33 * 50;
int w = 1920;
int h = 1440;
int cx = 960;
int cy = 720;
float n = 0.5;
float f = 1;
void Update()
{
    if (Input.GetKeyDown(KeyCode.O))
    {
        Texture2D texture2D_rgb = new Texture2D(rgb.width, rgb.height, TextureFormat.ARGB32, false);
        RenderTexture.active = rgb;
        texture2D_rgb.ReadPixels(new Rect(0, 0, rgb.width, rgb.height), 0, 0);
        texture2D_rgb.Apply();

        Texture2D texture2D_depth = new Texture2D(depth.width, depth.height, TextureFormat.RGBAFloat, false);
        RenderTexture.active = depth;
        texture2D_depth.ReadPixels(new Rect(0, 0, depth.width, depth.height), 0, 0);
        texture2D_depth.Apply();

        Color[] rgb = texture2D_rgb.GetPixels();
        Color[] depth = texture2D_depth.GetPixels();

		for(int v=0;v<w;v++)
		{
			for(int u=0;u<h;u++)
			{
				if(depth[v*h+u].r<=1/255||depth[v*h+u].r>=254/255)continue;
	            x = (u - cx) / fx
	            y = (v - cy) / fy
	            z = (n*f)/(depth[v*h+u].r*(f-n)+n)
	            x = x*z
	            y = y*z
	            r = rgb[v*h+u].r
	            g = rgb[v*h+u].g
	            b = rgb[v*h+u].b
	            //保存xyzrgb
			}
		}
    
        Debug.Log("GetPointCloud OK");
    }
}

2、将名为RGB的render texture拖入名为CetPointClound的C#脚本下的rgb。
3、将名为Depth的camera拖入名为CetPointClound的C#脚本下的depth。
请添加图片描述
4、将脚本挂到空物体上,运行项目,按O键即可得到点云信息。

四、结果展示

在这里插入图片描述

请添加图片描述

在这里插入图片描述

在这里插入图片描述


可以看到扫描出来的点云与unity中的坐标一致。

五、原理解释

关于相机成像焦距的像素表示fx、fy的解释(VSLAM14讲Chp5)
SLAM学习之路—双目相机照片生成点云(附C++代码)
基于深度学习的单目深度估计综述(数据集、单/双目视觉等)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值