PointXYZRGB转meshcolor
参考:如何使用PCL将XYZRGB点云转换为彩色mesh模型
#include <iostream>
#include <string>
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/io/ply_io.h>
#include <pcl/kdtree/kdtree_flann.h>
#include <pcl/features/normal_3d_omp.h>
#include <pcl/features/normal_3d.h>
#include <pcl/surface/gp3.h>
#include <pcl/surface/poisson.h>
#include <pcl/visualization/pcl_visualizer.h>void PointXYZRGB2meshcolor(pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud)
{pcl::NormalEstimationOMP<pcl::PointXYZRGB, pcl::Normal> ne;ne.setNumberOfThreads(8);ne.setInputCloud(cloud);ne.setKSearch(10);Eigen::Vector4f centroid;compute3DCentroid(*cloud, centroid);ne.setViewPoint(centroid[0], centroid[1], centroid[2]);//将向量计算原点置于点云中心pcl::PointCloud<pcl::Normal>::Ptr cloud_normals(new pcl::PointCloud<pcl::Normal>);ne.compute(*cloud_normals);//将法向量反向for (size_t i = 0; i < cloud_normals->size(); ++i){cloud_normals->points[i].normal_x *= -1;cloud_normals->points[i].normal_y *= -1;cloud_normals->points[i].normal_z *= -1;}//融合RGB点云和法向pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr cloud_smoothed_normals(new pcl::PointCloud<pcl::PointXYZRGBNormal>);pcl::concatenateFields(*cloud, *cloud_normals, *cloud_smoothed_normals);//泊松重建pcl::Poisson<pcl::PointXYZRGBNormal> poisson;poisson.setDegree(2);poisson.setDepth(8);poisson.setSolverDivide(8);poisson.setIsoDivide(8);poisson.setConfidence(false);poisson.setManifold(false);poisson.setOutputPolygons(false);poisson.setInputCloud(cloud_smoothed_normals);pcl::PolygonMesh mesh;poisson.reconstruct(mesh);//给mesh染色pcl::PointCloud<pcl::PointXYZRGB> cloud_color_mesh;pcl::fromPCLPointCloud2(mesh.cloud, cloud_color_mesh);pcl::KdTreeFLANN<pcl::PointXYZRGB> kdtree;kdtree.setInputCloud(cloud); //使用kdtree在原RGB点云上建立一个搜索索引int K = 10;std::vector<int> pointIdxNKNSearch(K);std::vector<float> pointNKNSquaredDistance(K);for (int i = 0; i < cloud_color_mesh.points.size(); ++i){uint8_t r = 0, g = 0, b = 0;int sum_r = 0, sum_g = 0, sum_b = 0;float dist = 0.0;if (kdtree.nearestKSearch(cloud_color_mesh.points[i], K, pointIdxNKNSearch, pointNKNSquaredDistance) > 0) //对mesh上的每一个点都搜索对应原RGB点云上的临近点{ //求得这些对应临近点的RGB通道均值,作为mesh上那个点的颜色信息for (int j = 0; j < pointIdxNKNSearch.size(); ++j){r = cloud->points[pointIdxNKNSearch[j]].r;g = cloud->points[pointIdxNKNSearch[j]].g;b = cloud->points[pointIdxNKNSearch[j]].b;sum_r += int(r);sum_g += int(g);sum_b += int(b);dist += 1.0 / pointNKNSquaredDistance[j];}}cloud_color_mesh.points[i].r = int(sum_r / pointIdxNKNSearch.size() + 0.5);cloud_color_mesh.points[i].g = int(sum_g / pointIdxNKNSearch.size() + 0.5);cloud_color_mesh.points[i].b = int(sum_b / pointIdxNKNSearch.size() + 0.5);}pcl::toPCLPointCloud2(cloud_color_mesh, mesh.cloud);pcl::io::savePLYFile("mesh.ply", mesh);pcl::visualization::PCLVisualizer viewer("viewer");viewer.addPolygonMesh(mesh);while (!viewer.wasStopped()){viewer.spinOnce(100);}
}int main(int argc, char** argv)
{pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGB>);pcl::io::loadPCDFile("bunny_color.pcd", *cloud);PointXYZRGB2meshcolor(cloud);return 0;
}
PointXYZRGB转meshcolor
#include <iostream>
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/io/ply_io.h>
#include <pcl/visualization/pcl_visualizer.h>void meshcolor2PointXYZRGB(pcl::PolygonMesh mesh)
{pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGB>);pcl::fromPCLPointCloud2(mesh.cloud, *cloud);pcl::io::savePCDFile("bunny_cloud.pcd", *cloud);pcl::io::savePLYFile("bunny_cloud.ply", *cloud);std::ofstream outfile;outfile.open("bunny_cloud.txt");for (size_t i = 0; i < cloud->size(); i++){pcl::PointXYZRGB p = cloud->points[i];outfile << p.x << " " << p.y << " " << p.z << " " << (int)p.r << " " << (int)p.g << " " << (int)p.b << std::endl;}outfile.close();pcl::visualization::PCLVisualizer viewer("Viewer");viewer.addPointCloud(cloud, "cloud");while (!viewer.wasStopped()){viewer.spinOnce(100);}
}int main(int argc, char** argv)
{pcl::PolygonMesh mesh;pcl::io::loadPLYFile("mesh.ply", mesh);meshcolor2PointXYZRGB(mesh);return 0;
}