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

PCL分割——法向量差分分割

Difference of Normals Based Segmentation

该算法基于一个点在不同大小邻域所得到的两个法向量的插值为依据对点进行分割。该方法计算效率高,并且对于大规模的无组织点云数据具有很好的效果。

算法流程

1️⃣ 使用较大的支持半径 (r_l),为点云中的每一个点估计法向量
2️⃣ 使用较小的支持半径 (r_s),再次为点云中的每一个点估计法向量
3️⃣ 对每一个点计算法向量的归一化差值
4️⃣ 对得到的向量场进行滤波,从而提取出属于目标尺度 / 感兴趣区域的点


  1. 算法要求要求必须使用半径搜索去计算点的法向量
  2. 滤波算法(可以使用条件滤波)需要基于我们得到的DON来进行选择,可以从以下数据中进行滤波条件的设定。
  3. 基于DON进行滤波后,还需要对滤波后的点云数据进行分割,才算完整整个流程。
过滤量(Quantity) PointNormal 字段 数值范围 含义说明 典型使用场景
DoN 向量 \(\Delta \hat{n}(p, r_s, r_l)\) normal[3] ([-1, 1]) 小尺度与大尺度法向量的差向量 DoN 方向 / 角度 过滤(方向敏感任务)
DoN 模长(L2 范数) (\(|\Delta \hat{n}|\)) curvature ((0, 1)) DoN 响应强度,衡量该点在给定尺度下的几何变化程度 尺度分割首选(与方向无关)
DoN x 分量 (\(\Delta \hat{n}_x\)) normal[0] ((-1, 1)) DoN 在 x 方向的分量 定向尺度过滤(如建筑立面)
DoN y 分量 (\(\Delta \hat{n}_y\)) normal[1] ((-1, 1)) DoN 在 y 方向的分量 定向尺度过滤
DoN z 分量 (\(\Delta \hat{n}_z\)) normal[2] ((-1, 1)) DoN 在 z 方向的分量 地面 / 屋顶 / 垂直结构区分
使用示例
int main()
{// Compute normals using both small and large scales at each pointpcl::NormalEstimationOMP<PointXYZRGB, PointNormal> ne;ne.setInputCloud (cloud);ne.setSearchMethod (tree);/*** NOTE: setting viewpoint is very important, so that we can ensure* normals are all pointed in the same direction!*/ne.setViewPoint (std::numeric_limits<float>::max (), std::numeric_limits<float>::max (), std::numeric_limits<float>::max ());// calculate normals with the small scalestd::cout << "Calculating normals for scale..." << scale1 << std::endl;pcl::PointCloud<PointNormal>::Ptr normals_small_scale (new pcl::PointCloud<PointNormal>);ne.setRadiusSearch (scale1);ne.compute (*normals_small_scale);// calculate normals with the large scalestd::cout << "Calculating normals for scale..." << scale2 << std::endl;pcl::PointCloud<PointNormal>::Ptr normals_large_scale (new pcl::PointCloud<PointNormal>);ne.setRadiusSearch (scale2);ne.compute (*normals_large_scale);// Create output cloud for DoN resultsPointCloud<PointNormal>::Ptr doncloud (new pcl::PointCloud<PointNormal>);copyPointCloud (*cloud, *doncloud);std::cout << "Calculating DoN... " << std::endl;// Create DoN operatorpcl::DifferenceOfNormalsEstimation<PointXYZRGB, PointNormal, PointNormal> don;don.setInputCloud (cloud);don.setNormalScaleLarge (normals_large_scale);don.setNormalScaleSmall (normals_small_scale);if (!don.initCompute ()){std::cerr << "Error: Could not initialize DoN feature operator" << std::endl;exit (EXIT_FAILURE);}// Compute DoNdon.computeFeature (*doncloud);// Save DoN featurespcl::PCDWriter writer;writer.write<pcl::PointNormal> ("don.pcd", *doncloud, false); // Filter by magnitudestd::cout << "Filtering out DoN mag <= " << threshold << "..." << std::endl;// Build the condition for filteringpcl::ConditionOr<PointNormal>::Ptr range_cond (new pcl::ConditionOr<PointNormal> ());range_cond->addComparison (pcl::FieldComparison<PointNormal>::ConstPtr (new pcl::FieldComparison<PointNormal> ("curvature", pcl::ComparisonOps::GT, threshold)));// Build the filterpcl::ConditionalRemoval<PointNormal> condrem;condrem.setCondition (range_cond);condrem.setInputCloud (doncloud);pcl::PointCloud<PointNormal>::Ptr doncloud_filtered (new pcl::PointCloud<PointNormal>);// Apply filtercondrem.filter (*doncloud_filtered);doncloud = doncloud_filtered;// Save filtered outputstd::cout << "Filtered Pointcloud: " << doncloud->size () << " data points." << std::endl;writer.write<pcl::PointNormal> ("don_filtered.pcd", *doncloud, false); // Filter by magnitudestd::cout << "Clustering using EuclideanClusterExtraction with tolerance <= " << segradius << "..." << std::endl;pcl::search::KdTree<PointNormal>::Ptr segtree (new pcl::search::KdTree<PointNormal>);segtree->setInputCloud (doncloud);std::vector<pcl::PointIndices> cluster_indices;pcl::EuclideanClusterExtraction<PointNormal> ec;ec.setClusterTolerance (segradius);ec.setMinClusterSize (50);ec.setMaxClusterSize (100000);ec.setSearchMethod (segtree);ec.setInputCloud (doncloud);ec.extract (cluster_indices);}

该算法在PCL没有直接封装,需要按照上面的流程进行处理。
PCL中的copyPointCloud是按照字段的名称实现拷贝,只会拷贝两个类型中的交集字段的数据。
此外,由于我们需要计算两组法向量并计算差分。因此在估计法向量是千万要记住设置视点的方向,让法向量朝向我们的视点方向。,保证前后两次计算的一致性。具体设置在哪里应该是随意的,但一定要选一个视点

http://www.gsyq.cn/news/104113.html

相关文章:

  • 亚马逊格局巨变!AI 助手重构购物逻辑,卖家如何顺势突围?
  • AutoGPT能否自动生成架构图?系统设计文档辅助
  • 北京市继承律师权威指南:2025-2026口碑评价与全场景解决方案推荐 - 老周说教育
  • 2025年紫外线消毒器品牌排名:紫外线消毒器哪家品牌的易用性 - mypinpai
  • 如何找代码bug
  • 基于单片机的智能家居燃气检测系统设计与技术实现
  • 从模拟到AI集成:图像采集卡的技术演进与未来三大趋势
  • AutoGPT能否接入网易邮箱?邮件协议调用示例
  • ComfyUI工作流中嵌入vLLM节点,动态批处理提速
  • 27、Docker 应用场景:Galera 集群负载均衡与 Spark 集群搭建
  • 固态断路器技术现状、应用场景与核心挑战
  • 17、Docker不同操作系统及工具使用指南
  • 打造专属AI助手:LobeChat角色预设配置完全手册
  • 2025年变压器回收公司排行榜,保兴顺达的售后服务完善吗? - mypinpai
  • 创建线程的五种写法
  • LobeChat与Next.js的完美结合:现代Web框架赋能AI前端开发
  • 豆包AI手机遭遇全网围剿:背后藏着什么行业秘密?
  • AutoGPT能否编写Python脚本?编程能力全面评测
  • 2025年X衍射仪售后哪家好?国产仪器权威推荐+优质厂家测评+品牌口碑榜 - 品牌推荐大师1
  • 2025年下半年AI应用架构演进:从RAG到Agent再到MCP的生态跃迁
  • ChatGPT-5.2:人工智能如何走进千家万户,改变我们的每一天
  • 网络语言系列php系列【仅供参考】:PHP Exception::getMessage 和 Exception:: getLine有什么区别
  • FAQ12118:关于修改底色为白色后,设置中菜单字体显示为灰色字体问题(白底黑字)
  • Hoppscotch批量编辑完全指南:从基础到精通的高效参数管理
  • 基控电箱是什么?功能、选型与应用全指南
  • 达尔文12号在哪买:权威榜单与专业选购指南 - 品牌测评家
  • 开源AI新宠LobeChat:支持多模型切换的聊天界面解决方案
  • 自动化工程:赋能产业升级的核心引擎,从原理到应用全解析
  • 5、编程中的函数、参数传递与数组应用
  • 光刻胶增感剂用4-羟基二苯基碘鎓盐