open3d-点云及其操作

open3d提供了一个专门用于点云的数据结构 PointCloud

class PointCloud(Geometry3D):
    color   # 颜色
    normals # 法向量
    points  # 点云
    def __init__(self, *args, **kwargs):
        """
        __init__(*args, **kwargs)
        Overloaded function.
        1. __init__(self: open3d.cpu.pybind.geometry.PointCloud) -> None
        Default constructor
        2. __init__(self: open3d.cpu.pybind.geometry.PointCloud, arg0: open3d.cpu.pybind.geometry.PointCloud) -> None
        Copy constructor
        3. __init__(self: open3d.cpu.pybind.geometry.PointCloud, points: open3d.cpu.pybind.utility.Vector3dVector) -> None
        Create a PointCloud from points
        """
    # dbscan聚类
    def cluster_dbscan(self, eps, min_points, print_progress=False):
    # 计算凸包
    def compute_convex_hull(self):
    # 计算马氏距离。 返回每个点的马氏距离
    def compute_mahalanobis_distance(self):
    # 计算均值与协方差矩阵
    def compute_mean_and_covariance(self): 
    # 计算点云每个点到其最近点的距离
    def compute_nearest_neighbor_distance(self):
    # 计算当前点云每个点到目标点云的最近距离
    def compute_point_cloud_distance(self, target):
    def create_from_depth_image(self, depth, intrinsic, extrinsic, *args, **kwargs):
    def create_from_rgbd_image(self, image, intrinsic, extrinsic, *args, **kwargs):
    # 裁剪。 输入一个aabb框或obb框
    def crop(self, *args, **kwargs):
    # 计算顶点法向量
    def estimate_normals(self, search_param=None, *args, **kwargs):
    # 是否有color
    def has_colors(self):
    # 是否有法向量
    def has_normals(self):
    # 是否有点云点
    def has_points(self):    
    # 隐藏点去除。 
    def hidden_point_removal(self, camera_location, radius):
    # 归一化法向量。 法向量长度为1
    def normalize_normals(self):
    # 法向量方向一致
    def orient_normals_consistent_tangent_plane(self, k):
    # 法向量方向一致。 指定相机位置
    def orient_normals_towards_camera_location(self, camera_location=None, *args, **kwargs):
    # 法向量方向一致。 指定参考方向
    def orient_normals_to_align_with_direction(self, orientation_reference=None, *args, **kwargs):
    # 上色。 颜色rgb,范围0~1
    def paint_uniform_color(self, color):
    # 随机下采样。 指定下采样率
    def random_down_sample(self, sampling_ratio):
    # 删除non 和 inf 值的点
    def remove_non_finite_points(self, remove_nan=True, remove_infinite=True):   
    # 删除指定半径内少于指定点数的点
    def remove_radius_outlier(self, nb_points, radius):
    # 删除相邻点中距离大于平均距离的点
    def remove_statistical_outlier(self, nb_neighbors, std_ratio):
    # 平面分割
    def segment_plane(self, distance_threshold, ransac_n, num_iterations):
    # 按照下标筛选点云
    def select_by_index(self, indices, invert=False):
    # 下采样。 每隔多少个点取一个
    def uniform_down_sample(self, every_k_points):
    # 体素下采样。 指定体素尺寸
    def voxel_down_sample(self, voxel_size):
    # 体素下采样并记录原数据。 指定体素尺寸
    def voxel_down_sample_and_trace(self, voxel_size, min_bound, max_bound, approximate_class=False): 
    
import numpy as np
import open3d as o3d
from open3d.web_visualizer import draw
from open3d.visualization import draw_geometries
pcd = o3d.io.read_point_cloud('datas/fragment.ply')
draw(pcd)

1.体素下采样

open3d.geometry.PointCloud 提供了 voxel_down_sample(self, voxel_size) 方法,来进行体素下采样操作。

    def voxel_down_sample(self, voxel_size):
        """
        voxel_down_sample(self, voxel_size)
        对输入点云进行体素下采样,如果法线和颜色存在,则法线和颜色取均值。

        Args:
            voxel_size (float): 体素尺寸

        Returns:
            open3d.geometry.PointCloud
        """
