草庐IT

python如何实现点云可视化交互——Open3D实例教程(获取所选点的信息)保姆级教学

ESRSchao 2023-04-14 原文

前言

Open3D是目前python中可用的用于 3D 数据处理的现代库,可以对点云、网格等三维数据进行读取、采样、配准、可视化等操作。其中对点云等三维模型进行可视化的功能在Python中显得非常方便。

在通过对官方文档的研究之后作者发现在Open3D的多种可视化函数中出现了返回所选点的信息的命令,将代码跑通后就有了这篇三维物体可视化交互的文章,希望诸位能通过这篇文章获取一些新的思路。

开发环境
python 3.9.12
Open3D 0.15.1
Pycharm 2021.2

点云的可视化

Open3D对于点云的可视化可以采用两种方式,一种是直接用visualization下面的用于绘制几何图形列表的函数draw_geometries来进行显示,另外一种就是使用可视化工具Visualizer来进行显示。
第一种方式简单快捷,但并不能返回所选点的信息,如果读者发现了可以返回值的方法欢迎补充。

1. draw_geometries

Open3D的官方文档中给出了四种不同的draw_geometries

  1. draw_geometries —— 用于绘制几何图形列表的函数
  2. draw_geometries_with_editing —— 具有编辑功能的用于绘制几何图形列表的函数
  3. draw_geometries_with_key_callbacks —— 具有自定义键调用功能的绘制几何图形列表的函数
  4. draw_geometries_with_vertex_selection —— 具有顶点选择功能的绘制几何图形列表的函数

除了第一种函数,后三种均可以选取点并在终端里显示选取点的信息,但是并不会返回值,所以我们无法在程序中直接得到所选点的信息。

后三种选取点的可视化效果也不太一样,这边只针对第四种进行说明。

draw_geometries这种方式代码比较简单,平常使用的时候比较方便,感兴趣的可以试着跑跑官方例程:

第一种 draw_geometries

import open3d as o3d
import numpy as np
print("Load a ply point cloud, print it, and render it")
ply_point_cloud = o3d.data.PLYPointCloud()
pcd = o3d.io.read_point_cloud(ply_point_cloud.path)
print(pcd)
print(np.asarray(pcd.points))
o3d.visualization.draw_geometries([pcd],
                                  zoom=0.3412,
                                  front=[0.4257, -0.2125, -0.8795],
                                  lookat=[2.6172, 2.0475, 1.532],
                                  up=[-0.0694, -0.9768, 0.2024])

小提示:在可视化窗口弹出后按H键可以在终端中查看详细的操作菜单

第四种 draw_geometries_with_vertex_selection

import open3d as o3d
import numpy as np
print("Load a ply point cloud, print it, and render it")
ply_point_cloud = o3d.data.PLYPointCloud()
pcd = o3d.io.read_point_cloud(ply_point_cloud.path)
print(pcd)
print(np.asarray(pcd.points))
point = o3d.visualization.draw_geometries_with_key_callbacks([pcd])
print(point)

执行代码,可视化窗口跳出

此时在可视化窗口按下Shift键进入点的选择模式:


这时候使用鼠标可以进行顶点的选择,所选点的信息会显示在终端中:
注意:代码中用point来获取返回值信息,而最后打印出来的point是None证明所选点只会在终端中显示出来,并不会返回值

官方文档中也说明了函数是没有返回值的,那么如果想要获得所选点的信息该怎么办呢。这就可以使用另外一种方法了。

2.Visualizer

Open3D的官方文档中也给出了四种不同的Visualizer

  1. Visualizer —— 可视化工具主类
  2. VisualizerWithEditing —— 具有编辑功能的可视化工具
  3. VisualizerWithKeyCallback —— 具有自定义键调用功能的可视化工具
  4. VisualizerWithVertexSelection —— 具有顶点选择功能的可视化工具

对于open3d.visualization.Visualizer这种可视化工具,它的基本使用方法可以简单总结为下面几步(作者为了演示简化了各函数参数,感兴趣的读者可以参考官方文档):

  1. 创建vis类
    vis = o3d.visualization.VisualizerWithVertexSelection()
  2. 创建可视化窗口
    vis.create_window(window_name=‘Open3D’, width=1920, height=1080, visible=True)
  3. 输入点云或者网格数据
    vis.add_geometry(mesh)
  4. 激活窗口 此操作会阻塞线程
    vis.run()
  5. 清除可视化窗口
    vis.destroy_window()

在可视化过程中也可以通过相关函数进行获得当前视角的RGB图像和深度图等操作,十分方便。

而open3d.visualization.VisualizerWithVertexSelection中增加了一个函数get_picked_points:

get_picked_points(self: open3d.cpu.pybind.visualization.VisualizerWithVertexSelection) → List[open3d::visualization::VisualizerWithVertexSelection::PickedPoint]

它的描述为Function to get picked points,此函数可以返回在可视化窗口选取点的坐标和索引信息。

下图展示了返回值point的信息,可以看到point列表在选取一个点的情况下有0号点的coord三维位置信息以及index索引信息。


整体的程序如下,用的是我自己的点云模型:

import open3d as o3d
import numpy as np
pcd = o3d.io.read_point_cloud("arrow.ply")
vis = o3d.visualization.VisualizerWithVertexSelection()
vis.create_window(window_name='Open3D', visible=True)
vis.add_geometry(pcd)
vis.run()
point = vis.get_picked_points()
vis.destroy_window()
print(point[0].index, np.asarray(point[0].coord))

弹出可视化界面

按住Shift键

选取一个或多个点(选中点显示为绿色)

