点云归一化是将点云数据缩放到固定范围内的过程,通常是将点云数据缩放到一个单位立方体中。点云归一化的意义在于:
数据预处理:归一化可以将点云数据从原始的坐标系中转换到一个统一的坐标系中,从而方便后续的数据处理和分析。例如,可以将点云数据归一化到一个单位立方体中,以便进行模型的对齐和匹配。
提高数据精度:归一化可以提高点云数据的精度和稳定性。由于点云数据通常是由不同的传感器和设备采集而来,这些数据可能会存在不同的尺度和坐标系,这会影响数据的精度和可靠性。通过归一化,可以将点云数据转换到一个统一的坐标系中,从而提高数据的精度和稳定性。
加速计算:归一化可以减少计算量,提高计算效率。由于点云数据通常是非常庞大的,进行计算时需要消耗大量的计算资源。通过归一化,可以将点云数据缩放到一个单位立方体中,从而减少计算量,提高计算效率。
显示和可视化:归一化可以方便点云数据的显示和可视化。在点云数据的显示和可视化过程中,通常需要将点云数据转换到一个统一的坐标系中,以便进行显示和可视化。通过归一化,可以将点云数据缩放到一个单位立方体中,从而方便点云数据的显示和可视化。
#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;
}
总之,点云归一化是点云处理和分析的重要步骤,它可以提高数据精度和稳定性,加速计算,方便数据的显示和可视化,从而为后续的点云处理和分析提供更好的基础。