downsample = pcd.voxel_down_sample(voxel_size=0.05)
draw(downsample)

2. 顶点法向量估计

open3d.geometry.PointCloud 提供了 estimate_normals(self, voxel_size) 方法,来计算顶点法向量。

    def estimate_normals(self, search_param=None, *args, **kwargs): 
        """
        estimate_normals(self, search_param=KDTreeSearchParamKNN with knn = 30, fast_normal_computation=True)        
        Args:
            search_param (open3d.geometry.KDTreeSearchParam, optional): 用于领域搜索的KDTree搜索参数。 默认值为:KDTreeSearchParamKNN with knn = 30
            fast_normal_computation (bool, optional, default=True): 如果为true,通过协方差矩阵计算特征向量,速度更快,但数值不稳定。如果为False,则使用迭代方式。

        Returns:
            None   无返回值,法向量直接存储于 PointCloud.normals 
        """

search_param 参数有:

  • class KDTreeSearchParamHybrid(KDTreeSearchParam):
    def init(self, radius, max_nn): # 搜索半径、最大近邻点数
  • class KDTreeSearchParamKNN(KDTreeSearchParam):
    def init(self, knn=30): # 近邻点数
  • class KDTreeSearchParamRadius(KDTreeSearchParam):
    def init(self, radius): # 搜索半径
downsample.estimate_normals(search_param=o3d.geometry.KDTreeSearchParamHybrid(radius=0.1, max_nn=30))

# 此处使用 draw_geometries绘制点云以及法线。
draw_geometries([downsample], point_show_normal=True)

3. 裁剪点云

裁剪点云,首先需要确定裁剪区域

通过o3d.visualization.read_selection_polygon_volume()函数,读取一个多边形区域。

然后通过多边形裁剪点云。

def read_selection_polygon_volume(filename): 
    """
    read_selection_polygon_volume(filename)
    Function to read SelectionPolygonVolume from file

    Args:
        filename (str): The file path.

    Returns:
        open3d.visualization.SelectionPolygonVolume
    """
    pass

open3d.visualization.SelectionPolygonVolume 含有两个方法:

  • crop_point_cloud(input)
  • crop_triangle_mesh(input)
# 读取多边形
vol = o3d.visualization.read_selection_polygon_volume('datas/cropped.json')
chair = vol.crop_point_cloud(pcd)
draw(chair)

4. 点云上色

open3d.geometry.PointCloud 提供了 paint_uniform_color(self, color)方法,来为点云进行上色。

def paint_uniform_color(self, color): 
    """
    paint_uniform_color(self, color)
    Assigns each point in the PointCloud the same color.

    Args:
        color (numpy.ndarray[float64[3, 1]]):RGB颜色,值在0~1范围内

    Returns:
        open3d.geometry.PointCloud
    """
    pass
chair.paint_uniform_color([1,0,0])  # 红色
draw(chair)

5. 点云距离与筛选

open3d.geometry.PointCloud 提供了 compute_point_cloud_distance(self, target)方法,计算当前点云中每个点到目标点云中点的最近距离。

def compute_point_cloud_distance(self, target):
    """        
    Args:
        target (open3d.geometry.PointCloud): 目标点云

    Returns:
        open3d.utility.DoubleVector
    """

open3d.geometry.PointCloud 提供了 select_by_index(self, indices, invert=False)方法,通过下标来筛选点云。

def select_by_index(self, indices, invert=False):
    """
    select_by_index(self, indices, invert=False)        
    Args:
        indices (List[int]): 下标
        invert (bool, optional, default=False): 反选

    Returns:
        open3d.geometry.PointCloud
    """
dists = pcd.compute_point_cloud_distance(chair)  # 计算整体点云中,每个点到椅子点云中最近点的距离。
dists = np.array(dists)
ind = np.where(dists > 0.01)[0]  # 获取距离大于0.01的点的下标
pcd_without_chair = pcd.select_by_index(ind)  # 通过下标筛选点云中点
draw(pcd_without_chair)

