首页 > 其他分享 >点云学习笔记17——PCL保存提取到的二维点云边界(即凸包边界)

点云学习笔记17——PCL保存提取到的二维点云边界(即凸包边界)

时间:2024-11-14 10:43:55浏览次数:3  
标签:边界 17 hull seg points pcl 点云 include cloud

#include <pcl/io/pcd_io.h>
#include <pcl/io/ply_io.h>
#include <pcl/point_types.h>
#include <pcl/features/normal_3d.h>
#include <pcl/filters/project_inliers.h>
#include <pcl/segmentation/sac_segmentation.h>
#include <pcl/surface/convex_hull.h>
#include <pcl/visualization/pcl_visualizer.h>

int main(int argc, char** argv) {
    // 读取点云文件
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
    std::string file_path = "F:\\convex.pcd";  // 替换为你的点云文件路径

    if (pcl::io::loadPCDFile<pcl::PointXYZ>(file_path, *cloud) == -1) {
        PCL_ERROR("Couldn't read PCD file \n");
        return (-1);
    }

    std::cout << "Loaded point cloud with " << cloud->points.size() << " points.\n";

    // 1. 使用RANSAC算法拟合最佳平面
    pcl::SACSegmentation<pcl::PointXYZ> seg;
    pcl::ModelCoefficients::Ptr coefficients(new pcl::ModelCoefficients);
    pcl::PointIndices::Ptr inliers(new pcl::PointIndices);

    // 设置RANSAC模型为平面模型
    seg.setModelType(pcl::SACMODEL_PLANE);
    seg.setMethodType(pcl::SAC_RANSAC);
    seg.setDistanceThreshold(0.001);  // 阈值,控制点到平面的最大距离
    seg.setInputCloud(cloud);
    seg.segment(*inliers, *coefficients);

    if (inliers->indices.size() == 0) {
        PCL_ERROR("Couldn't estimate a planar model for the given dataset.\n");
        return (-1);
    }

    std::cout << "Plane coefficients: "
        << coefficients->values[0] << " "
        << coefficients->values[1] << " "
        << coefficients->values[2] << " "
        << coefficients->values[3] << std::endl;

    // 2. 将点云投影到拟合的平面上
    pcl::PointCloud<pcl::PointXYZ>::Ptr projected_cloud(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::ProjectInliers<pcl::PointXYZ> proj;
    proj.setModelType(pcl::SACMODEL_PLANE);
    proj.setInputCloud(cloud);
    proj.setModelCoefficients(coefficients);
    proj.filter(*projected_cloud);

    std::cout << "Projected cloud size: " << projected_cloud->points.size() << std::endl;

    // 3. 使用凸包算法提取二维点云的凸多边形边界
    pcl::PointCloud<pcl::PointXYZ>::Ptr hull_points(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::ConvexHull<pcl::PointXYZ> chull;
    chull.setInputCloud(projected_cloud);
    chull.reconstruct(*hull_points);

    std::cout << "Convex hull points: " << hull_points->points.size() << std::endl;

    // 可视化原始点云、投影后的点云和凸包边界
    pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("Cloud Viewer"));
    //viewer->setBackgroundColor(0, 0, 0);
    //viewer->addPointCloud<pcl::PointXYZ>(cloud, "original cloud");
    //viewer->addPointCloud<pcl::PointXYZ>(projected_cloud, pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ>(projected_cloud, 0, 255, 0), "projected cloud");
    //viewer->addPointCloud<pcl::PointXYZ>(hull_points, pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ>(hull_points, 255, 0, 0), "hull cloud");

    // 连接凸包的点形成线条
    pcl::PointCloud<pcl::PointXYZ>::Ptr hull_lines(new pcl::PointCloud<pcl::PointXYZ>());
    for (size_t i = 0; i < hull_points->points.size(); ++i) {
        hull_lines->points.push_back(hull_points->points[i]);
    }

    // 4. 保存二维点云边界(凸包点云)到PCD文件
    pcl::io::savePCDFileASCII("F:\\convex_boundary1.pcd", *hull_lines);
    std::cout << "Saved convex hull points to 'convex_hull_boundary.pcd'." << std::endl;

    viewer->addPolygon<pcl::PointXYZ>(hull_lines, "convex hull");

    while (!viewer->wasStopped()) {
        viewer->spinOnce(100);
    }

    return 0;
}

标签:边界,17,hull,seg,points,pcl,点云,include,cloud
From: https://blog.csdn.net/qq_64095888/article/details/143761828

相关文章

  • more Layer Architecture in Python and postgreSQL17.0
    postgreSQLscript:createtableSchool--創建表(SchoolIdchar(5)NOTNULLPRIMARYKEY,SchoolNamevarchar(500)NOTNULLDEFAULT'',SchoolTelNovarchar(8)NULLDEFAULT'');model:#encoding:utf-8#版权所有20......
  • 打卡信奥刷题(225)用C++工具信奥P1760[普及组/提高] 通天之汉诺塔
    通天之汉诺塔题目背景直达通天路·小A历险记第四篇题目描述在你的帮助下,小A成功收集到了宝贵的数据,他终于来到了传说中连接通天路的通天山。但是这距离通天路仍然有一段距离,但是小A突然发现他没有地图!!!但是幸运的是,他在山脚下发现了一个宝箱。根据经验判断(小A有经......
  • 洛谷P1784.数独
    P1784数独思路这个题目最麻烦的是如何判断我们需要判断每一行,每一列,每一个九宫格这里有个小技巧,把每一行,每一列,每一个九宫格哪个数有没有被用过用数组存起来哪个数字属于哪个九宫格也可以先先存起来intid[10][10]={{0,0,0,0,0,0,0,0,0,0},{0,1,1,1,2,......
  • 代码随想录——二叉树17-路径总和
    这两道题目对于递归函数的返回值是不同的,这里进行总结,二叉树遍历中递归函数返回值何时有何时没有。这里总结如下三点:如果需要搜索整棵二叉树且不用处理递归返回值,递归函数就不要返回值。(这种情况就是路径总和ii)如果需要搜索整棵二叉树且需要处理递归返回值,递归函数就需......
  • 实验17:解释器模式
    本次实验属于模仿型实验,通过本次实验学生将掌握以下内容: 1、理解解释器模式的动机,掌握该模式的结构;2、能够利用解释器模式解决实际问题。 [实验任务一]:解释器模式某机器人控制程序包含一些简单的英文指令,其文法规则如下:expression::=directionactiondistance|compos......
  • 11.17
    [实验任务一]:双向适配器实现一个双向适配器,使得猫可以学狗叫,狗可以学猫抓老鼠。实验要求:画出对应的类图;提交源代码;packageadapter;//Cat接口interfaceCat{voidcry();voidcatchMouse();}//Dog接口interfaceDog{voidwang();voida......
  • Solution - Codeforces 1217E Sum Queries?
    对于这个“好的”的判定条件看起来有点奇怪,不妨结合上题目要求的“最小\(sum\)”一起考虑。因为要最小化\(s_p\),所以一个比较直观的想法是先从选的数个数入手。考虑到如果选的只有\(1\)个数\(a_i\),那么\(sum=a_i\),一定是好的,排除。如果选的是\(2\)个数\(a_i,a_j\),......
  • 点云学习笔记16——提取点云的边界,填充边界
    #include<iostream>#include<algorithm>#include<pcl/io/pcd_io.h>#include<pcl/point_types.h>#include<pcl/visualization/pcl_visualizer.h>voidBoundaryExtraction(pcl::PointCloud<pcl::PointXYZ>::Ptrcloud,pcl::Poi......
  • 题解:「2017 山东一轮集训 Day7」逆序对
    LibreOJ6077前置知识:生成函数、组合数先考虑平方怎么做。\(f_{i,j}\)表示处理了前\(i\)个值,逆序对有\(j\)个。显然可以转移到\(f_{i+1,j},f_{i+1,j+1},f_{i+1,j+2},...,f_{i+1,j+i}\)。然后发现这个东西是个很简单的递推,而且长得很生成函数,于是可以很自然的写成\[1\t......
  • 洛谷 P1772 [ZJOI2006] 物流运输 做题记录
    很神经的一道题。令\(val_{i,j}\)表示从第\(i\)天到第\(j\)天每天都走一条道路,单次的最小花费。可以枚举\(\{i,j\}\)然后把在这个区间里的所有点设置成不可达,每一个\(\{i,j\}\)都可以用floyd算,时间复杂度\(O(n^2m^3)\)。令\(f_i\)表示第\(i\)天的最小花费,那么......