关闭窗口即可获得所选点的信息
而且信息会被储存在point列表中

如此这般就实现了点云的可视化交互,我们可以通过在可视化界面中直接进行选择从而获得一个或者一部分点的信息,进而可以直接在后续的程序中进行处理。

教程书写不易,如果有帮到诸位还请点个赞或者收藏,谢谢大家。

有关python如何实现点云可视化交互——Open3D实例教程(获取所选点的信息)保姆级教学的更多相关文章

  1. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  2. ruby - 简单获取法拉第超时 - 2

    有没有办法在这个简单的get方法中添加超时选项?我正在使用法拉第3.3。Faraday.get(url)四处寻找,我只能先发起连接后应用超时选项,然后应用超时选项。或者有什么简单的方法?这就是我现在正在做的:conn=Faraday.newresponse=conn.getdo|req|req.urlurlreq.options.timeout=2#2secondsend 最佳答案 试试这个:conn=Faraday.newdo|conn|conn.options.timeout=20endresponse=conn.get(url

  3. ruby - 从 Ruby 中的主机名获取 IP 地址 - 2

    我有一个存储主机名的Ruby数组server_names。如果我打印出来,它看起来像这样:["hostname.abc.com","hostname2.abc.com","hostname3.abc.com"]相当标准。我想要做的是获取这些服务器的IP(可能将它们存储在另一个变量中)。看起来IPSocket类可以做到这一点,但我不确定如何使用IPSocket类遍历它。如果它只是尝试像这样打印出IP:server_names.eachdo|name|IPSocket::getaddress(name)pnameend它提示我没有提供服务器名称。这是语法问题还是我没有正确使用类?输出:ge

  4. ruby - 获取模块中定义的所有常量的值 - 2

    我想获取模块中定义的所有常量的值:moduleLettersA='apple'.freezeB='boy'.freezeendconstants给了我常量的名字:Letters.constants(false)#=>[:A,:B]如何获取它们的值的数组,即["apple","boy"]? 最佳答案 为了做到这一点,请使用mapLetters.constants(false).map&Letters.method(:const_get)这将返回["a","b"]第二种方式:Letters.constants(false).map{|c

  5. ruby - Ruby 中的波形可视化 - 2

    我即将开始一个将录制和编辑音频文件的项目,我正在寻找一个好的库(最好是Ruby,但会考虑Java或.NET以外的任何库)以进行实时可视化波形。有人知道我应该从哪里开始搜索吗? 最佳答案 要流入浏览器的数据量很大。Flash或Flex图表可能是唯一能提高内存效率的解决方案。Javascript图表往往会因大型数据集而崩溃。 关于ruby-Ruby中的波形可视化,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.c

  6. ruby-on-rails - 获取 inf-ruby 以使用 ruby​​ 版本管理器 (rvm) - 2

    我安装了ruby​​版本管理器,并将RVM安装的ruby​​实现设置为默认值,这样'哪个ruby'显示'~/.rvm/ruby-1.8.6-p383/bin/ruby'但是当我在emacs中打开inf-ruby缓冲区时,它使用安装在/usr/bin中的ruby​​。有没有办法让emacs像shell一样尊重ruby​​的路径?谢谢! 最佳答案 我创建了一个emacs扩展来将rvm集成到emacs中。如果您有兴趣,可以在这里获取:http://github.com/senny/rvm.el

  7. Ruby 从大范围中获取第 n 个项目 - 2

    假设我有这个范围:("aaaaa".."zzzzz")如何在不事先/每次生成整个项目的情况下从范围中获取第N个项目? 最佳答案 一种快速简便的方法:("aaaaa".."zzzzz").first(42).last#==>"aaabp"如果出于某种原因你不得不一遍又一遍地这样做,或者如果你需要避免为前N个元素构建中间数组,你可以这样写:moduleEnumerabledefskip(n)returnto_enum:skip,nunlessblock_given?each_with_indexdo|item,index|yieldit

  8. ruby - Net::HTTP 获取源代码和状态 - 2

    我目前正在使用以下方法获取页面的源代码:Net::HTTP.get(URI.parse(page.url))我还想获取HTTP状态,而无需发出第二个请求。有没有办法用另一种方法做到这一点?我一直在查看文档,但似乎找不到我要找的东西。 最佳答案 在我看来,除非您需要一些真正的低级访问或控制,否则最好使用Ruby的内置Open::URI模块:require'open-uri'io=open('http://www.example.org/')#=>#body=io.read[0,50]#=>"["200","OK"]io.base_ur

  9. Python 相当于 Perl/Ruby ||= - 2

    这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:Pythonconditionalassignmentoperator对于这样一个简单的问题表示歉意,但是谷歌搜索||=并不是很有帮助;)Python中是否有与Ruby和Perl中的||=语句等效的语句?例如:foo="hey"foo||="what"#assignfooifit'sundefined#fooisstill"hey"bar||="yeah"#baris"yeah"另外,类似这样的东西的通用术语是什么?条件分配是我的第一个猜测,但Wikipediapage跟我想的不太一样。

  10. ruby - 没有类方法获取 Ruby 类名 - 2

    如何在Ruby中获取BasicObject实例的类名?例如,假设我有这个:classMyObjectSystem我怎样才能使这段代码成功?编辑:我发现Object的实例方法class被定义为returnrb_class_real(CLASS_OF(obj));。有什么方法可以从Ruby中使用它? 最佳答案 我花了一些时间研究irb并想出了这个:classBasicObjectdefclassklass=class这将为任何从BasicObject继承的对象提供一个#class您可以调用的方法。编辑评论中要求的进一步解释:假设你有对象

随机推荐