点云归一化【C++\pcl】

点云归一化是将点云数据缩放到固定范围内的过程,通常是将点云数据缩放到一个单位立方体中。点云归一化的意义在于:

数据预处理:归一化可以将点云数据从原始的坐标系中转换到一个统一的坐标系中,从而方便后续的数据处理和分析。例如,可以将点云数据归一化到一个单位立方体中,以便进行模型的对齐和匹配。

提高数据精度:归一化可以提高点云数据的精度和稳定性。由于点云数据通常是由不同的传感器和设备采集而来,这些数据可能会存在不同的尺度和坐标系,这会影响数据的精度和可靠性。通过归一化,可以将点云数据转换到一个统一的坐标系中,从而提高数据的精度和稳定性。

加速计算:归一化可以减少计算量,提高计算效率。由于点云数据通常是非常庞大的,进行计算时需要消耗大量的计算资源。通过归一化,可以将点云数据缩放到一个单位立方体中,从而减少计算量,提高计算效率。

显示和可视化:归一化可以方便点云数据的显示和可视化。在点云数据的显示和可视化过程中,通常需要将点云数据转换到一个统一的坐标系中,以便进行显示和可视化。通过归一化,可以将点云数据缩放到一个单位立方体中,从而方便点云数据的显示和可视化。

#include <pcl/io/pcd_io.h>//PCL的PCD格式文件的输入输出头文件
#include <pcl/point_types.h>//PCL对各种格式的点的支持头文件
#include <pcl/common/common.h>	//getMinMax3D()函数所在头文件
#include <iostream>
#include <pcl/point_cloud.h>
#include <pcl/common/transforms.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <vector>
using namespace std;
struct Point {
    double x, y, z;
};
vector<Point> findMaxAndMin(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_in);
pcl::PointCloud<pcl::PointXYZ>::Ptr normialize(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_in, vector<Point> MaxAndMin, string filename);
int main(int argc, char** argv)
{  
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
    if (pcl::io::loadPCDFile<pcl::PointXYZ>("railway123.pcd", *cloud) == -1)//*打开点云文件
    {
        PCL_ERROR("Couldn't read pcd\n");
        return(-1);
    }
  
    
    cout << "Load " << "railway123.pcd" << endl;
    //    normialize(cloud,findMaxAndMin(cloud));

    vector<Point> p = findMaxAndMin(cloud); //输入点云的最值点
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_n(new pcl::PointCloud<pcl::PointXYZ>); //存储归一化之后的点云
    cloud_n = normialize(cloud, p, "railway123.pcd"); //归一化

    cout << "\nafter normalized:" << endl;
    vector<Point> p_ = findMaxAndMin(cloud_n); //归一化点云之后的最值点


    //可视化
    pcl::visualization::PCLVisualizer viewer("3D Viewer");
      // int v1(0);
   
      // viewer.createViewPort(0.5,0,1,1,v1);
      // viewer.setBackgroundColor (1, 1, 1);
      //  pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> point_cloud_color_handler (cloud, 0, 0, 0);
       //viewer.addPointCloud (cloud, point_cloud_color_handler, "cloud",v1);

    int v1(0);
    viewer.createViewPort(0, 0, 0.5, 1, v1);
    viewer.setBackgroundColor(1, 200, 200);
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> color2(cloud_n, 0, 0, 0);
    viewer.addPointCloud(cloud_n, color2, "cloud_n", v1);
    viewer.addText("cloud_normalized", 0, 0, "cloud_n", v1);

    viewer.addCoordinateSystem();
    while (!viewer.wasStopped())
    {
        viewer.spinOnce();
    }


    return 0;
}

vector<Point> findMaxAndMin(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_in)
{
    vector<Point> vector_back;
    Point max, min;
    max.x = cloud_in->points[0].x;
    max.y = cloud_in->points[0].y;
    max.z = cloud_in->points[0].z;

    min.x = cloud_in->points[0].x;
    min.y = cloud_in->points[0].y;
    min.z = cloud_in->points[0].z;

    for (int i = 0; i < cloud_in->size(); i++)
    {
        if (cloud_in->points[i].x >= max.x) { max.x = cloud_in->points[i].x; }
        if (cloud_in->points[i].x <= min.x) { min.x = cloud_in->points[i].x; }

        if (cloud_in->points[i].y >= max.y) { max.y = cloud_in->points[i].y; }
        if (cloud_in->points[i].y <= min.y) { min.y = cloud_in->points[i].y; }

        if (cloud_in->points[i].z >= max.z) { max.z = cloud_in->points[i].z; }
        if (cloud_in->points[i].z <= min.z) { min.z = cloud_in->points[i].z; }
    }

    vector_back.push_back(max);
    vector_back.push_back(min);

    cout << "max: " << max.x << "," << max.y << "," << max.z << endl;
    cout << "min: " << min.x << "," << min.y << "," << min.z << endl;

    return vector_back;

}

pcl::PointCloud<pcl::PointXYZ>::Ptr normialize(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_in, vector<Point> MaxAndMin, string filename)
{
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_back(new pcl::PointCloud<pcl::PointXYZ>);
    cloud_back->width = cloud_in->width;
    cloud_back->height = cloud_in->height;
    cloud_back->is_dense = cloud_in->is_dense;
    cloud_back->resize(cloud_in->size());
    Point max_bound, min_bound;
    max_bound = MaxAndMin[0];
    min_bound = MaxAndMin[1];
    double middlex, middley, middlez;
    middlex = (max_bound.x + min_bound.x) / 2;
    middley = (max_bound.y + min_bound.y) / 2;
    middlez = (max_bound.z + min_bound.z) / 2;

    for (int i = 0; i < cloud_back->size(); i++)
    {
        cloud_back->points[i].x = cloud_in->points[i].x - middlex;
        cloud_back->points[i].y = cloud_in->points[i].y - middley;
        cloud_back->points[i].z = cloud_in->points[i].z - middlez;
    }

    //scale based on x range
    double scalecoe = (max_bound.x - min_bound.x) / 2;
    for (int i = 0; i < cloud_back->size(); i++) {
        cloud_back->points[i].x = cloud_back->points[i].x / scalecoe;
        cloud_back->points[i].y = cloud_back->points[i].y / scalecoe;
        cloud_back->points[i].z = cloud_back->points[i].z / scalecoe;
    }
    //    pcl::io::savePCDFileASCII("normalized.pcd",*cloud_back);
    ostringstream oss;
    oss << "normalized_" << filename;
    pcl::io::savePCDFileASCII(oss.str(), *cloud_back);
    cout<<"Normalized!"<<endl;
    cout<<oss.str()<<" Saved!"<<endl;
    return cloud_back;
 
}


总之,点云归一化是点云处理和分析的重要步骤,它可以提高数据精度和稳定性,加速计算,方便数据的显示和可视化,从而为后续的点云处理和分析提供更好的基础。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

方sir点云学习经验分享

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值