大致思路:定义起始种子点后通过当前点k邻域搜索最邻近点,调整邻近点法线朝向与当前种子点法线朝向同向,然后传播出去。
具体实现:(1)用vector模拟两个栈points和normals,存放点云的点和法线。首先将初始种子点压入这两个栈。
(2)设置一个和点云点数相同大小的flags用来标记点云中的点是否被生长过,并将初始种子点的标志位置为true。
(3)建立点云的kd树。
(4)分别从points和normals弹出最后一个值作为当前种子点,计算该点对应的法线,并求出其k邻域点。
(5)遍历该点的k邻域点,若该点未被标记过,判断该点与当前种子点法线朝向是否同向,如果反向则翻转法线方向。将该点压入栈中并将该点的标志位置为true。
(6)返回(4),直到栈为空。

/**
* @brief normal_flip   法线方向翻转
* @param cloud         点云
* @param cloud_normals 点云法线
* @param seed_index    种子点索引
*/
void normal_flip(pcl::PointCloud<pcl::PointXYZ>::Ptr& cloud, pcl::PointCloud<pcl::Normal>::Ptr& cloud_normals, int seed_index)
{std::vector<pcl::PointXYZ> points;std::vector<pcl::Normal> normals;points.push_back(cloud->points[seed_index]);normals.push_back(cloud_normals->points[seed_index]);std::vector<bool> flags(cloud->size(), false);   //用来标记点云中的点是否被生长过flags[seed_index] = true;pcl::KdTreeFLANN<pcl::PointXYZ> kdtree;kdtree.setInputCloud(cloud);int K = 20;std::vector<int> pointsIdx(K);          //索引std::vector<float> pointsDistance(K);   //距离while (!normals.empty()){pcl::PointXYZ seed_point = points.back();   //种子点pcl::Normal seed_normal = normals.back();   //种子点法线points.pop_back();normals.pop_back();kdtree.nearestKSearch(seed_point, K, pointsIdx, pointsDistance);    //k近邻搜索Eigen::Vector3f v1(seed_normal.normal_x, seed_normal.normal_y, seed_normal.normal_z);for (size_t i = 0; i < pointsIdx.size(); i++){if (!flags[pointsIdx[i]])   //如果该点没有被生长到{Eigen::Vector3f   v2(cloud_normals->points[pointsIdx[i]].normal_x,cloud_normals->points[pointsIdx[i]].normal_y,cloud_normals->points[pointsIdx[i]].normal_z);if (v1.dot(v2) < 0) //如果该点法线方向与种子点法线方向相反(夹角为钝角),则翻转法线方向{cloud_normals->points[pointsIdx[i]].normal_x *= -1;cloud_normals->points[pointsIdx[i]].normal_y *= -1;cloud_normals->points[pointsIdx[i]].normal_z *= -1;}points.push_back(cloud->points[pointsIdx[i]]);normals.push_back(cloud_normals->points[pointsIdx[i]]);flags[pointsIdx[i]] = true;    //标记该点已经被生长过}}}//std::vector<int> indexs;//for (size_t i = 0; i < flags.size(); ++i)//{//  if (flags[i])//     indexs.push_back(i);//}//pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_flag(new pcl::PointCloud<pcl::PointXYZ>);//pcl::copyPointCloud(*cloud, indexs, *cloud_flag);//pcl::io::savePCDFile("cloud_flag.pcd", *cloud_flag);
}

效果展示:
pcl法线提取结果(法线朝向有内有外)

统一法线方向结果(法线朝向都朝外侧)

参考:无序点云的法线全局定向

