PCL中viewer添加并显示的点云过于简单,现总结常见的几种点云渲染方式,便于点云结果的显示。
(1)按照点云坐标x、y、z坐标值中字段给点云进行赋值渲染
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <vector>
using namespace std;
int main(int argc, char* argv[])
{
pcl::PointCloud<pcl::PointXYZ>::Ptr Cloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::io::loadPCDFile("XX.pcd", *Cloud);//读入点云数据
pcl::visualization::PCLVisualizer viewer("点云");
viewer.setBackgroundColor(0, 0, 0);
pcl::visualization::PointCloudColorHandlerGenericField<pcl::PointXYZ> fildColor(Cloud, "z");//按照z字段进行渲染
viewer.addPointCloud<pcl::PointXYZ>(Cloud, fildColor, "sample");//显示点云,其中fildColor为颜色显示
viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "sample");//设置点云大小
while (!viewer.wasStopped())
{
viewer.spinOnce();
}
return 0;
}
按照z高程渲染图:
按照x坐标渲染图:
(2)给点云单独赋予某一颜色
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <vector>
using namespace std;
int main(int argc, char* argv[])
{
pcl::PointCloud<pcl::PointXYZ>::Ptr Cloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::io::loadPCDFile("XX.pcd", *Cloud);//读入点云数据
pcl::visualization::PCLVisualizer viewer("点云");
viewer.setBackgroundColor(0, 0, 0);
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> singleColor(Cloud, 0,255,0);//0-255 设置成绿色
viewer.addPointCloud<pcl::PointXYZ>(Cloud, singleColor, "sample");//显示点云,其中fildColor为颜色显示
viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "sample");//设置点云大小
while (!viewer.wasStopped())
{
viewer.spinOnce();
}
return 0;
}
点云设置成绿色的结果:
(3)随机生成颜色
int main(int argc, char* argv[])
{
pcl::PointCloud<pcl::PointXYZ>::Ptr Cloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::io::loadPCDFile("xx.pcd", *Cloud);//读入点云数据
pcl::visualization::PCLVisualizer viewer("点云");
viewer.setBackgroundColor(0, 0, 0);
pcl::visualization::PointCloudColorHandlerRandom<pcl::PointXYZ> RandomColor(Cloud);//随机给点云生成颜色
viewer.addPointCloud<pcl::PointXYZ>(Cloud, RandomColor, "sample");//显示点云,其中fildColor为颜色显示
viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "sample");//设置点云大小
while (!viewer.wasStopped())
{
viewer.spinOnce();
}
return 0;
}
随机生成的颜色结果图:
(4)采用某一属性值进行显示
在实际中会遇到根据某一特征对点集进行分类,为便于从视觉上直接判断该特征的区别度,可以依据该特征值设置成点的颜色,进行渲染,看其效果。
如下代码是依据法向量方差特征的显示图,代码及图如下:
#include"CalculateFeatures.h"
#include<iostream>
#include<sstream>
#include<vector>
#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
#include <pcl/visualization/pcl_visualizer.h>
#include"IO.h"
using namespace std;
#define e 2.718
void main()
{
CalculateFeatures CalExample;
IO IOExample;
ifstream infile("Area1.txt", ios::in);
pcl::PointXYZ temp;
char line[128];
int label;
vector<pcl::PointXYZ> AllPoints;
vector<int> LabelArr;
vector<pcl::PointXYZ> UnclassPoints;//未分类点 格网化高程点特征只针对未分类的点
vector<pcl::PointXYZ> GroundPoints;//已经分类的点,为地面点
while (infile.getline(line, sizeof(line)))
{
stringstream word(line);
word >> temp.x;
word >> temp.y;
word >> temp.z;
word >> label;
AllPoints.push_back(temp);
LabelArr.push_back(label);
if (label == 1)
{
UnclassPoints.push_back(temp);
}
else if (label == 2)
{
GroundPoints.push_back(temp);
}
}
pcl::PointCloud<pcl::PointXYZ>::Ptr UnclassPointsPtr(new pcl::PointCloud<pcl::PointXYZ>);
UnclassPointsPtr = IOExample.PointXYZ2Ptr(UnclassPoints);
vector<double> NormalHis;
NormalHis = CalExample.AngleHistogramZ(UnclassPointsPtr, 60, 15, 6);
pcl::PointCloud<pcl::PointXYZRGB>::Ptr new_cloud(new pcl::PointCloud<pcl::PointXYZRGB>);
new_cloud->width = UnclassPoints.size();
new_cloud->height = 1;
new_cloud->is_dense = false;
new_cloud->points.resize(new_cloud->width*new_cloud->height);
for (int i = 0; i < UnclassPoints.size(); i++)
{
new_cloud->points[i].x = UnclassPoints[i].x;
new_cloud->points[i].y = UnclassPoints[i].y;
new_cloud->points[i].z = UnclassPoints[i].z;
new_cloud->points[i].rgb = -NormalHis[i];//
}
pcl::visualization::PointCloudColorHandlerGenericField<pcl::PointXYZRGB> fildColor(new_cloud, "rgb");
pcl::visualization::PCLVisualizer viewer("点云特征");
//pcl::visualization::PointCloudColorHandlerRGBField<pcl::PointXYZRGB> rgb(new_cloud);
viewer.setBackgroundColor(0, 0, 0);
viewer.addPointCloud<pcl::PointXYZRGB>(new_cloud, fildColor, "inCloud");
viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 5, "inCloud");
while (!viewer.wasStopped())
{
viewer.spinOnce();
}
}
(5)带RGB值的可视化
有些点云数据的RGB值是分开的,为R、G、B,将RGB赋值给该点作为颜色进行显示,代码如下
#include"CalculateFeatures.h"
#include<iostream>
#include<sstream>
#include<vector>
#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/kdtree/kdtree_flann.h>
#include"IO.h"
using namespace std;
#define e 2.718
#include"DataStruct.h"
#include"EuclideanCluster.h"
#include"NearestKD.h"
#include"stdint.h"
void main()
{
IO IOExample;
CalculateFeatures CalExample;
arrayoperation ArrExample;
ifstream infile("D:\\XX.txt", ios::in);
struct ColorRGB
{
double R;
double G;
double B;
};
vector<pcl::PointXYZ> PointCluster;
vector<ColorRGB>RGBVec;
pcl::PointXYZ TemPoint;
ColorRGB TempRGB;
char line[256];
while (infile.getline(line, sizeof(line)))
{
stringstream word(line);
word >> TemPoint.x;
word >> TemPoint.y;
word >> TemPoint.z;
word >> TempRGB.R;
word >> TempRGB.G;
word >> TempRGB.B;
RGBVec.push_back(TempRGB);
PointCluster.push_back(TemPoint);
}
pcl::PointCloud<pcl::PointXYZRGB>::Ptr new_cloud(new pcl::PointCloud<pcl::PointXYZRGB>);
new_cloud->width = PointCluster.size();
new_cloud->height = 1;
new_cloud->is_dense = false;
new_cloud->points.resize(new_cloud->width*new_cloud->height);
for (int i = 0; i < PointCluster.size(); i++)
{
new_cloud->points[i].x = PointCluster[i].x;
new_cloud->points[i].y = PointCluster[i].y;
new_cloud->points[i].z = PointCluster[i].z;
int R = RGBVec[i].R;
int G = RGBVec[i].G;
int B = RGBVec[i].B;
new_cloud->points[i].r = R;
new_cloud->points[i].g = G;
new_cloud->points[i].b = B;
}
pcl::visualization::PointCloudColorHandlerRGBField<pcl::PointXYZRGB>fildColor(new_cloud);
pcl::visualization::PCLVisualizer viewer("彩色点云数据");
viewer.setBackgroundColor(0, 0, 0);
viewer.addPointCloud<pcl::PointXYZRGB>(new_cloud, fildColor, "inCloud");
viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 5, "inCloud");
while (!viewer.wasStopped())
{
viewer.spinOnce();
}
}
(6)法向量的颜色表示
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/kdtree/kdtree_flann.h>
#include <pcl/features/normal_3d.h>
#include <pcl/surface/gp3.h>
#include <pcl/visualization/pcl_visualizer.h>
void main()
{
//定义一个点云cloud
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::io::loadPCDFile("E:\\program_study\\C++\\pcd_data\\bunny.pcd", *cloud);//读入点云数据
// Normal estimation*
//法向计算
pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> n;
pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>);
//建立kdtree来进行近邻点集搜索
pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>);
//为kdtree添加点云数据
tree->setInputCloud(cloud);
n.setInputCloud(cloud);
n.setSearchMethod(tree);
//点云法向计算时,需要搜索的近邻点大小
n.setKSearch(20);
//开始进行法向计算
n.compute(*normals);
//* normals should not contain the point normals + surface curvatures
//显示类
pcl::visualization::PCLVisualizer viewer("Cloud Viewer");
//设置背景色
viewer.setBackgroundColor(0, 0, 0);
//按照z值进行渲染点的颜色
pcl::visualization::PointCloudColorHandlerGenericField<pcl::PointXYZ> fildColor(cloud, "z");
//添加需要显示的点云数据
viewer.addPointCloud<pcl::PointXYZ>(cloud, fildColor, "sample cloud");
//设置点显示大小
viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "sample cloud");
//添加需要显示的点云法向。cloud为原始点云模型,normal为法向信息,1表示需要显示法向的点云间隔,即每1个点显示一次法向,0.01表示法向长度。
viewer.addPointCloudNormals<pcl::PointXYZ, pcl::Normal>(cloud, normals, 1, 0.01, "normals");
while (!viewer.wasStopped())
{
viewer.spinOnce();
}
}
法向量估算渲染图:
修改法向量的代码:
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/kdtree/kdtree_flann.h>
#include <pcl/features/normal_3d.h>
#include <pcl/surface/gp3.h>
#include <pcl/visualization/pcl_visualizer.h>
void main()
{
IO IOExample;
//定义一个点云cloud
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
ifstream infile("littleregion_15_new.off", ios::in);
double x, y, z, nx, ny, nz;
vector<double> nxVec, nyVec, nzVec;
char line[128];
pcl::PointXYZ point;
vector<pcl::PointXYZ> pointVec;
while (infile.getline(line, sizeof(line)))
{
stringstream word(line);
word >> point.x;
word >> point.y;
word >> point.z;
pointVec.push_back(point);
word >> nx;
word >> ny;
word >> nz;
nxVec.push_back(nx);
nyVec.push_back(ny);
nzVec.push_back(nz);
}
pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>);
normals->width = pointVec.size();
normals->height = 1;
normals->is_dense = false;
normals->resize(normals->width*normals->height);
for (int i = 0; i < pointVec.size(); i++)
{
(*normals)[i].normal_x = nxVec[i];
(*normals)[i].normal_y = nyVec[i];
(*normals)[i].normal_z = nzVec[i];
}
cloud = IOExample.PointXYZ2Ptr(pointVec);
//显示类
pcl::visualization::PCLVisualizer viewer("法向量可视化");
//设置背景色
viewer.setBackgroundColor(0, 0, 0);
//按照z值进行渲染点的颜色
pcl::visualization::PointCloudColorHandlerGenericField<pcl::PointXYZ> fildColor(cloud, "z");
//添加需要显示的点云数据
viewer.addPointCloud<pcl::PointXYZ>(cloud, fildColor, "sample cloud");
//设置点显示大小
viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "sample cloud");
//添加需要显示的点云法向。cloud为原始点云模型,normal为法向信息,1表示需要显示法向的点云间隔,即每1个点显示一次法向,1表示法向长度。
viewer.addPointCloudNormals<pcl::PointXYZ, pcl::Normal>(cloud, normals, 1, 1, "normals");
while (!viewer.wasStopped())
{
viewer.spinOnce();
}
}
附快捷键: