学习记录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;
}

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

相关推荐
海绵波波1073 分钟前
Webserver(4.9)本地套接字的通信
c++
@小博的博客9 分钟前
C++初阶学习第十弹——深入讲解vector的迭代器失效
数据结构·c++·学习
爱吃喵的鲤鱼1 小时前
linux进程的状态之环境变量
linux·运维·服务器·开发语言·c++
7年老菜鸡2 小时前
策略模式(C++)三分钟读懂
c++·qt·策略模式
Ni-Guvara2 小时前
函数对象笔记
c++·算法
似霰2 小时前
安卓智能指针sp、wp、RefBase浅析
android·c++·binder
芊寻(嵌入式)2 小时前
C转C++学习笔记--基础知识摘录总结
开发语言·c++·笔记·学习
獨枭2 小时前
C++ 项目中使用 .dll 和 .def 文件的操作指南
c++
霁月风2 小时前
设计模式——观察者模式
c++·观察者模式·设计模式
橘色的喵2 小时前
C++编程:避免因编译优化引发的多线程死锁问题
c++·多线程·memory·死锁·内存屏障·内存栅栏·memory barrier