简单平面点云的内外侧轮廓提取
原点云如图所示:
外侧轮廓提取用的方法是经纬线扫描法,全轮廓提取的方法是alpha shapes算法(点云边界提取方法总结),从全轮廓中剔除外侧轮廓得到内侧轮廓。
alpha shapes算法轮廓提取结果:
经纬线扫描法轮廓提取结果:
内侧轮廓:
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/surface/concave_hull.h>void BoundaryExtraction1(const pcl::PointCloud<pcl::PointXYZ>::Ptr& cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr& cloud_boundary, int resolution)
{pcl::PointXYZ px_min = *std::min_element(cloud->begin(), cloud->end(), [](pcl::PointXYZ pt1, pcl::PointXYZ pt2) {return pt1.x < pt2.x; });pcl::PointXYZ px_max = *std::max_element(cloud->begin(), cloud->end(), [](pcl::PointXYZ pt1, pcl::PointXYZ pt2) {return pt1.x < pt2.x; });float delta_x = (px_max.x - px_min.x) / resolution;float min_y = INT_MAX, max_y = -INT_MAX;std::vector<int> indexs_x(2 * resolution);std::vector<std::pair<float, float>> minmax_x(resolution, { INT_MAX,-INT_MAX });for (size_t i = 0; i < cloud->size(); ++i){int id = (cloud->points[i].x - px_min.x) / delta_x;if (cloud->points[i].y < minmax_x[id].first){minmax_x[id].first = cloud->points[i].y;indexs_x[id] = i;}else if (cloud->points[i].y > minmax_x[id].second){minmax_x[id].second = cloud->points[i].y;indexs_x[id + resolution] = i;}}pcl::PointXYZ py_min = *std::min_element(cloud->begin(), cloud->end(), [](pcl::PointXYZ pt1, pcl::PointXYZ pt2) {return pt1.y < pt2.y; });pcl::PointXYZ py_max = *std::max_element(cloud->begin(), cloud->end(), [](pcl::PointXYZ pt1, pcl::PointXYZ pt2) {return pt1.y < pt2.y; });float delta_y = (py_max.y - py_min.y) / resolution;float min_x = INT_MAX, max_x = -INT_MAX;std::vector<int> indexs_y(2 * resolution);std::vector<std::pair<float, float>> minmax_y(resolution, { INT_MAX,-INT_MAX });for (size_t i = 0; i < cloud->size(); ++i){int id = (cloud->points[i].y - py_min.y) / delta_y;if (cloud->points[i].x < minmax_y[id].first){minmax_y[id].first = cloud->points[i].x;indexs_y[id] = i;}else if (cloud->points[i].x > minmax_y[id].second){minmax_y[id].second = cloud->points[i].x;indexs_y[id + resolution] = i;}}pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_xboundary(new pcl::PointCloud<pcl::PointXYZ>);pcl::copyPointCloud(*cloud, indexs_x, *cloud_xboundary);pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_yboundary(new pcl::PointCloud<pcl::PointXYZ>);pcl::copyPointCloud(*cloud, indexs_y, *cloud_yboundary);*cloud_boundary = *cloud_xboundary + *cloud_yboundary;
}void BoundaryExtraction2(const pcl::PointCloud<pcl::PointXYZ>::Ptr& cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr& cloud_boundary, double alpha)
{pcl::ConcaveHull<pcl::PointXYZ> chull;chull.setInputCloud(cloud); chull.setAlpha(alpha); chull.reconstruct(*cloud_boundary);
}int main(int argc, char* argv[])
{pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_boundary1(new pcl::PointCloud<pcl::PointXYZ>);pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_boundary2(new pcl::PointCloud<pcl::PointXYZ>);pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_boundary3(new pcl::PointCloud<pcl::PointXYZ>);pcl::io::loadPCDFile("test.pcd", *cloud);BoundaryExtraction1(cloud, cloud_boundary1, 200); //经纬线扫描法pcl::io::savePCDFile("boundary1.pcd", *cloud_boundary1);BoundaryExtraction2(cloud, cloud_boundary2, 3); //alpha shapes算法pcl::io::savePCDFile("boundary2.pcd", *cloud_boundary2);//求cloud_boundary2-cloud_boundary1pcl::search::KdTree<pcl::PointXYZ>::Ptr kdtree(new pcl::search::KdTree<pcl::PointXYZ>);kdtree->setInputCloud(cloud_boundary1);std::vector<int> pointIdxRadiusSearch;std::vector<float> pointRadiusSquaredDistance;std::vector<int> indices;float radius = 3;for (size_t i = 0; i < cloud_boundary2->size(); i++){if (kdtree->radiusSearch(cloud_boundary2->points[i], radius, pointIdxRadiusSearch, pointRadiusSquaredDistance) > 0){indices.push_back(i);}}pcl::PointCloud<pcl::PointXYZ>::Ptr cloud3(new pcl::PointCloud<pcl::PointXYZ>);for (size_t i = 0; i < cloud_boundary2->size(); i++){if (find(indices.begin(), indices.end(), i) == indices.end())cloud_boundary3->push_back(cloud_boundary2->points[i]);}pcl::io::savePCDFile("boundary3.pcd", *cloud_boundary3);return EXIT_SUCCESS;
}
简单平面点云的内外侧轮廓提取相关推荐
- 概述—基于机载LiDAR点云数据的建筑物轮廓提取
一.机载LiDAR系统介绍 机载激光雷达测量技术的英文名称是LiDAR, LiDAR是英文Light Detection And Ranging(光探测与光测距)的缩写,是融合了 GPS.INS.激光 ...
- 基于MATLAB的点云建筑物轮廓提取与基于平面探测法的点云建筑物提取
博客中轮廓提取使用的点云数据 建筑物平面检测使用的点云数据 **两个小的点云处理实验项目,(源码资源****有常(注意目前是有常哦)私我vx:xdsqczkyqs713 ,第一个项目点云建筑物轮廓提取 ...
- 如何外网访问内网svn 网云穿内网穿透教你简单实现
在没有服务器,没有公网IP的情况下,我们如何才能实现在外网访问局域网内的svn服务器:这个问题对于大多部分人来说是个头疼的问题:那么我们怎么做才能做到低成本实现在外网成功访问内网的svn呢? 今天我们 ...
- PCL 三维点云轮廓提取
PCL 三维点云轮廓提取 建一个pclfive文件夹,建一个pclfive.cpp文档如下: #include <iostream> #include <pcl/range_imag ...
- 边缘检测、Hough变换、轮廓提取、种子填充、轮廓跟踪
转自:http://blog.sina.com.cn/s/blog_6c083cdd0100nm4s.html 7.1 边沿检测 我们给出一个模板 和一幅图象 .不难发现原图中左边暗,右边亮,中间存在 ...
- 基于深度学习的图像边缘和轮廓提取
点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 导读:边缘和轮廓的提取是一个非常棘手的工作,细节也许就会被过强的图 ...
- 使用Matlab对二值图像进行轮廓提取
转自:http://blog.csdn.net/q1302182594/article/details/50394576 本文主要总结一下在matlab中可用于进行轮廓提取的函数. 1 bwperim ...
- 《OpenCv视觉之眼》Python图像处理十二 :Opencv图像轮廓提取之基于一阶导数的Roberts算法、Prewitt算法及Sobel算法
本专栏主要介绍如果通过OpenCv-Python进行图像处理,通过原理理解OpenCv-Python的函数处理原型,在具体情况中,针对不同的图像进行不同等级的.不同方法的处理,以达到对图像进行去噪.锐 ...
- 边缘检测 Hough变换 轮廓提取 种子填充 轮廓跟踪
分享一下我老师大神的人工智能教程.零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow 转自:http:/ ...
最新文章
- 今日 Paper | 协作蒸馏;人脸反欺骗;人脸表示;3D-CariGAN等
- 网络管理员常见九大问题快速解决方法
- 【Python】随机划分数据集并生成VOC格式列表
- python中list是什么类型_Python 入门系列 —— 13. List 类型简介
- 《守墓人》主程:如何用像素风做出真实的游戏世界
- 火狐浏览器Firefox如何使用插件,火狐有哪些好用的插件
- 将win server 2003 AD域升级到win server 2012 R2
- 庆祝我的第一本书出版
- python 地理处理包:geopandas介绍
- 获取Nist的美国官方标准时间的解决办法
- vue结合elmentui实现前端分页
- WLAN与WiFi的区别和联系
- 对于 ACM程序设计选修课的感想
- 1.1UiPath下载安装与激活
- 理解LaaS、SaaS、PaaS的含义及区别
- 应用网易轻舟,德邦快递核心系统入选云原生应用十大优秀案例
- win10使计算机进入睡眠状态什么意思,win10如何进入睡眠模式 电脑睡眠模式设置教程...
- 获奖证书如何批量制作
- linux下无论什么命令都command not fount
- 同事关系再好也别表现,学做曾国藩和左宗棠,多数人不懂三规矩