Python: 用open3D库,连续多帧显示点云(查看localization pose的好坏)

这篇具有很好参考价值的文章主要介绍了Python: 用open3D库,连续多帧显示点云(查看localization pose的好坏)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

  • 连续多帧显示点云,需要 点云文件 和 定位信息(IMU惯导信息),我这里是从bag包里面自己解析出来的定位信息,因为是自己写的节点,所以直接从代码里面跑出来的,不是ros官方定义的,所以没有用官方给出的方法
  • 总体思路:将每一帧点云和旋转矩阵进行 时间对齐 -----> 再进行空间对齐 ------> 统一对齐到一帧坐标系下可视化
    • 时间对齐:就是说我们哪一个时间下录制的pcd要和对应时间下旋转矩阵相乘(我这里没有用严格的时间插值,用的只是他们的差值小于0.01,我就认为是匹配的)
    • 空间对齐:1.看看静态物体(比如杆子)有没有对齐    2.看看地面有没有变厚
    • 每一帧pcd都是在自车坐标系下录制的所以要转到世界坐标系下,然后再转到某一帧的自车坐标系下,就可以看到物体在移动的拖影,但是静止的非物体不会移动
    • Python: 用open3D库,连续多帧显示点云(查看localization pose的好坏)

  • 时间对齐

    • 命令可见   rosbag解析
    • 用ros给出的命令直接解析bag包里面的点云数据,它是以时间戳命名的(unix时间戳),小数点后面有9位
    • Python: 用open3D库,连续多帧显示点云(查看localization pose的好坏)

    • 而我解析定位信息得到的如下图所示,第一列也是时间戳,小数点后面只有6位,后面的16列就是 自车转世界坐标系 的4×4的矩阵
    • Python: 用open3D库,连续多帧显示点云(查看localization pose的好坏)

    • 将两个时间做差小于0.01秒的,就认为匹配
    • 首先先将pcd的时间戳切出来
    • Python: 用open3D库,连续多帧显示点云(查看localization pose的好坏)
    • 再把定位信息的时间戳切出来
      • Python: 用open3D库,连续多帧显示点云(查看localization pose的好坏) 
    • 进行差值判断并转到世界坐标系下

      Python: 用open3D库,连续多帧显示点云(查看localization pose的好坏)

     

    • 在转到某一帧的坐标系下

      Python: 用open3D库,连续多帧显示点云(查看localization pose的好坏)

    • 20帧在统一坐标系下进行可视化

      Python: 用open3D库,连续多帧显示点云(查看localization pose的好坏)文章来源地址https://www.toymoban.com/news/detail-410505.html

  • 总代码:

  • import os
    from os import listdir
    import open3d as o3d
    import numpy as np
    
    #获取pcd的名字
    p=[]
    def get_name_dict():
        name_dict = "./out_pcd"
        pcd_time = []
    
        for i,j,k in os.walk(name_dict):
            pcd_time = k
        for t in pcd_time:
            p.append(t.split(".pcd")[0])
    
        # pcds = listdir("./out_pcd")
        # pcd_name = []
        # for j,l in enumerate(pcds):
        #     pcd_path = os.path.join("./out_pcd",l)
        #     pcd_name.append(l)
        #     # print(l)
    
        return p
    #获取txt文件的每一行
    def get_time_txt():
        txtname = './vehicle2globle_mat.txt'
        txt_time = []
        with open(txtname,"r+",encoding="utf-8") as f:
            for line in f:
                a = line.split()
                txt_time.append(a)
        # print(txt_time[0][0],txt_time[1][0])
    
        return txt_time
    
    #pcd与旋转矩阵相乘
    def Trans(pcd, R):
        '''
        Input:
            pcd, (N, C)
            R, (4, 4)
        '''
        pcd_trans = pcd.copy()
        pcd_hm = np.pad(pcd[:, :3], ((0, 0), (0, 1)), 'constant', constant_values=1) #(N, 4)
        pcd_hm_trans = np.dot(R, pcd_hm.T).T
        pcd_trans[:, :3] = pcd_hm_trans[:, :3]
        return pcd_trans
    
    #将每一个
    def v_to_w():
        dd = []
        R = []
        tt = get_time_txt()
        for o in p:
            # print(o)
            for i  in  range(200):
                a= '%.6f'%float(tt[i][0])
                o=float(o)
                # print("a",a)
                # print("o",o)
                if -0.01 < o-float(a)  < 0.01 :
                    #dd是个列表,存放两个符合条件的txt时间戳,总是dd[0]小,而我也只要小的所以以下就有dd[0]使用
                    dd.append(float(a))
                    print("pcd",o)
                    print("txt",a)
    
                    if len(dd) == 2:
                        print(dd)
                        pcd_path= os.path.join("./out_pcd/",str(o)+'.pcd')
                        # print(pcd_path)
                        #循环txt中每一个元素,切出4*4矩阵
                        for r in range(len(tt)):
                            for t in range(len(tt[0])):
                                if float(tt[r][0]) == dd[0] and t > 0:
                                    #求得4*4旋转矩阵
                                    R.append(tt[r][t])
                                    if len(R) == 16:
                                        print("R",R)
                                        R = np.array(R).reshape(4,4)
                                        print("R.shape",R)
                                        #画图
                                        pcd = o3d.io.read_point_cloud(pcd_path)
                                        pcd_xyz = np.asarray(pcd.points)
                                        valid_mask = ~np.isnan(pcd_xyz.sum(axis=1))
                                        pcd_xyz = pcd_xyz[valid_mask]
                                        R = R.astype(np.float32)
                                        print(R)
                                        pcd_xyz_world = Trans(pcd_xyz, R)
                                        pcd_xyz_world_point = o3d.geometry.PointCloud()
                                        pcd_xyz_world_point.points = o3d.utility.Vector3dVector(pcd_xyz_world)
                                        o = str(o)
                                        # o3d.io.write_point_cloud("./out_pcd_w/"+o+".pcd",pcd_xyz_world_point,write_ascii=True,compressed=False,print_progress=True)
                                        R = R.tolist()
                                        R = R * 0
                        dd.clear()
                else:
                    pass
    
    
    def w_to_R0():
        pcd_dict = os.listdir("./out_pcd_w")
        for i in pcd_dict:
            print(i)
            pcd = o3d.io.read_point_cloud("./out_pcd_w/"+i)
            pcd_xyz = np.asarray(pcd.points)
            valid_mask = ~np.isnan(pcd_xyz.sum(axis=1))
            pcd_xyz = pcd_xyz[valid_mask]
            R0 = np.array([[-0.815266 ,0.578755 ,0.019607 ,656827.306071 ],
                  [-0.578086 ,-0.815380 ,0.031173 ,2967527.172453],
                  [0.034029 ,0.014080 ,0.999322 ,59.210000 ],
                  [0.000000 ,0.000000,0.000000 ,1.000000]])
            R0 = np.linalg.inv(R0)
            pcd_R0 =Trans(pcd_xyz,R0)
            pcd_w_R0 = o3d.geometry.PointCloud()
            pcd_w_R0.points = o3d.utility.Vector3dVector(pcd_R0)
            o3d.io.write_point_cloud("./w_to_R0/" + i, pcd_w_R0, write_ascii=False, compressed=False,
                                     print_progress=False)
    
    def vis_RO():
        pcds = []
        pcds_p = []
        pcd_20 = o3d.geometry.PointCloud()
        files = os.listdir("./w_to_R0")
        for f in files:
            pcd_path = os.path.join("./w_to_R0/" + f)
            pcds_p.append(pcd_path)
            pcd = o3d.io.read_point_cloud(pcd_path)
            # 降采样
            pcd_dow = pcd.voxel_down_sample(voxel_size=0.2)
            pcds.append(pcd_dow)
    
        for i in range(len(pcds_p)):
            if i == 0:
                pcd0 = o3d.io.read_point_cloud(pcds_p[0])
                o3d.io.write_point_cloud("pcd_20_20.pcd",pcd0)
            else:
                pcd1 = o3d.io.read_point_cloud("pcd_20_20.pcd")
                pcd2 = pcd1 + o3d.io.read_point_cloud(pcds_p[i])
                o3d.io.write_point_cloud("pcd_20_20.pcd",pcd2)
                o3d.visualization.draw_geometries([pcd2], window_name="拼接20个点云",
                                                  width=1024, height=768,
                                                  left=50, top=50,
                                                  mesh_show_back_face=False)
    
    
    
    
    
        # # ---------------将两个点云进行拼接------------------
        # pcd0 = o3d.io.read_point_cloud(pcds_p[0])
        # pcd1 = o3d.io.read_point_cloud(pcds_p[1])
        # pcd_combined = o3d.geometry.PointCloud()
        # pcd_20 = pcd0 + pcd1
        # # 保存点云
        # o3d.io.write_point_cloud("pcd_20.pcd", pcd_combined)
        # for i in range(2, 16):
        #     print(i)
        #
        #     pcd_2 = o3d.io.read_point_cloud("pcd_20.pcd")
        #     pcd1 = o3d.io.read_point_cloud(pcds_p[i])
        #
        #     pcd_combined = pcd_2 + pcd1
        #     o3d.io.write_point_cloud("pcd_20.pcd", pcd_combined)
        # o3d.visualization.draw_geometries([pcd_combined], window_name="拼接20个点云",
        #                                   width=1024, height=768,
        #                                   left=50, top=50,
        #                                   mesh_show_back_face=False)
    
    
    
        # o3d.visualization.draw_geometries(pcd_20,
        #                                   window_name="点云旋转",
        #                                   point_show_normal=False,
        #                                   width=800,  # 窗口宽度
        #                                   height=600)
    
    
    
    
    if __name__ == '__main__':
        # print(get_time_txt())
        # get_time_txt()
        # get_name_dict()
        # v_to_w()
        # w_to_R0()
        vis_RO()
    

