open3d实现搜索在一个球内部的点云

目录

  • 写在前面
  • 原理
  • 代码
  • 结果
  • 参考

写在前面

1、本文内容
给定一个点云P和一个圆心为center,半径为r的球,搜索出P中属于球内的点

2、平台/环境
使用open3d, cmake,适用windows/linux
3、转载请注明出处:
https://blog.csdn.net/qq_41102371/article/details/131666033

原理

利用open3d的kdtree,以点云P建立kdtree,对给定点进行进行半径搜索,在搜索之前先用边长=2*radius的box裁剪以加速搜索

代码

目录结构如下,请将sphere_search.cpp和CMakeLists.txt放入src
在这里插入图片描述
sphere_search.cpp

#include <iostream>
#include <chrono>#include <open3d/Open3D.h>std::shared_ptr<open3d::geometry::PointCloud> PointInSphere(std::shared_ptr<open3d::geometry::PointCloud> pcd, Eigen::Vector3d center, double radius, bool vis)
{auto search_s = std::chrono::high_resolution_clock::now();std::shared_ptr<open3d::geometry::PointCloud> points_in_sphere(new open3d::geometry::PointCloud);if (nullptr == pcd || pcd->IsEmpty()){*points_in_sphere = *pcd;return points_in_sphere;}std::cout << "point size: " << pcd->points_.size() << " search center: " << center.transpose() << " search radius: " << radius << std::endl;if (radius <= 0.0){*points_in_sphere = *pcd;return points_in_sphere;}// 先用边长等于2*radius的正方体裁剪,得到更少的点云,然后再搜索更快open3d::geometry::OrientedBoundingBox obb;obb.center_ = center;obb.extent_ = Eigen::Vector3d(radius * 2, radius * 2, radius * 2);std::vector<std::size_t> idx_crop = obb.GetPointIndicesWithinBoundingBox(pcd->points_);auto pcd_crop = pcd->SelectByIndex(idx_crop);auto crop_e = std::chrono::high_resolution_clock::now();auto crop_cost = std::chrono::duration_cast<std::chrono::microseconds>(crop_e - search_s).count() / 1000.0;std::cout << "crop_cost: " << crop_cost << " ms" << std::endl;open3d::geometry::KDTreeFlann target_kdtree;target_kdtree.SetGeometry(*pcd_crop);std::vector<int> indices;std::vector<double> dis;target_kdtree.SearchRadius(center, radius, indices, dis);if (indices.empty()){std::cout << "no point in sphere, please check your center or radius" << std::endl;return points_in_sphere;}else{std::cout << indices.size() << " pints searched in pcd" << std::endl;}// std::vector<int>转std::vector<std::size_t>std::vector<std::size_t> idx_in_sphere;for (auto i : indices){idx_in_sphere.push_back(i);}points_in_sphere = pcd_crop->SelectByIndex(idx_in_sphere);auto search_e = std::chrono::high_resolution_clock::now();auto search_cost = std::chrono::duration_cast<std::chrono::microseconds>(search_e - search_s).count() / 1000.0;std::cout << "total cost: " << search_cost << " ms" << std::endl;if (vis){auto coordinate = open3d::geometry::TriangleMesh::CreateCoordinateFrame(1.0);auto pcd_remain = pcd->SelectByIndex(idx_crop, true);auto pcd_inbox_remain = pcd_crop->SelectByIndex(idx_in_sphere, true);// pcd_remain->PaintUniformColor({1, 0, 0});pcd_inbox_remain->PaintUniformColor({0, 1, 0});points_in_sphere->PaintUniformColor({1, 1, 0});obb.color_ = Eigen::Vector3d(0, 0, 1);open3d::visualization::DrawGeometries({coordinate, pcd_remain, pcd_inbox_remain, points_in_sphere,std::make_shared<open3d::geometry::OrientedBoundingBox>(obb)}, "sphere search result");}return points_in_sphere;
}
int main(int argc, char *argv[])
{int idx = open3d::utility::GetProgramOptionAsInt(argc, argv, "--idx", 0);bool vis = open3d::utility::ProgramOptionExists(argc, argv, "--vis");double radius = open3d::utility::GetProgramOptionAsDouble(argc, argv, "--radius", 0);std::string path_pcd = open3d::utility::GetProgramOptionAsString(argc, argv, "--path_pcd", "");if (path_pcd.empty()){std::cout << "please input pcd path with --path_pcd" << std::endl;return 0;}std::shared_ptr<open3d::geometry::PointCloud> pcd(new open3d::geometry::PointCloud);open3d::io::ReadPointCloud(path_pcd, *pcd);std::cout << "read " << path_pcd << " with " << pcd->points_.size() << " points" << std::endl;// 使用索引以点云内某一点为圆心if (open3d::utility::ProgramOptionExists(argc, argv, "--idx")){PointInSphere(pcd, pcd->points_[idx], radius, true);}else{// 另外指定圆心PointInSphere(pcd, {0, 0, 0}, radius, vis);}return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.18)
project(SphereSearch)option(STATIC_WINDOWS_RUNTIME "Use static (MT/MTd) Windows runtime" ON)if(STATIC_WINDOWS_RUNTIME)set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
else()set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL")
endif()# set(Open3D_ROOT /root/open3D_install/) #linux
find_package(Open3D REQUIRED)
include_directories(${Open3D_INCLUDE_DIRS}
)add_executable(sphere_search ./sphere_search.cpp)
target_link_libraries(sphere_search ${Open3D_LIBRARIES})

compile.bat
请为替换自己的open3d目录,该目录包含open3d的cmake文件

cmake -DCMAKE_BUILD_TYPE=Release -DOpen3D_DIR="D:\carlos\install\open3d141\CMake" -S ./src -B ./build
cmake --build ./build --config Release --target ALL_BUILD

run.bat

.\build\Release\sphere_search.exe .\build\Release\sphere_search.exe --path_pcd D:\carlos\my_tools\data\bun000.pcd --radius 0.05 --vis --idx 0                                     

结果

黄色是搜索到的点云
在这里插入图片描述
在这里插入图片描述

参考

主要做激光/影像三维重建,配准、分割等常用点云算法,技术交流、咨询可私信

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【uniapp开发小程序】实现同声传译(长按语音转文字)

效果图&#xff1a; 插件&#xff1a; 采用小程序插件&#xff1a;微信同声传译。插件文档定位 具体步骤&#xff1a; 先登录小程序后台&#xff08;项目别错了&#xff09;&#xff1a;官网传送然后 设置 > 第三方设置 > 添加插件 在插件文档里面拿到Appid和版本号 在…

14-Vue插槽(slot),制作可复用组件

什么是 slot ? Vue 将 <slot>元素作为承载分发内容的出口。插槽内可以包含任何模板代码&#xff0c;包括 HTML或其它组件。 在某些组件的模板中&#xff0c;有一部分区域需要父组件来指定 <!-- message组件&#xff1a;一个弹窗消息 --> <div class"mes…

组合取球-2022年全国青少年信息素养大赛Python国赛第6题

[导读]&#xff1a;超平老师计划推出《全国青少年信息素养大赛Python编程真题解析》50讲&#xff0c;这是超平老师解读Python编程挑战赛真题系列的第8讲。 全国青少年信息素养大赛&#xff08;原全国青少年电子信息智能创新大赛&#xff09;是“世界机器人大会青少年机器人设计…

安全防御 --- DDOS攻击(01)

DOS攻击&#xff08;deny of service&#xff09;--- 拒绝式服务攻击 例&#xff1a;2016年10月21日&#xff0c;美国提供动态DNS服务的DynDNS遭到DDOS攻击&#xff0c;攻击导致许多使用DynDNS服务的网站遭遇访问问题&#xff0c;此事件中&#xff0c;黑客人就是运用了DNS洪水…

LinearAlgebraMIT_5_SpacesOfVectors

这一节中我们将学习向量空间。 x.1 转置矩阵和构造对称矩阵 在开启向量空间的学习前我们先复习一下转置矩阵和置换矩阵。我们将矩阵转置前后不变的矩阵称为对称矩阵。而我们如何得到一个对称矩阵呢&#xff0c;我们使用矩阵乘以矩阵的转置便可得到。 x.2 Vectors Space 向量…

如何执行Photoshop脚本

环境 Photoshop: CC2017 OS: Windows 10 脚本放置位置 C:\Program Files\Adobe\Adobe Photoshop CC 2015\Presets\Scripts #也就是 PS的安装目录\Presets\Scripts

探究Vue源码:mustache模板引擎(5) 对比rollup与webpack,在本地搭建webpack环境

好 从本文开始 我们就来手写一下mustache这个库 他是模板引擎的一个祖先 将模板字符串编译成一个dom字符串 就是它的思想&#xff0c;这也是一个具有跨时代意义的思想 这里的话 我们还是搭一个 webpack 的项目环境 这里值得一提的是 mustache 他官方是通过rollup来进行打包的 …

简述JMeter实现分布式并发及操作

为什么要分布式并发&#xff1f; JMeter性能实践过程中&#xff0c;一旦进行高并发操作时就会出现以下尴尬场景&#xff0c;JMeter客户端卡死、请求错误或是超时等&#xff0c;导致很难得出准确的性能测试结论。 目前知道的有两个方法可以解决JMeter支撑高并发&#xff1a; …

微信小程序学习之数据绑定,事件绑定,事件传参与数据同步的学习记录

数据绑定&#xff0c;事件绑定&#xff0c;事件传参与数据同步 1. 数据绑定1.1. 在data中定义数据1.2. 在wxml中渲染数据 &#xff08;mustache语法&#xff09; 2. 事件绑定2.1. 事件2.2. 常用的事件2.3. 事件对象的属性列表2.4. target 和 currentTarget的区别 3. 事件传参与…

订单结算页+下单业务

一、订单结算页 1.业务分析 (1) 获取用户收货地址信息 一般的收货地址都是多个&#xff0c;使用时选中一个&#xff0c;所以收货地址使用List集合封装 (2)获取购物车商品信息 购物车商品也是多个&#xff0c;使用List集合封装 (3)查询商品库存 查询每个商品是否有库存&#…

Scrap爬虫框架集成Selenium来解析动态网页

1、爬虫项目单独使用scrpay框架的不足 当前网站普遍采用了javascript 动态页面&#xff0c;特别是vue与react的普及&#xff0c;使用scrapy框架定位动态网页元素十分困难&#xff0c;而selenium是最流行的浏览器自动化工具&#xff0c;可以模拟浏览器来操作网页&#xff0c;解…

spring boot MySQL操作

极简spring boot MySQL测试 默认: spring boot环境已经搭好,可以跑最基本的hello world 有MySQL环境有部分测试数据表,并且有MySQL语法基础 配置 application.yml 如下配置,根据自己的数据库信息与个人需求配置 server: tomcat: uri-encoding: UTF-8 threads: …