Open3D 将点云投影到圆柱

目录

一、概述

1.1原理介绍

1.2实现步骤

二、代码实现

2.1关键函数

2.2完整代码

三、实现效果

3.1原始点云

3.2投影后点云


前期试读,后续会将博客加入下列链接的专栏,欢迎订阅

Open3D点云算法与点云深度学习案例汇总(长期更新)-CSDN博客

一、概述

        将点云投影到圆柱上需要将每个点投影到圆柱的表面。我们需要定义圆柱的轴线、半径,并计算每个点到轴线的投影位置。然后,根据这些投影位置计算出投影到圆柱表面上的点。

1.1原理介绍

        圆柱可以用一个轴线(由轴线方向向量和轴线上任意一点定义)和半径来定义。将点云投影到圆柱上的步骤如下:

  1. 计算每个点到圆柱轴线的投影位置。
  2. 将这些投影位置投影到圆柱表面。

1.2实现步骤

  1. 生成或读取点云数据:使用 Open3D 生成或读取点云数据。
  2. 定义圆柱:给定圆柱的轴线(方向向量和轴线上任意一点)和半径。
  3. 计算投影向量:计算每个点在圆柱轴线上的投影位置,然后将这些位置投影到圆柱表面。
  4. 替换点云数据:用投影位置替换原始点云数据。
  5. 可视化结果:使用 Open3D 可视化投影后的点云数据。

二、代码实现

2.1关键函数

计算投影向量:

  • project_to_cylinder 函数中,首先计算每个点到圆柱轴线的投影位置。具体来说,先计算每个点到轴线起点的向量,然后计算这些向量在轴线方向上的投影,得到投影点在轴线上的位置。
  • 计算每个点到轴线的径向向量,并将其归一化到圆柱半径,得到投影到圆柱表面上的点。
def project_to_cylinder(pcd, cylinder_axis_point, cylinder_axis_direction, cylinder_radius):
    """
    将点云投影到给定的圆柱上。

    参数:
    pcd (open3d.geometry.PointCloud): 输入点云。
    cylinder_axis_point (np.ndarray): 圆柱轴线上任意一点 (x, y, z)。
    cylinder_axis_direction (np.ndarray): 圆柱轴线的方向向量 (dx, dy, dz)。
    cylinder_radius (float): 圆柱的半径。

    返回:
    open3d.geometry.PointCloud: 投影后的点云。
    """
    points = np.asarray(pcd.points)
    cylinder_axis_point = np.asarray(cylinder_axis_point)
    cylinder_axis_direction = np.asarray(cylinder_axis_direction)
    cylinder_axis_direction = cylinder_axis_direction / np.linalg.norm(cylinder_axis_direction)  # 归一化方向向量

    # 计算每个点到圆柱轴线的投影
    vectors_to_axis = points - cylinder_axis_point
    projections_onto_axis = np.dot(vectors_to_axis, cylinder_axis_direction)[:, None] * cylinder_axis_direction
    projected_points_on_axis = projections_onto_axis + cylinder_axis_point

    # 计算每个点到轴线的径向向量,并归一化到圆柱半径
    radial_vectors = points - projected_points_on_axis
    radial_vectors_normalized = radial_vectors / np.linalg.norm(radial_vectors, axis=1, keepdims=True) * cylinder_radius

    # 计算投影到圆柱表面上的点
    projected_points = projected_points_on_axis + radial_vectors_normalized

    # 创建新的点云
    projected_pcd = o3d.geometry.PointCloud()
    projected_pcd.points = o3d.utility.Vector3dVector(projected_points)
    return projected_pcd

2.2完整代码

import open3d as o3d
import numpy as np

def generate_random_point_cloud(num_points=1000):
    """
    生成随机点云数据。

    参数:
    num_points (int): 点的数量。

    返回:
    open3d.geometry.PointCloud: 生成的点云。
    """
    points = np.random.uniform(-10, 10, (num_points, 3))
    pcd = o3d.geometry.PointCloud()
    pcd.points = o3d.utility.Vector3dVector(points)
    return pcd