6. 边界框

o3d.geometry.Geometry3D 提供了 get_axis_aligned_bounding_box() 方法,来获取aabb包围盒(轴对齐包围盒)

def get_axis_aligned_bounding_box(self):
    """
    get_axis_aligned_bounding_box(self)        
    Returns:
        open3d.geometry.AxisAlignedBoundingBox
    """

o3d.geometry.Geometry3D 提供了 get_oriented_bounding_box() 方法,来获取obb包围盒(有向包围盒)

def get_oriented_bounding_box(self):
    """
    Returns:
        open3d.geometry.OrientedBoundingBox
    """
aabb = chair.get_axis_aligned_bounding_box()
print(aabb)
draw([chair, aabb])

obb = chair.get_oriented_bounding_box()
print(obb)
draw([chair, obb])

7.凸包

o3d.geometry.Geometry3D 提供了 compute_convex_hull() 方法,来获取点云的凸包。

def compute_convex_hull(self):
    """
    Returns:
        Tuple[open3d.geometry.TriangleMesh, List[int]] 返回两个值,第一个以三角形网格返回凸包,第二个返回凸包的顶点下标。
    """
hull, ind = chair.compute_convex_hull()

hull.paint_uniform_color([1,0,0])
draw([hull, chair])

chair.paint_uniform_color([0.5,0.5,0.5])
points = chair.select_by_index(ind)  # 红色点为凸包顶点
points.paint_uniform_color([1,0,0])
draw([chair, points])

8. dbscan聚类

open3d.geometry.PointCloud 提供了 cluster_dbscan(self, eps, min_points, print_progress=False) 方法,实现dbscan密度聚类。

def cluster_dbscan(self, eps, min_points, print_progress=False):
    """
    cluster_dbscan(self, eps, min_points, print_progress=False)        
    Args:
        eps (float):密度
        min_points (int): 形成簇的最小点数
        print_progress (bool, optional, default=False): 
    Returns:
        open3d.utility.IntVector label值,int
    """
from matplotlib import pyplot as plt
labels = pcd.cluster_dbscan(eps=0.02, min_points=10, print_progress=True)
labels = np.asarray(labels)
max_label = labels.max()
colors = plt.get_cmap("tab20")(labels / (max_label if max_label > 0 else 1))
colors[labels < 0] = 0
pcd.colors = o3d.utility.Vector3dVector(colors[:, :3])

draw(pcd)

9. 平面分割

open3d.geometry.PointCloud 提供了 **segment_plane(self, distance_threshold, ransac_n, num_iterations)** 方法,通过RANSAC从点云中分割平面。
def segment_plane(self, distance_threshold, ransac_n, num_iterations):
    """        
    Args:
        distance_threshold (float): 点到面的最大距离
        ransac_n (int): 随机采样估计平面的点数
        num_iterations (int): 迭代次数

    Returns:
        Tuple[numpy.ndarray[float64[4, 1]], List[int]]
        """
pcd = o3d.io.read_point_cloud('datas/fragment.ply')
plane_model, ind = pcd.segment_plane(distance_threshold=0.01, ransac_n=3, num_iterations=1000)

plane = pcd.select_by_index(ind)
plane.paint_uniform_color([1,0,0])
without_plane = pcd.select_by_index(ind, True)
draw([plane, without_plane])

10. 隐藏点去除

open3d.geometry.PointCloud 提供了 hidden_point_removal(self, camera_location, radius) 方法。

def hidden_point_removal(self, camera_location, radius):
    """        
    Args:
        camera_location (numpy.ndarray[float64[3, 1]]): All points not visible from that location will be reomved
        radius (float): The radius of the sperical projection

    Returns:
        Tuple[open3d.geometry.TriangleMesh, List[int]]
    """
