当前位置: 首页 > news >正文

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) -> NoneDefault constructor2. __init__(self: open3d.cpu.pybind.geometry.PointCloud, arg0: open3d.cpu.pybind.geometry.PointCloud) -> NoneCopy constructor3. __init__(self: open3d.cpu.pybind.geometry.PointCloud, points: open3d.cpu.pybind.utility.Vector3dVector) -> NoneCreate 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):# 是否有colordef has_colors(self):# 是否有法向量def has_normals(self):# 是否有点云点def has_points(self):    # 隐藏点去除。 def hidden_point_removal(self, camera_location, radius):# 归一化法向量。 法向量长度为1def 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~1def 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 = 30fast_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 fileArgs: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 reomvedradius (float): The radius of the sperical projectionReturns: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)

相关文章:

open3d-点云及其操作

open3d提供了一个专门用于点云的数据结构 PointCloud。 class PointCloud(Geometry3D):color # 颜色normals # 法向量points # 点云def __init__(self, *args, **kwargs):"""__init__(*args, **kwargs)Overloaded function.1. __init__(self: open3d.cpu.py…...

无人机助力电力设备螺母缺销智能检测识别,python基于YOLOv7开发构建电力设备螺母缺销高分辨率图像小目标检测系统

传统作业场景下电力设备的运维和维护都是人工来完成的&#xff0c;随着现代技术科技手段的不断发展&#xff0c;基于无人机航拍飞行的自动智能化电力设备问题检测成为了一种可行的手段&#xff0c;本文的核心内容就是基于YOLOv7来开发构建电力设备螺母缺销检测识别系统&#xf…...

如何使用Python的Open3D开源库进行三维数据处理

简介 在本文中&#xff0c;我提供了一个关于如何使用Python的Open3D库&#xff08;一个用于3D数据处理的开源库&#xff09;来探索、处理和可视化3D模型的快速演练。 使用Open3D可视化的3D模型&#xff08;链接https://sketchfab.com/3d-models/tesla-model-s-plaid-9de8855fa…...

HarmonyOS应用开发者基础认证试题

判断题 1.Ability是系统调度应用的最小单元&#xff0c;是能够完成一个独立功能的组件。一个应用可以包含一个或多个Ability。(true) 2.Tabs组件仅可包含子组件TabsContent&#xff0c;每一个页签对应一个内容视图即TabContet组件。(true) 3.使用http模块发起网络请求时&#…...

Android Camera2开启电子防抖(EIS)和光学防抖(OIS)

刚好当前项目有录像功能&#xff0c;使用了第三方框架是基于Camera2引擎开发&#xff0c;当使用 Camera2 API 开发相机应用时&#xff0c;启用和关闭 EIS&#xff08;电子防抖&#xff09;是一个重要的功能。EIS 可以帮助减少相机拍摄时的抖动&#xff0c;从而提高图像和视频的…...

劲爆:Sam Altman 回归CEO专访确认Q*的存在

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…...

Electronica慕尼黑电子展 Samtec团队与21ic分享虎家产品与方案

【摘要/前言】 “希望但凡是能够使用到连接器的场合都有Samtec的身影” 在慕尼黑上海电子展现场&#xff0c;Samtec华东区销售经理章桢彦先生在与21ic副主编刘岩轩老师的采访中&#xff0c;如是说道。这是一种愿景&#xff0c;更是Samtec的努力方向。短短一句话&#xff0c;…...

Vue基本使用(一)

&#x1f4d1;前言 本文主要是【Vue】——Vue基本使用的文章&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是听风与他&#x1f947; ☁️博客首页&#xff1a;CSDN主页听风与他 &#x1f304;每日一句&#x…...

Android:BackStackRecord

BackStackRecord:fragment回退栈,继承自FragmentTransaction,并且实现了OpGenerator接口,OpGenerator接口用来添加或弹出事务的,后面会提到。 从《Android:从源码看FragmentManager如何工作》文章知道,每次beginTransaction会创建一个BackStackRecord对象,改对象持有f…...

微信小程序 slider 翻转最大和最小值

