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;
}
meshcolor转PointXYZRGB
#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;
}