学习记录PCL-1 通过哈希表进行三维点云的虚拟格网划分

直接对整个场景的点云进行特征提取,效果很差,因此通过划分区域格网进行划分。格网划分有很多种方式,在这里尝试使用哈希表进行格网链接,后续通过在每个格网内基于点云特征进行提取。

参考博客:

点云侠的PCL 点云分块_pcl 点云按网格分块_点云侠的博客-CSDN博客

点云学徒的PCL点云处理之创建二维格网组织点云数据(六十四)_哈希表 c++ pcl 点云_点云学徒的博客-CSDN博客

使用了c++的哈希表代替了的qt库中哈希表

代码如下:

cpp 复制代码
#include <iostream>
#include <fstream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/common/pca.h>
#include <pcl/common/common.h>
#include <unordered_map>
#include <list>
#include <functional>
#include <cstdlib>
#include <pcl/point_cloud.h>



using namespace std;
using namespace Eigen;

int main(int argc, char** argv) {
    // 定义点云容器
    pcl::PointCloud<pcl::PointXYZI>::Ptr PC(new pcl::PointCloud<pcl::PointXYZI>);  // 原始点云容器

    // 读入原始点云
    if (pcl::io::loadPCDFile<pcl::PointXYZI>("iScan.pcd", *PC) == -1) {
        cout << "打开失败" << endl;
        return false;
    }

    // 根据原始点云坐标最值创建格网
    pcl::PointXYZI minPt, maxPt;  // 存储点云最值
    int RowNum = 2;               // 格网的行数
    int ColNum = 2;               // 格网的列数

    pcl::getMinMax3D(*PC, minPt, maxPt);

    cout << " 格网创建完成 " << endl;

    // 哈希表存储点云
    unordered_map<unsigned int, pcl::PointCloud<pcl::PointXYZI>> Point2dHash;  // 存放点云的二维哈希表
    list<unsigned int> no_empty_List;                                          // 判断二维格网内部是否有点的链表 将有点格网对应的哈希号存储进去
    int row, col;                                                               // 点云对应的格网行、列号
    size_t TempIndex;                                                           // 哈希键  意思就是将二维索引变成一维索引

    for (size_t Index = 0; Index < PC->points.size(); Index++) {
        // 计算点云所在的行、列
        row = int(RowNum * (PC->points[Index].x - minPt.x) / (maxPt.x - minPt.x));
        col = int(ColNum * (PC->points[Index].y - minPt.y) / (maxPt.y - minPt.y));

        // 防止越界
        row = max(0, min(row, RowNum - 1));
        col = max(0, min(col, ColNum - 1));

        TempIndex = row * ColNum + col;

        if (find(no_empty_List.begin(), no_empty_List.end(), TempIndex) == no_empty_List.end()) {
            no_empty_List.push_back(TempIndex);
        }

        Point2dHash[TempIndex].push_back(PC->points[Index]);
    }

    cout << " 哈希表完成 " << endl;

    // 显示每个格网内的点云数量
    for (const auto& entry : no_empty_List)
    {
        size_t count = Point2dHash[entry].size();
        cout << "Grid[" << entry << "] has " << count << " points." << endl;
    }

    // 将每个格网内的点云合并保存为新的点云文件
    pcl::PointCloud<pcl::PointXYZI>::Ptr resultCloud(new pcl::PointCloud<pcl::PointXYZI>);
    for (const auto& entry : no_empty_List) {
        if (!Point2dHash[entry].empty()) {
            *resultCloud += Point2dHash[entry];
        }
    }


    // 将每个格网内的点云合并保存为新的点云文件 pcd格式有坐标偏移的现状
    pcl::PCDWriter writer;

    string base_path = "G:\\test\\";  // 指定基本路径

    for (const auto& entry : no_empty_List) {
        if (!Point2dHash[entry].empty()) {
            string file_path = base_path + "result_cloud_grid_" + to_string(entry) + ".pcd";

          
          writer.write<pcl::PointXYZI>(file_path, Point2dHash[entry], true);
          

            cout << "Grid[" << entry << "] saved to " << file_path << endl;
        }
    }


  


    return 0;
}

​​​​​运行结果如下:

相关推荐
WG_174 分钟前
C++多态
开发语言·c++·面试
ahauedu1 小时前
案例分析-Stream List 中取出值最大的前 5 个和最小的 5 个值
数据结构·list
Charles Ray2 小时前
C++学习笔记 —— 内存分配 new
c++·笔记·学习
重生之我在20年代敲代码2 小时前
strncpy函数的使用和模拟实现
c语言·开发语言·c++·经验分享·笔记
X同学的开始3 小时前
数据结构之二叉树遍历
数据结构
AIAdvocate6 小时前
Pandas_数据结构详解
数据结构·python·pandas
jiao000016 小时前
数据结构——队列
c语言·数据结构·算法
kaneki_lh6 小时前
数据结构 - 栈
数据结构
铁匠匠匠6 小时前
从零开始学数据结构系列之第六章《排序简介》
c语言·数据结构·经验分享·笔记·学习·开源·课程设计
C-SDN花园GGbond6 小时前
【探索数据结构与算法】插入排序:原理、实现与分析(图文详解)
c语言·开发语言·数据结构·排序算法