『OPEN3D』1.7 Ray Casting

news2025/1/18 20:09:26

       

1 ray casting

        ray casting(光线衍射) 和 ray tracing(光线追踪)都属于计算机图形学内的基础方法;用于对三维的实体建模和图片渲染;ray casting一词来自于General Motors Research Labs from 1978–1980;出自论文《Ray Casting for Modeling Solids》。ray casting 极大的简化了3D物体或场景到图片的渲染。详情可以查看该wiki。

        这里简单介绍以下ray casting;在假设光线不会二次或多次反射的情况下,从相机的focal point为中心点每个像素根据设定的FOV计算得到每个像素上对应的光线方向,并从该方向射出所有光线,如若光线与场景中的物体相交,则记录下来,并选取距离与相机最短的物体作为该光线的结果映射会图像上。简而言之:给定一个场景和相机的位姿,可以使用ray casting得到该位姿下拍摄得到的图像信息

        

以下为几个网上ray casting示意图

在open3d中实现了RaycastingScene类用于基础的ray casting功能;下面介绍以下如何在open3d中创建一个简单的场景并使用ray casing来进行光线与物体的相交测试;同时可以使用该类为mesh;cad模型等创建虚拟的点云信息。


import open3d as o3d
import numpy as np
import matplotlib.pyplot as plt

if __name__ == "__main__":
    # Create meshes and convert to open3d.t.geometry.TriangleMesh .

    # 创建普通的geometry类型在cpu上
    # 创建立方体
    cube_ = o3d.geometry.TriangleMesh.create_box().translate([0, 0, 0])
    # 创建环面
    torus_ = o3d.geometry.TriangleMesh.create_torus().translate([0, 0, 2])
    # 创建球体
    sphere_ = o3d.geometry.TriangleMesh.create_sphere(radius=0.5).translate(
        [1, 2, 3])


    o3d.visualization.draw_geometries([cube_, torus_, sphere_],
                                      lookat=[0, 0, 2],  # 相机查看的方向
                                      front=[2, 3, 0],  # 相机的位置
                                      up=[0, 1, 0],
                                      zoom=1.0,
                                      )




    # 将cpu上的geometry类型转换成tensorgeometry的类型,可以运算在显卡等设备上加速处理
    # 由于ray casting操作运算量大,所以open3d没有基于cpu对该类进行实现,
    # 但是open3d做了对集成显卡的支持
    cube = o3d.t.geometry.TriangleMesh.from_legacy(cube_)
    sphere = o3d.t.geometry.TriangleMesh.from_legacy(sphere_)
    torus = o3d.t.geometry.TriangleMesh.from_legacy(torus_)

    # 初始化RaycastingScene类
    # param : nthreads用于指定使用多少个线程用于创建场景,0代表自动选择
    scene = o3d.t.geometry.RaycastingScene(nthreads=0)
    # 添加上述创建的物体到场景中,返回值为该geometry在RaycastingScene中的ID
    _ = scene.add_triangles(cube)
    _ = scene.add_triangles(torus)
    _ = scene.add_triangles(sphere)




    """
    生成的光线示例
    # We create two rays:
    # The first ray starts at (0.5,0.5,10) and has direction (0,0,-1).
    # The second ray start at (-1,-1,-1) and has direction (0,0,-1).
    rays = o3d.core.Tensor([[0.5, 0.5, 10, 0, 0, -1], [-1, -1, -1, 0, 0, -1]],
                           dtype=o3d.core.Dtype.Float32)
    
    """
    

    # 根据相机的参数设置光线的射出方向
    # 返回值是一个大小为(height_px,width_px,6)的张量为
    #  [ox, oy, oz, dx, dy, dz] 中心坐标时[ox,oy,oz] 方向为 [dx,dy,dz]
    rays = o3d.t.geometry.RaycastingScene.create_rays_pinhole(
        fov_deg=90,  # 相机的水平fov角度
        center=[0, 0, 2],  # 相机的位置
        eye=[2, 3, 0],  # 相机查看的方向
        up=[0, 1, 0],
        width_px=640,  # 图像的宽度
        height_px=480,  # 图像的高度
    )





    # We can directly pass the rays tensor to the cast_rays function.
    # 计算光线与场景中的物体第一次相交
    # 输入的rays的维度大于等于2,shape为{..,6},
    # 方向向量不必进行归一化操作,但是返回的最近的物体与相机的距离结果为方向单位向量的长度
    ans = scene.cast_rays(rays=rays, nthreads=0)
    """
    print(ans) 结果为
    dict_keys(['primitive_uvs', 'primitive_ids', 'geometry_ids', 'primitive_normals', 't_hit'])
    
    t_hit is the distance to the intersection. The unit is defined by the length of the ray direction. If there is no intersection this is inf
    t_hit 是光线与物体相交点距离相机的距离,单位是光线方向的单位向量,如果该光线没有与物体相交,则该值为inf
    
    geometry_ids gives the id of the geometry hit by the ray. If no geometry was hit this is RaycastingScene.INVALID_ID
    geometry_ids 给出了该光线与哪个ID的物体相交,如果该光线没有与物体相交,则该值为RaycastingScene.INVALID_ID
    
    primitive_ids is the triangle index of the triangle that was hit or RaycastingScene.INVALID_ID
    primitive_ids 返回了光线与triangle mesh的哪个mesh相交,返回了该mesh在triangle mesh中的索引,
    如果该光线没有与物体相交,则该值为RaycastingScene.INVALID_ID
    
    primitive_uvs is the barycentric coordinates of the intersection point within the triangle.
    primitive_uvs 是三角形内交点的重心坐标 shape:{.., 2}
    
    primitive_normals is the normal of the hit triangle.
    primitive_normals 相交triangle mesh的法线信息 shape: {.., 3}
    """
    # 使用matplotlib画出所有光线距离相机的图像,颜色越深代表距离越远
    plt.imshow(ans['t_hit'].numpy())
    plt.show()
    # 使用matplotlib画出所有光线对应mesh的法线信息
    plt.imshow(np.abs(ans['primitive_normals'].numpy()))
    plt.show()
    # 使用matplotlib画出所有光线对应的物体id,不同的物体颜色不同,相同的物体颜色相同
    plt.imshow(np.abs(ans['geometry_ids'].numpy()), vmax=3)
    plt.show()