diameter = np.linalg.norm(np.asarray(pcd.get_max_bound()) - np.asarray(pcd.get_min_bound()))
camera = [0, 0, diameter]
radius = diameter * 100
_, pt_map = pcd.hidden_point_removal(camera, radius)

pcd = pcd.select_by_index(pt_map)
draw(pcd)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

多个加速度计/麦克风连接指引

座舱内的振动投诉&#xff1a;如乘客/驾驶员在车厢内感受到传动轴、方向盘抖动剧烈 图1.三轴模式下的单个加速度计 图2.软件设置界面 如果您只有一个加速度计&#xff0c;可以在三轴模式下使用一个加速度计找出客户投诉车厢内振动最强烈的区域。例如将加速度计连接到驾驶员座椅…

猫头虎博主与CSDN的三年之约——我的创作纪念日三周年

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

关于大模型在文本分类上的尝试

文章目录 前言所做的尝试总结前言 总共25个类别,在BERT上的效果是48%,数据存在不平衡的情况,训练数据分布如下: 训练数据不多,4000左右 所做的尝试 1、基于 Qwen-14b-base 做Lora SFT,Loss忘记记录 准确率在68%左右 Lora配置 class LoraArguments:lora_r: int = 64…

我在Vscode学OpenCV 图像处理一(阈值处理、形态学操作【连通性,腐蚀和膨胀,开闭运算,礼帽和黑帽,内核】)

文章目录 一、阈值处理1.1 OpenCV 提供了函数 cv2.threshold()和函数 cv2.adaptiveThreshold()&#xff0c;用于实现阈值处理1.1.1. cv2.threshold()&#xff1a;(1)在函数cv2.threshold()中&#xff0c;参数threshold_type用于指定阈值处理的方式。它有以下几种可选的阈值类型…

C#开发的OpenRA游戏之属性SelectionDecorations(13)

C#开发的OpenRA游戏之属性SelectionDecorations(13) 在前面分析SelectionDecorations属性类时,会发现它有下面这个属性: public class SelectionDecorations : SelectionDecorationsBase, IRender { readonly Interactable interactable; 它是定义了一个Interactabl…

Python使用pywebview开发桌面应用:打造现代化、跨平台的用户体验

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com 在当今科技快速发展的时代&#xff0c;为了提供更好的用户体验&#xff0c;许多应用程序都转向了桌面应用的开发。在Python领域&#xff0c;pywebview是一款优秀的库&#xff0c;它使得用Web技术开发桌面应用变得…

Java高级技术(动态代理)

一&#xff0c;代理 二&#xff0c;案例 放到代码中演示&#xff1a; 首先&#xff0c;创建一个明星接口&#xff0c;这个接口有一个skill方法&#xff0c;说明只要是明星就必须有点技能。 public interface Star {void skill(); } 然后&#xff0c;创建坤坤对象&#xff0c…

震坤行自有品牌 | 搬运存储全面打造快速选型的标准品

震坤行自有品牌 | 搬运存储全面打造快速选型的标准品 中国仓储与配送协会2023年仓储配送行业发展与趋势展望报告中指出&#xff0c;截至2022年底&#xff0c;我国营业性通用&#xff08;常温&#xff09;仓库面积约为12.2亿㎡&#xff0c;仓储业&#xff08;含装卸搬运&#x…

池式组件 ----- Mysql连接池的原理实现

前言 本文是mysql连接池的实现。学完mysql连接池之后&#xff0c;接下来会结合多线程来进行测试&#xff0c;看看使用连接池性能高&#xff0c;还是不要连接池性能高&#xff0c;具体能差多少。当然这是下一篇文章了哈哈哈哈哈。当前首要任务是学会连接池&#xff0c;会都不会…

深度学习——激活函数汇总

深度学习——激活函数汇总 一、ReLU 一、ReLU 参考资料&#xff1a; https://zhuanlan.zhihu.com/p/428448728

试试手气(Python)

