高效率mesh转深度图python代码

  要将mesh转换为深度图,有两种思路:

  1. 遍历mesh的每一个面片,将每个面片往图像上投影,将投影覆盖到的区域深度利用面片顶点的深度进行插值计算。
  2. 获取图像上所有像素对应的光线,将这些光线与mesh进行求交运算,获取交点的坐标,进而求解交点到像素的距离,即为深度值。

  这里介绍的是第2种方法 。使用python语言,基于mesh处理包trimesh(官网)进行计算。此外,由于代码使用了pyembree进行加速,所以需要同时安装pyembree包。这两个包的安装命令:

pip install pyembree trimesh

  转换代码如下:

import numpy as np
import trimesh
from trimesh.ray.ray_pyembree import RayMeshIntersector

# 获取图像所有像素所对应的光线起点和方向
def get_rays(W, H, fx, fy, cx, cy, c2w_R, c2w_t, center_pixels):
    
	# 获取图像所有像素中心点
	j, i = np.meshgrid(np.arange(H, dtype=np.float32), np.arange(W, dtype=np.float32))
    if center_pixels:
        i = i.copy() + 0.5
        j = j.copy() + 0.5

	# 计算相机坐标系下的光线方向,(H, W, 3)
    directions = np.stack([(i - cx) / fx, (j - cy) / fy, np.ones_like(i)], -1)
    directions /= np.linalg.norm(directions, axis=-1, keepdims=True)

	# 获取光线起点,起点均为相机在世界坐标系下坐标
	rays_o = np.expand_dims(c2w_t,0).repeat(H*W, 0)
	
	# 获取光线方向
    rays_d = directions @ c2w_R.T    # (H, W, 3)
    rays_d = (rays_d / np.linalg.norm(rays_d, axis=-1, keepdims=True)).reshape(-1,3)

    return rays_o, rays_d

# mesh转深度图
# 其中R和t是相机在世界坐标系下的位姿,即c2w
def mesh2depth(meshpath, W, H, fx, fy, cx, cy, R, t, outdir):

    # 读取mesh文件
    mesh = trimesh.load(meshpath)

    # 获取光线原点、方向、对应像素的坐标
    rays_o, rays_d = get_rays(W, H, f, f, cx, cy, c2w_R, c2w_t, True)
    coords = np.array(list(np.ndindex(H,W))).reshape(H,W,-1).transpose(1,0,2).reshape(-1,2)

    # 使用trimesh包进行ray-mesh求交计算
    # 这里的RayMeshIntersector()是使用pyembree进行加速
    # 输出points是交点坐标列表,index_ray是有交点的ray的id,_是相交的面片id,我们不需要用到
    points, index_ray, _ = RayMeshIntersector(mesh).intersects_location(rays_o, rays_d, multiple_hits=False)

    # 如下是两种计算深度的方式,通常使用的是第二种,即相当于每个像素的z值;
    # 而第一种计算的是交点沿着光线到发射原点(光心)的距离
    # depth = trimesh.util.diagonal_dot(points - rays_o[0], rays_d[index_ray])    # 计算交点到相机中心的距离
    depth = (points @ w2c_R.T + w2c_t)[:,-1]    # 将交点转换到相机坐标系下,取其z值

    # 通过光线id获得其像素坐标
    pixel_ray = coords[index_ray]

    # 创建深度图矩阵,并进行对应赋值,没值的地方为nan,即空值
    depthmap = np.full([H,W], np.nan)
    depthmap[pixel_ray[:, 0], pixel_ray[:, 1]] = depth
    
    # 保存深度图,格式默认为npy
    np.save(outdir, depthmap)

  这里将深度图保存为npy格式的,是方便使用深度图进行后续的操作,只要np.load进来即是ndarray了。而如果要可视化深度图,或者想把深度图转换为jpg图片的话,可以参考python读取并可视化npy格式的深度图文件以及将其保存为jpg图片的方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zeeq_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值