本文分别讲述,三个数据x\y\z)的点云txt文件、四个数据(x\y\z\i)(i为强度)的点云txt文件、六个数据(x\y\z\r\g\b)的点云txt文件的点云着色代码,代码都大同小异,无非是PointXYZ类型、PointXYZI类型、PointXYZRGB类型然后分别填入数据。
1.PointXYZ类型的点云上色.txt文件
#include <iostream>
#include <sstream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/kdtree/kdtree_flann.h>
#include <pcl/search/impl/kdtree.hpp>
#include <boost/thread/thread.hpp>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/filters/statistical_outlier_removal.h> //统计滤波
#include <pcl/surface/mls.h> //最小二乘
using namespace std;
// ----------------------------读取txt文件中的xyz坐标-------------------------------------
void ReadCloudXYZFromTxt(const std::string& file_path, pcl::PointCloud<pcl::PointXYZ>::Ptr cloud)
{
std::ifstream file(file_path.c_str());//c_str():生成一个const char*指针,指向以空字符终止的数组。
std::string line;
pcl::PointXYZ point;
while (getline(file, line)) {
std::stringstream ss(line);
ss >> point.x;
ss >> point.y;
ss >> point.z;
//ss >> point.intensity;
cloud->push_back(point);
}
file.close();
}
//******************可视化*******************************************
void visualization(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud)
{
boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("3D Viewer"));
viewer->setBackgroundColor(0, 0, 0); //设置背景(1,1,1)是白
//pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> single_color(cloud, 0, 255, 0); // green
pcl::visualization::PointCloudColorHandlerGenericField<pcl::PointXYZ> fildColor(cloud, "x"); //根据第二个参数来着色
viewer->addPointCloud<pcl::PointXYZ>(cloud, fildColor, "sample cloud");
cout << cloud->points.size();
while (!viewer->wasStopped())
{
viewer->spinOnce(100);
boost::this_thread::sleep(boost::posix_time::microseconds(100000));
}
}
int main(int argc, char** argv) //liqiaoyang:我在之前的代码上改的 注释掉的函数都是没用的 只用了visualization的
{
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointXYZ>::Ptr cloudC1(new pcl::PointCloud<pcl::PointXYZ>);//依次读取四个文件的点云数据
pcl::PointCloud<pcl::PointXYZ>::Ptr cloudC2(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointXYZ>::Ptr cloudC3(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointXYZ>::Ptr cloudC4(new pcl::PointCloud<pcl::PointXYZ>);
ReadCloudXYZFromTxt("D:\\YinParker\\Desktop\\C1M(1).txt", cloudC1);
ReadCloudXYZFromTxt("D:\\YinParker\\Desktop\\C2M(1).txt", cloudC2);
ReadCloudXYZFromTxt("D:\\YinParker\\Desktop\\C3M(1).txt", cloudC3);
ReadCloudXYZFromTxt("D:\\YinParker\\Desktop\\C4M(1).txt", cloudC4);
*cloud = *cloudC1 + *cloudC2 + *cloudC3 + *cloudC4;
visualization(cloud);
}
效果:
2.PointXYZI类型的点云.txt文件上色(I为强度)
#include <iostream>
#include <sstream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/kdtree/kdtree_flann.h>
#include <pcl/search/impl/kdtree.hpp>
#include <boost/thread/thread.hpp>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/filters/statistical_outlier_removal.h> //统计滤波
#include <pcl/surface/mls.h> //最小二乘
using namespace std;
// ----------------------------读取txt文件中的xyz坐标以及I强度-------------------------------------
void ReadCloudXYZIFromTxt(const std::string& file_path, pcl::PointCloud<pcl::PointXYZI>::Ptr cloud)
{
std::ifstream file(file_path.c_str());//c_str():生成一个const char*指针,指向以空字符终止的数组。
std::string line;
pcl::PointXYZI point;
while (getline(file, line)) {
std::stringstream ss(line);
ss >> point.x;
ss >> point.y;
ss >> point.z;
ss >> point.intensity;
cloud->push_back(point);
}
file.close();
}
//******************可视化*******************************************
void visualization(pcl::PointCloud<pcl::PointXYZI>::Ptr cloud)
{
boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("3D Viewer"));
viewer->setBackgroundColor(0, 0, 0); //设置背景(1,1,1)是白
//pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> single_color(cloud, 0, 255, 0); // green
pcl::visualization::PointCloudColorHandlerGenericField<pcl::PointXYZI> fildColor(cloud, "intensity"); //根据第二个参数来着色
viewer->addPointCloud<pcl::PointXYZI>(cloud, fildColor, "sample cloud");
cout << cloud->points.size();
while (!viewer->wasStopped())
{
viewer->spinOnce(100);
boost::this_thread::sleep(boost::posix_time::microseconds(100000));
}
}
int main(int argc, char** argv)
{
pcl::PointCloud<pcl::PointXYZI>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZI>);
pcl::PointCloud<pcl::PointXYZI>::Ptr cloudC1(new pcl::PointCloud<pcl::PointXYZI>);//依次读取四个文件的点云数据
pcl::PointCloud<pcl::PointXYZI>::Ptr cloudC2(new pcl::PointCloud<pcl::PointXYZI>);
pcl::PointCloud<pcl::PointXYZI>::Ptr cloudC3(new pcl::PointCloud<pcl::PointXYZI>);
pcl::PointCloud<pcl::PointXYZI>::Ptr cloudC4(new pcl::PointCloud<pcl::PointXYZI>);
ReadCloudXYZIFromTxt("D:\\YinParker\\Desktop\\C1M(1)_.txt", cloudC1);
ReadCloudXYZIFromTxt("D:\\YinParker\\Desktop\\C2M(1)_.txt", cloudC2);
ReadCloudXYZIFromTxt("D:\\YinParker\\Desktop\\C3M(1)_.txt", cloudC3);
ReadCloudXYZIFromTxt("D:\\YinParker\\Desktop\\C4M(1)_.txt", cloudC4);
*cloud = *cloudC1 + *cloudC2 + *cloudC3 + *cloudC4;
visualization(cloud);
}
效果:由于每个点后面的强度值是我随机生成的,参考这个博文,所以着色是都比较杂乱,实际应用中,相邻的点云的强度值会差不多,产生的颜色也会比较趋同。
3.PointXYZRGB类型的点云.txt文件上色
#include <iostream>
#include <sstream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/kdtree/kdtree_flann.h>
#include <pcl/search/impl/kdtree.hpp>
#include <boost/thread/thread.hpp>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/filters/statistical_outlier_removal.h> //统计滤波
#include <pcl/surface/mls.h> //最小二乘
using namespace std;
// ----------------------------读取txt文件中的xyz坐标-------------------------------------
void ReadCloudXYZRGBFromTxt(const std::string& file_path, pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud)
{
std::ifstream file(file_path.c_str());//c_str():生成一个const char*指针,指向以空字符终止的数组。
std::string line;
pcl::PointXYZRGB point;
while (getline(file, line)) {
float r, g, b;
std::stringstream ss(line);
ss >> point.x;
ss >> point.y;
ss >> point.z;
//ss >> point.intensity;
ss >> r;
ss >> g;
ss >> b;
uint8_t red = static_cast<uint8_t>(r);
uint8_t green = static_cast<uint8_t>(g);
uint8_t blue = static_cast<uint8_t>(b);
uint32_t rgb = (static_cast<uint32_t>(red) << 16 | static_cast<uint32_t>(green) << 8 | static_cast<uint32_t>(blue));
//uint32_t rgb = (static_cast<uint32_t>(red) *0.299+static_cast<uint32_t>(green) *0.587+ static_cast<uint32_t>(blue))*0.114;
point.rgb = *reinterpret_cast<float*>(&rgb);
cloud->push_back(point);
}
file.close();
}
//******************可视化*******************************************
void visualization(pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud)
{
boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("3D Viewer"));
viewer->setBackgroundColor(0, 0, 0); //设置背景(1,1,1)是白
//pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> single_color(cloud, 0, 255, 0); // green
//pcl::visualization::PointCloudColorHandlerGenericField<pcl::PointXYZRGB> fildColor(cloud, "rgb"); //根据第二个参数来着色
//viewer->addPointCloud<pcl::PointXYZRGB>(cloud, fildColor, "sample cloud");
pcl::visualization::PointCloudColorHandlerRGBField<pcl::PointXYZRGB> rgb(cloud);
viewer->addPointCloud<pcl::PointXYZRGB>(cloud, rgb, "cloud");
cout << cloud->points.size();
while (!viewer->wasStopped())
{
viewer->spinOnce(100);
boost::this_thread::sleep(boost::posix_time::microseconds(100000));
}
}
int main(int argc, char** argv) //liqiaoyang:我在之前的代码上改的 注释掉的函数都是没用的 只用了visualization的
{
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGB>);
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloudC1(new pcl::PointCloud<pcl::PointXYZRGB>);//依次读取四个文件的点云数据
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloudC2(new pcl::PointCloud<pcl::PointXYZRGB>);
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloudC3(new pcl::PointCloud<pcl::PointXYZRGB>);
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloudC4(new pcl::PointCloud<pcl::PointXYZRGB>);
ReadCloudXYZRGBFromTxt("D:\\YinParker\\Desktop\\C1M(1)_color.txt", cloudC1);
ReadCloudXYZRGBFromTxt("D:\\YinParker\\Desktop\\C2M(1)_color.txt", cloudC2);
ReadCloudXYZRGBFromTxt("D:\\YinParker\\Desktop\\C3M(1)_color.txt", cloudC3);
ReadCloudXYZRGBFromTxt("D:\\YinParker\\Desktop\\C4M(1)_color.txt", cloudC4);
*cloud = *cloudC1 + *cloudC2 + *cloudC3 + *cloudC4;
visualization(cloud);
}
效果:我有一个.txt文件的rgb都设置成了255 255 255,所以是白色,结果证明是对的
如果我把上面代码中的显示rgb的部分按照前两种方法改写,如下面代码,效果如下,我猜是把rag当成强度值了,只不过名字是rgb而已。因为我把第四个txt的rgb后面都设成[255,255,255],按理应该是白色的
pcl::visualization::PointCloudColorHandlerGenericField<pcl::PointXYZRGB> fildColor(cloud, "rgb"); //根据第二个参数来着色
viewer->addPointCloud<pcl::PointXYZRGB>(cloud, fildColor, "sample cloud");
//pcl::visualization::PointCloudColorHandlerRGBField<pcl::PointXYZRGB> rgb(cloud);
//viewer->addPointCloud<pcl::PointXYZRGB>(cloud, rgb, "cloud");
参考:PCL visualization color 点云可视化,颜色显示,多窗口,显示文本
【补充知识点1】补充软件cloud -compare也可以导入文件时选择颜色
还有一个Alpha表示透明度。越大越不透明。RGBA是以一个数代表整个颜色,0000~FF,FF,FF,FF,很大。RGBAi是整数,RGBAf是浮点数。
【补充知识点2】PCL 点云随机赋色
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/common/common.h>
using namespace std;
int main(int argc, char** argv)
{
// ---------------------------加载点云数据--------------------------------------
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGB>);
pcl::io::loadPCDFile<pcl::PointXYZRGB>("xxxxxxx.pcd", *cloud);
srand((unsigned)time(NULL));
for (auto& point_i : *cloud)
{
// 随机生成颜色
uint8_t R = rand() % (256) + 0;
uint8_t G = rand() % (256) + 0;
uint8_t B = rand() % (256) + 0;
point_i.r = R;
point_i.g = G;
point_i.b = B;
}
pcl::io::savePCDFileBinary("randomColor.pcd", *cloud);
return (0);
}
然后在cloudCompare里导入randomColor.pcd