微信小程序 slider 翻转最大和最小值 场景代码示例index.wxmlindex.jsutil.js 参考资料 场景 我想使用 slider 时最左边是 10 最右是 -10。 但是想当然的直接改成<slider min"10" max"-10" step"1" /> 并没用。 查了文档和社区也没有现成…...

APITable免费开源的多维表格与可视化数据库本地部署公网远程访问

APITable免费开源的多维表格与可视化数据库公网远程访问 文章目录 APITable免费开源的多维表格与可视化数据库公网远程访问前言1. 部署APITable2. cpolar的安装和注册3. 配置APITable公网访问地址4. 固定APITable公网地址 前言 vika维格表作为新一代数据生产力平台&#xff0c…...

配电房综合监控系统

配电房综合监控系统是一种集成了实时监控、数据采集、远程控制等多功能的系统&#xff0c;用于对配电房进行全方位的监测和管理。 力安科技配电室综合监控系统依托电易云-智慧电力物联网&#xff0c;实现配电室环境监测、有害气体监测、安防监控、采暖通风、门禁、灯光、风机、…...

【JavaSE】集合(学习笔记)

一、数据结构 1、栈 压栈 / 弹栈栈顶元素、栈底元素先进后出 2、队列 入队列 / 出队列前端、后端先进先出 3、数组 查询效率高&#xff0c;增删效率低 4、链表 查询效率低(必须从头找)&#xff0c;增删效率高 5、哈希表 比较方法哈希值equals结构&#xff1a;数组 链…...

Mybatis 的简单运用介绍

Mybatis 用于操作数据库 操作数据库肯定需要: 1.SQL语句 2.数据库对象和 java 对象的映射 接下来我们看看怎么使用 Mybatis 我们先搞一些数据库内容 然后将其这些内容和Java对象进行映射 再创建一个类实现 select * from 再写一个类证明上述代码是否可以实现 别忘了在appli…...

python的itertools库

itertools常用的方法如下&#xff1a; import itertools 1. 生成的列表累加&#xff0c;在生成新的列表x itertools.accumulate(range(10))print(list(x))结果&#xff1a;[0, 1, 3, 6, 10, 15, 21, 28, 36, 45] 2. 连接多个列表或者迭代器x itertools.chain(range(3), rang…...

STM32/GD32_分散加载

Q&#xff1a;如何将一个变量、某个源文件的函数在编译阶段就存储在用户指定的区域&#xff1f; KEIL环境&#xff1a;.map后缀文件、.sct后缀文件 IAR环境&#xff1a;.map后缀文件、.icf后缀文件 【map文件】 对固件里面的变量、函数、常量等元素的存储空间进行分配的说明…...

go clean

移除目标文件和缓存文件。 更多信息&#xff1a;https://golang.org/cmd/go/#hdr-Remove_object_files_and_cached_files. 只打印移除命令&#xff0c;而不会真正移除任何东西&#xff1a; go clean -n 删除编译缓存&#xff1a; go clean -cache 删除所有测试结果缓存&…...

BUUCTF [ACTF新生赛2020]swp 1

BUUCTF:https://buuoj.cn/challenges 题目描述&#xff1a; 得到的 flag 请包上 flag{} 提交。 密文&#xff1a; 下载附件&#xff0c;得到一个.tar文件。 解题思路&#xff1a; 1、使用WinRAR解压.tar文件&#xff0c;得到两个.zip文件。 解压wget.zip文件&#xff0c;得…...

【PTA题目】7-4 缩写期刊名 分数 10

7-4 缩写期刊名 分数 10 全屏浏览题目 切换布局 作者 黄龙军 单位 绍兴文理学院 科研工作者经常要向不同的期刊投稿。但不同期刊的参考文献的格式往往各不相同。有些期刊要求参考文献所发表的期刊名必须采用缩写形式&#xff0c;否则直接拒稿。现对于给定的期刊名&#xff…...

什么是 TLS/SSL 握手

TLS/SSL 握手是一个加密过程&#xff0c;每当客户端&#xff08;如浏览器&#xff09;与服务器建立连接时&#xff0c;都会在后台进行&#xff0c;此握手协议有助于客户端和服务器之间的安全连接&#xff0c;从而促进隐私、数据完整性和机密性。 TLS/SSL 握手何时发生 每当客…...