点云统一法线方向(未知视点)相关推荐

  1. pcl点云特征提取 法线估计 PFH FPFH NARF 惯量偏心矩 RoPs特征 视点特征直方图VFH GASD特征

    pcl点云特征提取 法线估计 PFH FPFH NARF 惯量偏心矩  RoPs特征  视点特征直方图VFH GASD特征 博文末尾支持二维码赞赏哦 _ 如果要对一个三维点云进行描述,光有点云的位置是 ...

  2. Open3d之点云顶点法线估计

    代码展示 # -*-coding:utf-8 -*- import os import open3d as o3d import numpy as nptest_data_dir = '/home/p ...

  3. 技术实力加速企业上云,联想混合云获评专有云优秀案例入选混合云全景图四大方向

    7月25-26日,由中国信息通信研究院.中国通信标准化协会联合主办的第十届可信云大会在京顺利召开.大会重磅发布了云计算白皮书(2023年).<混合云产业全景图(2023)>.中国算力服务研 ...

  4. 【点云重采样Resampling】Python-pcl 基于多项式平滑点云及法线估计的曲面重建

    1. 点云重采样 基于多项式平滑点云及法线估计的曲面重建以实现重采样,可以使得点云数据更规整一些,没之前那么杂乱. set_Compute_Normals(True) 可以通过在最小二乘法中进行法线估 ...

  5. 与容器服务 ACK 发行版的深度对话第二弹:如何借助 hybridnet 构建混合云统一网络平面

    作者:若禾.昱晟.瑜佳 记者: 各位阿里巴巴云原生的读者朋友们大家好,欢迎再次来到探究身世之谜系列专访栏目,今天邀请来的还是大家的老朋友,『阿里云容器服务 ACK 发行版』,上次的访谈中它为我们介绍了 ...

  6. 多边形的时针方向与法线方向

    从相反的法线方向观察,顺时针还是逆时针是相反的. 多边形的时针方向与法线方向的关系呈右手法则关系. GoogleEarth中的面具有时针方向,法线方向为正向,反之为负向 GoogleEarth的垂面在 ...

  7. 等分曲线轮廓,法线方向矩形

    利用Halcon均匀分割曲线,并标记法线方向. 原始图片: 处理效果如下所示: 代码: read_image (Image, 'C:/Users/Sawyer/Desktop/13_36559_e7f ...

  8. 如何沿法线方向挤出面

    本文基于Blender 2.8 正式版 在面的编辑模式下,假设我们选择了一些像下面这样曲度比较复杂的面 我们尝试着用普通的挤出命令E把它们挤出,就出现了下面的结果 一般来说这不会是我们想要的结果.实际 ...

  9. 科力锐助力政务云统一灾备中心建设

    一.政务云建设趋势 随着我国政府向公共服务型政府转型,政府对民生问题的重视不断加强,通过搭建政务云,对政府管理和服务职能进行精简.优化.整合,并通过信息化手段在政务上实现各种业务流程办理和职能服务,经 ...

  10. 蓝鲸智云统一开发环境搭建指南

    腾讯官方的<蓝鲸智云统一开发环境搭建指南> 蓝鲸应用统一开发环境指南 一:背景 蓝鲸应用开发需要依赖django,celery,mysql-client等第三方库,而像celery又依赖其 ...

最新文章

  1. vim切换编程语言_把 Vim 打造成源代码编辑器 - C 语言编程透视
  2. 【Web安全】XSS简介与XSS测试平台截取用户COOKIE的探索
  3. word中格式化姓名的输出
  4. 如何让ios app支持32位和64位?
  5. 【Trie】最长异或路径(ybtoj Trie-3/luogu 4551)
  6. Bootstrap HTML编码规范之减少标签的数量
  7. 基于Jenkins + Tomcat 的安卓客户端可持续化构建及发布下载(loltube.cn)
  8. Scrum Meeting---Ten(2015-11-5)
  9. git 合并其他分支代码到自己的分支
  10. 《剑指offer》面试题——把数组排成最小的数
  11. android 扫描照片功能,巧把安卓手机打造成扫描仪:拍照识别文档、手写笔记转PDF(图)...
  12. 使用js一行代码解决上网培训弹窗问题
  13. Qt Creator 安装 VLD
  14. 雷电模拟器通过命令行设置分辨率及其他命令
  15. JQuery中append(function(index,html)),appendTo(),after(function(index,html)),clone()方法
  16. android 清空画布内容,Android,canvas:如何清除(删除)位于surfaceView中的画布(=位图)的内容?...
  17. android 开发机型差异性
  18. 互联网大会蓝皮书_世界互联网大会蓝皮书
  19. JNI程序开发入门之高端大气上档次的Hello World
  20. python爬取ajax动态内容肯德基门店_爬虫爬取国内肯德基门店信息

热门文章

  1. JNI便捷开发框架JNA框架之指针参数Pointer(二)
  2. 对应的服务器证书无效。控制台输入 showRequestInfo() 可以获取更详细信息
  3. python爬取链家二手房信息并存储到数据库
  4. 新华社痛批铁道部封抢票软件:自己傻就怨别人太聪明
  5. 会话技术——Cookie
  6. 麦吉尔大学计算机科学申请,加拿大麦吉尔大学计算机科学硕士成功案例分享
  7. window10去掉快捷方式小箭头
  8. VOT数据集自动/手动下载
  9. 大屏可视化解决方案:公安大数据平台建设
  10. python图形包是什么_介绍Python 图形计算工具包