题目描述 试试手气 我们知道一个骰子有 6 个面&#xff0c;分别刻了 1 到 6 个点。下面给你 6 个骰子的初始状态&#xff0c;即它们朝上一面的点数&#xff0c;让你一把抓起摇出另一套结果。假设你摇骰子的手段特别精妙&#xff0c;每次摇出的结果都满足以下两个条件&#xff…

高速PCB设计中的射频分析与处理方法

射频&#xff08;Radio Frequency&#xff0c;RF&#xff09;电路在现代电子领域中扮演着至关重要的角色&#xff0c;涵盖了广泛的应用&#xff0c;从通信系统到雷达和射频识别&#xff08;RFID&#xff09;等。在高速PCB设计中&#xff0c;射频电路的分析和处理是一项具有挑战…

【正点原子STM32连载】 第六十一章 USB读卡器(Slave)实验摘自【正点原子】APM32F407最小系统板使用指南

1&#xff09;实验平台&#xff1a;正点原子APM32F407最小系统板 2&#xff09;平台购买地址&#xff1a;https://detail.tmall.com/item.htm?id609294757420 3&#xff09;全套实验源码手册视频下载地址&#xff1a; http://www.openedv.com/thread-340252-1-1.html## 第六十…

UG\NX二次开发 创建对象属性UF_ATTR_set_user_attribute

文章作者:里海 来源网站:里海NX二次开发3000例专栏 简介 创建对象属性UF_ATTR_set_user_attribute,这是一个新函数用于替代UF_ATTR_assign,旧版本NX是用UF_ATTR_assign函数创建、更新属性值,请参照这篇文章《UG\NX二次开发 创建对象属性UF_ATTR_assign》 下面是这个新函数…

在Windows 10中,主要有两种方法进入UEFI固件设置,包括传统的方法

在计算机上&#xff0c;基本输入输出系统&#xff08;BIOS&#xff09;是一种重要的底层软件&#xff0c;位于主板的一个芯片上&#xff0c;它负责基本操作&#xff0c;如引导和配置硬件&#xff08;鼠标、键盘、内存、处理器等&#xff09;。统一可扩展固件接口&#xff08;UE…

加速产品成长:待完成工作框架如何改变游戏规则

待完成的工作 (JTBD) 框架旨在认识到客户心中有特定的目标&#xff0c;我们将这些目标称为工作。然后&#xff0c;客户“租用”产品或服务来帮助他们实现特定目标。该产品成为客户试图完成的工作的解决方案。如果一种产品或服务有效地帮助客户实现目标&#xff0c;他们就更有可…

C++ :运算符重载

运算符重载&#xff1a; 运算符重载概念&#xff1a;对已有的运算符重新进行定义&#xff0c;赋予其另一种功能&#xff0c;以适应不同的数据类型 加号运算符重载&#xff1a; 作用&#xff1a;实现两个自定义数据类型相加的运算 1.成员函数实现 号运算符重载 #include <io…

恋上数据结构与算法之二叉堆

文章目录 需求分析Top K 问题堆堆的基本接口设计二叉堆(Binary Heap)最大堆添加思路交换位置的优化实现 删除思路流程图解实现 replace批量建堆自上而下的上滤自下而上的下滤效率对比复杂度计算实现 完整代码 最小堆比较器解析Top K 问题问题分析代码实现内部方法分析问题 2 堆…

智慧科研助力科研数据的分析处理

如今&#xff0c;科研领域的发展日新月异&#xff0c;数据量也越来越大。这时&#xff0c;智慧科研可视化技术不仅为科研人员提供了快速高效的数据分析手段&#xff0c;而且为科研工作的推进提供了新的思路和方法。通过可视化手段&#xff0c;我们可以将各种数据、信息、知识以…

可行性研究:2023年废旧金属回收行业前景及市场数据分析

废品收购是再生资源行业的重要业务之一。是指将各种废弃物品分类后按不同种类和性能卖给不同的生产厂商或直接出售给再制造厂家&#xff08;如重新使用报废汽车拆解的零件&#xff09;。废旧金属是指暂时失去使用价值的金属或合金制品&#xff0c;一般的废旧金属都含有有用的金…