和鲸科技与国科环宇建立战略合作伙伴关系,以软硬件一体化解决方案促进科技创新

近日&#xff0c;在国科环宇土星云算力服务器产品发布会暨合作伙伴年度会上&#xff0c;和鲸科技与国科环宇正式完成战略伙伴签约仪式&#xff0c;宣布达成战略合作伙伴关系。未来&#xff0c;双方将深化合作&#xff0c;充分发挥在产品和市场方面的互补优势&#xff0c;为企事…...

[C++]六大默认成员函数详解

☃️个人主页&#xff1a;fighting小泽 &#x1f338;作者简介&#xff1a;目前正在学习C和Linux &#x1f33c;博客专栏&#xff1a;C入门 &#x1f3f5;️欢迎关注&#xff1a;评论&#x1f44a;&#x1f3fb;点赞&#x1f44d;&#x1f3fb;留言&#x1f4aa;&#x1f3fb; …...

组合(回溯算法)

77. 组合 - 力扣&#xff08;LeetCode&#xff09; 题目描述 给定两个整数 n 和 k&#xff0c;返回范围 [1, n] 中所有可能的 k 个数的组合。 你可以按 任何顺序 返回答案。 样例输入 示例 1&#xff1a; 输入&#xff1a;n 4, k 2 输出&#xff1a; [[2,4],[3,4],[2,3],…...

力扣:1419. 数青蛙

题目&#xff1a; 代码&#xff1a; class Solution { public:int minNumberOfFrogs(string croakOfFrogs){string s "croak";int ns.size();//首先创建一个哈希表来标明每个元素出现的次数&#xff01;vector<int>hash(n); //不用真的创建一个hash表用一个数…...

java_springboot企业人事考勤请假管理信息系统rsglxx+jsp

&#xff08;1&#xff09;熟练掌握Java开发的原理和方法 &#xff08;2&#xff09;熟练学习掌握SSM框架 &#xff08;3&#xff09;熟悉软件开发的流程 &#xff08;4&#xff09;了解中内外互联网中所主流的技术 &#xff08;5&#xff09;深层次的了解计算机学科领域的知识…...

java项目之木里风景文化管理平台(ssm+vue)

项目简介 木里风景文化管理平台实现了以下功能&#xff1a; 前台功能&#xff1a;用户进入系统可以实现首页&#xff0c;旅游公告&#xff0c;景区&#xff0c;景区商品&#xff0c;景区美食&#xff0c;旅游交通工具&#xff0c;红黑榜&#xff0c;个人中心&#xff0c;后台…...

源码安装mysql

使用源码安装mysql&#xff0c;这里选择的版本是mysql5.7.35 ,系统是Centos7.6 官网下载地址&#xff1a;https://downloads.mysql.com/archives/community/ 下载源码压缩包 [rootlocalhost ~]# cd /opt[rootlocalhost opt]# wget https://downloads.mysql.com/archives/get/…...

注解方式优雅的实现Redisson分布式锁

1.前言 随着微服务的快速推进&#xff0c;分布式架构也得到蓬勃的发展&#xff0c;那么如何保证多进程之间的并发则成为需要考虑的问题。因为服务是分布式部署模式&#xff0c;本地锁Reentrantlock和Synchnorized就无法使用了&#xff0c;当然很多同学脱口而出的基于Redis的se…...

服务器安装JDK17 版本显示JDK8

服务器之前安装的是JDK8&#xff0c;后面升级JDK17后&#xff0c;发现执行 java -vsrsion 显示的是此时我的环境变量已经换成了JAVA17的路径 输入&#xff1a; vim /etc/profile 解决办法&#xff1a; 1.更新自己环境变量 bash export JAVA_HOME/usr/local/jdk-17.0.7 …...

利用MCMC 获得泊松分布

写出概率流方程如下 if state 0: if np.random.random() < min([Lambda/2, 1]):state 1else:passelif state 1:if choose_prob_state[i] < 0.5:#选择 1 -> 0&#xff0c;此时的接受概率为min[2/Lambda, 1]if np.random.random() < min([2/Lambda, 1]…...