注:其中相机视角的参数可以查阅opengl的相关内容,这里给一个tutorial的链接LearnOpenGL - Camera

                                                                相机与物体的深度图

物体表面的法线信息

 

每个像素代表一条光线,光线与某个物体相交则统一显示为同一个颜色

 

 

2 使用ray casting创建虚拟点云

        结合上面的内容,可以根据光线与物体相交得到的深度信息来创建物体的点云信息,在虚拟的环境中可以使用根据虚拟的相机位姿信息通过raycasting来获取当前位姿下相机看到物体的深度图。

# 判断该点是否与物体相交
    hit = ans['t_hit'].isfinite()
    # 取出所有与物体相交的rays,并根据结果t_hit来获取每个相交光线与物体的深度距离,加在原光线点中
    points = rays[hit][:,:3]
    points_distance = rays[hit][:,3:]*ans['t_hit'][hit].reshape((-1,1))
    points+=points_distance
    pcd = o3d.t.geometry.PointCloud(points)
    # Press Ctrl/Cmd-C in the visualization window to copy the current viewpoint
    o3d.visualization.draw_geometries([pcd.to_legacy()],
                                      front=[0.5, 0.86, 0.125],
                                      lookat=[0.23, 0.5, 2],
                                      up=[-0.63, 0.45, -0.63],
                                      zoom=0.7)
    # o3d.visualization.draw([pcd]) # new API

 

3 TSDF中使用ray casting

此内容在重建TSDF时补充

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/435025.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

软件测试金融项目经验总结,面试题都问什么?接口加解密如何处理?

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 加/解密接口的处理…

JAVA数据结构之顺序表、单向链表及双向链表的设计和API实现

一、顺序表 顺序表在内存中是数组的形式存储 类名SequenceList构造方法SequenceList(int capacity):创建容量为capacity的SequenceList对象成员方法1. public void clear():空置线性表 2. public boolean isEmpty():判断线性表是否为空&…

浅谈java网络编程及RPC框架

目录 1.计算机网络 2.TCP/IP协议 3.UDP协议 4.RPC框架 1.计算机网络 从资源共享的角度上来说,计算机网络就是以能够相互共享资源的方式互连起来的自治计算机系统的集合。网络建立的主要目的是实现计算机资源的共享。 目前来说,计算机网络分为两大模…

JRE和JDK 及 常用DOS命令