def project_to_cylinder(pcd, cylinder_axis_point, cylinder_axis_direction, cylinder_radius):
    """
    将点云投影到给定的圆柱上。

    参数:
    pcd (open3d.geometry.PointCloud): 输入点云。
    cylinder_axis_point (np.ndarray): 圆柱轴线上任意一点 (x, y, z)。
    cylinder_axis_direction (np.ndarray): 圆柱轴线的方向向量 (dx, dy, dz)。
    cylinder_radius (float): 圆柱的半径。

    返回:
    open3d.geometry.PointCloud: 投影后的点云。
    """
    points = np.asarray(pcd.points)
    cylinder_axis_point = np.asarray(cylinder_axis_point)
    cylinder_axis_direction = np.asarray(cylinder_axis_direction)
    cylinder_axis_direction = cylinder_axis_direction / np.linalg.norm(cylinder_axis_direction)  # 归一化方向向量

    # 计算每个点到圆柱轴线的投影
    vectors_to_axis = points - cylinder_axis_point
    projections_onto_axis = np.dot(vectors_to_axis, cylinder_axis_direction)[:, None] * cylinder_axis_direction
    projected_points_on_axis = projections_onto_axis + cylinder_axis_point

    # 计算每个点到轴线的径向向量,并归一化到圆柱半径
    radial_vectors = points - projected_points_on_axis
    radial_vectors_normalized = radial_vectors / np.linalg.norm(radial_vectors, axis=1, keepdims=True) * cylinder_radius

    # 计算投影到圆柱表面上的点
    projected_points = projected_points_on_axis + radial_vectors_normalized

    # 创建新的点云
    projected_pcd = o3d.geometry.PointCloud()
    projected_pcd.points = o3d.utility.Vector3dVector(projected_points)
    return projected_pcd

# 生成随机点云
num_points = 1000
pcd = generate_random_point_cloud(num_points)

# 定义圆柱 (例如,轴线方向向量为 (0, 0, 1),轴线上一点为 (0, 0, 0),半径为 5)
#圆柱由一个轴线方向向量、轴线上任意一点和半径定义。方向向量需要归一化,即方向向量的长度为1。
cylinder_axis_point = np.array([0.0, 0.0, 0.0])
cylinder_axis_direction = np.array([0.0, 0.0, 1.0])
cylinder_radius = 5.0

# 将点云投影到圆柱上
projected_pcd = project_to_cylinder(pcd, cylinder_axis_point, cylinder_axis_direction, cylinder_radius)

# 可视化原始点云和投影后的点云
o3d.visualization.draw_geometries([pcd], window_name="Original Point Cloud", width=800, height=600, left=50, top=50)
o3d.visualization.draw_geometries([projected_pcd], window_name="Projected Point Cloud on Cylinder", width=800, height=600, left=850, top=50)

# 保存投影后的点云
o3d.io.write_point_cloud("projected_cylinder.pcd", projected_pcd)

三、实现效果

3.1原始点云

3.2投影后点云

相关推荐

  1. PCL 圆柱的距离(3D

    2024-07-22 11:48:02       33 阅读
  2. OPEN3D』1.7 拟合问题

    2024-07-22 11:48:02       69 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-22 11:48:02       52 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-22 11:48:02       54 阅读
  3. 在Django里面运行非项目文件

    2024-07-22 11:48:02       45 阅读
  4. Python语言-面向对象

    2024-07-22 11:48:02       55 阅读

热门阅读

  1. 掌握Git:面试中常见的问题与解答

    2024-07-22 11:48:02       16 阅读
  2. DOS常用命令大全

    2024-07-22 11:48:02       12 阅读
  3. 设计模式在FileBrowser中的几个应用

    2024-07-22 11:48:02       13 阅读
  4. 代码随想录 day 17 二叉树

    2024-07-22 11:48:02       16 阅读
  5. Golang_交替打印ABC\奇偶数\1-10\字母(并发编程)

    2024-07-22 11:48:02       15 阅读
  6. 每天一个数据分析题(四百三十六)- 正态分布

    2024-07-22 11:48:02       16 阅读
  7. 使用Event Sourcing模式管理应用状态

    2024-07-22 11:48:02       18 阅读
  8. 从0到1搭建数据中台(4):TiDB的安装和使用

    2024-07-22 11:48:02       16 阅读
  9. Modbus协议了解与简单使用

    2024-07-22 11:48:02       20 阅读
  10. springboot引入kafka

    2024-07-22 11:48:02       14 阅读
  11. web前端 React 框架面试200题(五)

    2024-07-22 11:48:02       14 阅读
  12. MySQL

    2024-07-22 11:48:02       14 阅读
  13. Udp协议

    Udp协议

    2024-07-22 11:48:02      20 阅读
  14. Xcode应用开发:自定义图表的终极指南

    2024-07-22 11:48:02       17 阅读