PCL Save VTK File With Texture Coordinates 使用PCL库来保存带纹理坐标的VTK文件
来源:互联网 发布:淘宝卖家能删除评价嘛 编辑:程序博客网 时间:2024/06/05 03:21
我之前有一篇博客Convert PLY to VTK Using PCL 1.6.0 or PCL 1.8.0 使用PCL库将PLY格式转为VTK格式展示了如何将PLY格式文件转化为VTK格式的文件,在文章的最后提到了VTK文件保存纹理的两种方式,第一种是需要有texture的图片,然后每个点存储上该点在图片中的x,y坐标,一般会normalize到[0,1]之间。第二种方法是直接存每个点的rgb值,上面的方法用的是第二种,因为导入的PLY格式就直接存储的texture的rgb值,并没有额外提供texture图片。
对于一般的PLY或者PCD格式的点云,一般都是用第二种方式来保存纹理的,即直接存储rgb值,这样转换成的vtk文件自然也是第二种情况,而对于大多数的可视化软件,比如ParaView或者3D Slicer,貌似只支持第一种方式,即需要导入texture图片(如果大家知道直接显示rgb值的方法,请在下方留言告知博主)。这样就极大的不方便了,而且PCL库中的点云格式一般也是XYZRGBA,并没有带UV,纹理有专门的数据结构。我们的目标是生成带texture coordinates的VTK文件,那么可以通过修改pcl自带的saveVTKFile函数来实现目标。
这里我们把纹理坐标单独抽出来,用下面的数据结构来表示:
std::vector<Eigen::Vector2f> texcoord;
pcl自带的pcl::io::saveVTKFile函数所在的文件的地址是.../io/src/vtk_io.cpp。默认的是写入RGB的值,我们只需要注释掉写入RGB的部分,添加上写入纹理坐标的部分:
Using PCL 1.6.0
// PCL 1.6.0
int save_vtk_file(const std::string &file_name, const sensor_msgs::PointCloud2 &cloud, const std::vector<Eigen::Vector2f>& texcoord, unsigned precision) { if (cloud.data.empty ()) { PCL_ERROR ("[pcl::io::saveVTKFile] Input point cloud has no data!\n"); return (-1); } // Open file std::ofstream fs; fs.precision (precision); fs.open (file_name.c_str ()); unsigned int nr_points = cloud.width * cloud.height; unsigned int point_size = static_cast<unsigned int> (cloud.data.size () / nr_points); // Write the header information fs << "# vtk DataFile Version 3.0\nvtk output\nASCII\nDATASET POLYDATA\nPOINTS " << nr_points << " float" << std::endl; // Iterate through the points for (unsigned int i = 0; i < nr_points; ++i) { int xyz = 0; for (size_t d = 0; d < cloud.fields.size (); ++d) { int count = cloud.fields[d].count; if (count == 0) count = 1; // we simply cannot tolerate 0 counts (coming from older converter code) int c = 0; if ((cloud.fields[d].datatype == sensor_msgs::PointField::FLOAT32) && ( cloud.fields[d].name == "x" || cloud.fields[d].name == "y" || cloud.fields[d].name == "z")) { float value; memcpy (&value, &cloud.data[i * point_size + cloud.fields[d].offset + c * sizeof (float)], sizeof (float)); fs << value; if (++xyz == 3) break; } fs << " "; } if (xyz != 3) { PCL_ERROR ("[pcl::io::saveVTKFile] Input point cloud has no XYZ data!\n"); return (-2); } fs << std::endl; } // Write vertices fs << "\nVERTICES " << nr_points << " " << 2*nr_points << std::endl; for (unsigned int i = 0; i < nr_points; ++i) fs << "1 " << i << std::endl; // Write RGB values// int field_index = pcl::getFieldIndex (cloud, "rgb");// if (field_index != -1)// {// fs << "\nPOINT_DATA " << nr_points << "\nCOLOR_SCALARS scalars 3\n";// for (unsigned int i = 0; i < nr_points; ++i)// {// int count = cloud.fields[field_index].count;// if (count == 0)// count = 1; // we simply cannot tolerate 0 counts (coming from older converter code)// int c = 0;// if (cloud.fields[field_index].datatype == sensor_msgs::PointField::FLOAT32)// {// pcl::RGB color;// memcpy (&color, &cloud.data[i * point_size + cloud.fields[field_index].offset + c * sizeof (float)], sizeof (pcl::RGB));// int r = color.r;// int g = color.g;// int b = color.b;// fs << static_cast<float> (r) / 255.0f << " " << static_cast<float> (g) / 255.0f << " " << static_cast<float> (b) / 255.0f;// }// fs << std::endl;// }// } // Write texture coordinates fs << "\nPOINT_DATA " << nr_points << "\nTEXTURE_COORDINATES tcoords 2 float\n"; for (unsigned int i = 0; i < nr_points; ++i) { //fs << texcoord[i][0] << " " << texcoord[i][1] << "\n"; fs << texcoord[i][1] << " " << texcoord[i][0] << "\n"; } fs << std::endl; // Close file fs.close (); return (0);}
Using PCL 1.8.0
// PCL 1.8.0int save_vtk_file (const std::string &file_name, const pcl::PCLPointCloud2 &cloud, const std::vector<Eigen::Vector2f>& texcoord, unsigned precision){ if (cloud.data.empty ()) { PCL_ERROR ("[pcl::io::saveVTKFile] Input point cloud has no data!\n"); return (-1); } // Open file std::ofstream fs; fs.precision (precision); fs.open (file_name.c_str ()); unsigned int nr_points = cloud.width * cloud.height; unsigned int point_size = static_cast<unsigned int> (cloud.data.size () / nr_points); // Write the header information fs << "# vtk DataFile Version 3.0\nvtk output\nASCII\nDATASET POLYDATA\nPOINTS " << nr_points << " float" << '\n'; // Iterate through the points for (unsigned int i = 0; i < nr_points; ++i) { int xyz = 0; for (size_t d = 0; d < cloud.fields.size (); ++d) { int count = cloud.fields[d].count; if (count == 0) count = 1; // we simply cannot tolerate 0 counts (coming from older converter code) int c = 0; if ((cloud.fields[d].datatype == pcl::PCLPointField::FLOAT32) && ( cloud.fields[d].name == "x" || cloud.fields[d].name == "y" || cloud.fields[d].name == "z")) { float value; memcpy (&value, &cloud.data[i * point_size + cloud.fields[d].offset + c * sizeof (float)], sizeof (float)); fs << value; if (++xyz == 3) break; } fs << " "; } if (xyz != 3) { PCL_ERROR ("[pcl::io::saveVTKFile] Input point cloud has no XYZ data!\n"); return (-2); } fs << '\n'; } // Write vertices fs << "\nVERTICES " << nr_points << " " << 2*nr_points << '\n'; for (unsigned int i = 0; i < nr_points; ++i) fs << "1 " << i << '\n';// // Write RGB values// int field_index = getFieldIndex (cloud, "rgb");// if (field_index != -1)// {// fs << "\nPOINT_DATA " << nr_points << "\nCOLOR_SCALARS scalars 3\n";// for (unsigned int i = 0; i < nr_points; ++i)// {// int count = cloud.fields[field_index].count;// if (count == 0)// count = 1; // we simply cannot tolerate 0 counts (coming from older converter code)// int c = 0;// if (cloud.fields[field_index].datatype == pcl::PCLPointField::FLOAT32)// {// pcl::RGB color;// memcpy (&color, &cloud.data[i * point_size + cloud.fields[field_index].offset + c * sizeof (float)], sizeof (RGB));// int r = color.r;// int g = color.g;// int b = color.b;// fs << static_cast<float> (r) / 255.0f << " " << static_cast<float> (g) / 255.0f << " " << static_cast<float> (b) / 255.0f;// }// fs << '\n';// }// } // Write texture coordinates fs << "\nPOINT_DATA " << nr_points << "\nTEXTURE_COORDINATES tcoords 2 float\n"; for (unsigned int i = 0; i < nr_points; ++i) { //fs << texcoord[i][0] << " " << texcoord[i][1] << "\n"; fs << texcoord[i][1] << " " << texcoord[i][0] << "\n"; } fs << '\n'; // Close file fs.close (); return (0);}
- PCL Save VTK File With Texture Coordinates 使用PCL库来保存带纹理坐标的VTK文件
- PCL嵌入VTK/QT显示
- pcl显示报错-VTK
- 把pcl的VTK显示融合到MFC
- PCL(Point Cloud Library)的第三方库简介(boost,eigen,flann,vtk,qhull)
- PCL(Point Cloud Library)的第三方库简介(boost,eigen,flann,vtk,qhull)
- PCL(Point Cloud Library)的第三方库简介(boost,eigen,flann,vtk,qhull)
- 《PCL点云库学习&VS2010(X64)》Part 4 MFC+VTK+VS2010 测试VTK的MFC对话框程序
- pcl 1.8.0(5) VTK编译
- Texture Coordinates and Visuals on 3D surfaces 纹理坐标
- 基于MFC 对话框的 PCL、VTK 、OPENCV岩体识别系统构建(1)
- 基于MFC 对话框的 PCL、VTK 、OPENCV岩体识别系统构建(2)
- PCL第三方库:Eigen, Flann , Qhull, VTK, Boost(C++标准库预备役)
- QT+VTK+PCL实现交互式点云平面切割
- 最近编写过程中遇到的问题总结(在练习qt pcl vs vtk的融合中)
- 《PCL点云库学习&VS2010(X64)》Part 5 VTK6.2+VS2013+Qt5.5 测试VTK基于VS2013的Qt程序
- PCL 学习笔记-使用 PCL 来显示点云
- pcl库的配置
- 获取所在地的省份和ip
- 欢迎使用CSDN-markdown编辑器
- 质量的三要素
- PAT乙级1025. 反转链表 (25)
- session总结
- PCL Save VTK File With Texture Coordinates 使用PCL库来保存带纹理坐标的VTK文件
- hdu 2159 FATE 二维完全背包
- error: Couldn't start Appium REST http interface listener. Requested port is already in use. Please
- 现在这里记录我自己的学习历程吧
- vue与cordova整合,生成webapp
- Netty入门应用
- 编程之战第六章 负数项斐波那契
- sunxi-tools修改script.bin
- GSF 入门教程