JRE和JDK Java程序开发的三个步骤 ●编写代码 ●编译代码 ●运行代码 1.编写代码 A.txt JRE : JRE是Java Runtime Environment缩写,指Java运行环境,包含JVM虚拟机及Java核心类库。 类:java文件在代码中的集合体现( 类java文件&#xf…

CAD转SHP最好的方法 赶快收藏起来吧

1、利用 ArcToolsbox 工具先将 DWG 文件转为 MDB 通过 CASS 软件生成的 DWG 文件,字段中包含有很多属性内容,所以我们先将 DWG 格式 的文件转换为 MDB 格式,再通过 MDB 转换为 SHP 格式数据进行整理。具体步骤如下: 通过 ArcTool…

jenkins——凭据管理

这里写目录标题 一、Jenkins 凭据管理1、凭据管理入口2、凭据的新增3、用户名和密码方式的凭据配置4、SSH密钥方式的凭据配置5、凭据的更新和删除6、凭据的使用 一、Jenkins 凭据管理 凭据管理的作用:管理ssh、邮箱、git等认证信息 1、凭据管理入口 Dashboard —…

深度学习实战24-人工智能(Pytorch)搭建transformer模型,真正跑通transformer模型,深刻了解transformer的架构

大家好,我是微学AI,今天给大家讲述一下人工智能(Pytorch)搭建transformer模型,手动搭建transformer模型,我们知道transformer模型是相对复杂的模型,它是一种利用自注意力机制进行序列建模的深度学习模型。相较于 RNN 和…

【微信小程序】数据监听器,纯数据字段

一、数据监听器 1.1 什么是数据监听器 数据监听器用于 监听和响应任何属性和数据字段的变化,从而执行特定的操作 。它的作用类似于 vue 中 的 watch 侦听器。在小程序组件中, 在componets中新建一个test2文件夹在文件夹里新建component 在app.json …

C学习笔记3

1、将一个整数转换成二进制形式,就是其原码。(通俗的理解,原码就是一个整数本来的二进制形式。) 例如short a 6;a 的原码就是0000 0000 0000 0110 2、反码就区分正负数,因为正负数的反码是不一样的,正数…

2023年MathorCup数模D题赛题解题思路

MathorCup俗称妈杯,是除了美赛国赛外参赛人数首屈一指的比赛,而我们的妈杯今天也如期开赛。今年的妈杯难度,至少在我看来应该是2023年截至目前来讲最难的一场比赛。问题的设置、背景的选取等各个方面都吐露着我要难死你们的想法。难度是恒定的…

Euro-NCAP 2030愿景

每隔五年,Euro NCAP都会将利益相关者聚集在一起,研究当前的汽车技术现状,预测未来几年可能的挑战,并确定未来的机会所在。讨论的结果是该组织的未来发展方向和明确的未来愿景:Euro NCAP 2030年愿景。 2020年初,Euro NCAP开始制定一套新的战略目标,打算在下一年公布其《2…

STM-32:SPI通信协议/W25Q64简介—软件SPI读写W25Q64

目录 一、SPI简介1.1电路模式1.2通信原理1.3SPI时序基本单元1.3.1起始和终止1.3.2交换字节 二、W25Q642.1W25Q64简介2.2W25Q64硬件电路2.3W25Q64框图2.4Flash操作注意事项 三、软件SPI读写W25Q643.1接线图3.2程序代码 一、SPI简介 SPI是串行外设接口(Serial Periph…

Spring Boot异步任务、异步消息

目录 1.异步任务 1.1.概述 1.2.使用 2.异步消息 2.1.概述 2.2.使用 1.异步任务 1.1.概述 举一个例子,我现在有一个网上商城,客户在界面点击下单后,后台需要完成两步: 1.创建客户订单 2.发短信通知客户订单号 这里面第2…

selenium 连接已经打开的chrome浏览器 MAC

selenium 连接已经打开的chrome浏览器 MAC 一,前言 今天在爬取chatGPT的谷歌插件的prompts的时候,发现绕不过他的反爬机制,失败111,所以想用连接已打开的chatGPT页面进行控制 二,具体步骤 1,添加环境变…

Android入门

一、Android系统架构 Android大致可以分为4层架构:Linux内核层、系统运行库层、应用框架层和应用层 1.1Linux内核层 Android系统是基于Linux内核的,这一层为Android设备的各种硬件提供了如显示、音频、照相机、蓝牙、Wi-Fi等底层的驱动。 1.2系统运行层…

2023MathorCup 高校数学建模挑战赛D题思路解析

如下为MathorCup 高校数学建模挑战赛D题思路解析: D 题 航空安全风险分析和飞行技术评估问题 飞行安全是民航运输业赖以生存和发展的基础。随着我国民航业的快速发展,针对飞行安全问题的研究显得越来越重要。2022 年 3 月 21 日,“3.21”空难…

如何使用vim的插件Ctags查看Linux源码

一.ubuntu下安装Linux内核源码 (1).查看自己的内核版本 (2).查看源内的内核源码类表 (3).下载源码 (4).进入/usr/src (5).解压下载的文件到用户主 二.安装vim插件Ctags和使用 插件的介绍 Ctags工具是用来遍历源代码文件生成tags文件,这些tags文件能被编辑器或其它工…

2023年的深度学习入门指南(4) - 在你的电脑上运行大模型

2023年的深度学习入门指南(4) - 在你的电脑上运行大模型 上一篇我们介绍了大模型的基础,自注意力机制以及其实现Transformer模块。因为Transformer被PyTorch和TensorFlow等框架所支持,所以我们只要能够配置好框架的GPU或者其他加速硬件的支持&#xff0…

同为科技(TOWE)防雷科普篇1—雷电灾害认识与雷电预警信号解读

前 言 雷电是自然界最为壮观的大气现象之一。其强大的电流、炙热的高温、猛烈的冲击波以及强烈的电磁辐射等物理效应能够在瞬间产生巨大的破坏作用,常常导致人员伤亡,击毁建筑物、供配电系统、通信设备,造成计算机信息系统中断,引…

电风扇出口欧美CE/UL507认证办理

电风扇简称电扇,是一种利用电动机驱动扇叶旋转,来达到使空气加速流通的家用电器,主要用于清凉解暑和流通空气。风扇主要由扇头、叶片、网罩和控制装置等部件组成。电风扇的主要部件是:交流电动机。其工作原理是:通电线圈在磁场中受力而转动。…