到了这里,关于Python: 用open3D库,连续多帧显示点云(查看localization pose的好坏)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Open3D完全指南:点云读取、保存与显示

    Open3D完全指南:点云读取、保存与显示 Open3D是一款强大的开源库,旨在促进3D计算机视觉和深度学习技术在研究和开发中的应用。在本文中,我们将专注于如何使用Open3D库来读取、保存和显示点云数据。 首先,让我们看看如何从文件中读取点云数据。Open3D支持多种文件格式,

    2024年02月05日
    浏览(32)
  • 第二章 python-pcl、open3d读取、显示pcd、bin等格式点云数据

    点云数据实际上就是许多组点的集合,每个点由{x,y,z}组成。当然理论上的只包含有3D坐标。 实际激光雷达获取的点云数据还会包含强度、反射率等等。但我们一般只用提取{x,y,z}来处理即可。 点云数据相比于其他传感器数据的核心优势就是在于 精准的深度信息。可惜获取具体

    2024年01月16日
    浏览(49)
  • Open3D点云数据处理(一):VSCode配置python,并安装open3d教程

    专栏地址:https://blog.csdn.net/weixin_46098577/category_11392993.html 在很久很久以前,我写过这么一篇博客,讲的是open3d点云处理的基本方法。👇 当时是 PyCharm + Anaconda + python3.8 + open3d 0.13 已经是2023年了,现在有了全新版本。目前python由当年的3.8更新到了3.11版本,open3d也从0.13来到了

    2024年02月07日
    浏览(47)
  • Open3D 点云裁剪(Python版本)

    基于用户给定的多边形区域,来提取区域内所有的点云数据,这个多边形Open3D会通过一个json文件来进行指定。 CropPointCloud.py

    2024年02月13日
    浏览(34)
  • 在PyQt5窗口中嵌入open3d窗口显示点云图形

     本文方法来自:PYQT5内嵌外部exe程序(win7)_pyqt5嵌入外部窗口_这杯可乐有点甜的博客-CSDN博客 open3d在绘制点云等图形时,通常需要创建一个窗口。本文实现了将open3d创建的窗口显示在Qt窗口内,以便于后续通过Qt控件和槽函数调用open3d强大的绘图和处理功能。 运行结果如下

    2024年02月06日
    浏览(148)
  • Open3D 点云颜色渲染(Python版本)

    Open3D主要有两种方式来进行点云的颜色渲染,一种是使用PaintUniformColor函数为点云赋单色,第二种则是通过对点云对象的colors数组进行操作来实现,这种方式更为灵活。这里也简单实现一下单色渲染以及随机赋色。 PainPointCloud.py

    2024年02月11日
    浏览(30)
  • 『OPEN3D』1.1 点云处理 python篇

    目录 1.open3d中的点云IO 2.点云的可视化 3 点云voxel下采样 4. 顶点法线估计 5.最小外界矩 6. 凸包计算 7. 点云距离计算 8. DBSCAN clustering聚类 9. RANSAC(Random Sample Consensus)  10. 点云平面分割 11. 隐藏点移除 12.outliers移除 13 最远点采样(Farthest Point Sample) 专栏地址:https://blog.csdn.net/

    2024年02月02日
    浏览(29)
  • Open3D 点云投影到拟合平面:Python 实现详解

    Open3D 点云投影到拟合平面:Python 实现详解 点云是指由大量离散的 3D 点组成的几何图形,常常用于工业检测、三维建模等领域。而拟合平面是指在点云数据中找到一个最适合的平面,该平面能够近似地拟合这些点云数据。将点云投影到拟合平面可以方便地进行分析和处理。本

    2024年02月07日
    浏览(38)
  • Open3D 点云数据转深度图像(一,python版本)

    由于对深度图像也是感觉比较好奇,所以就简单的使用正投影的方式来生成一个深度图像来看一下效果,深度值这里采用了z值的差值(高差),具体的代码与效果如下所示。 这里是将点云投影到xoy平面上,使用高差作为深度值。

    2024年02月15日
    浏览(28)
  • 三维点云拟合圆形(附open3d python 代码)

    圆拟合方法可分为以下步骤: 使用  SVD(奇异值分解) 找到平均中心点集的最佳拟合平面。 将均值中心点投影到新的 2D 坐标中的拟合平面上。 使用 最小二乘法 拟合 2D 坐标中的圆并得到圆心和半径。 将圆中心变换回 3D 坐标。现在,拟合圆由其中心、半径和法线向量指定。

    2024年02月06日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包