PCL Save VTK File With Texture Coordinates 使用PCL库来保存带纹理坐标的VTK文件
我之前有一篇博客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.0int 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 informationfs << "# vtk DataFile Version 3.0\nvtk output\nASCII\nDATASET POLYDATA\nPOINTS " << nr_points << " float" << std::endl;// Iterate through the pointsfor (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 verticesfs << "\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 coordinatesfs << "\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.0 int 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 informationfs << "# vtk DataFile Version 3.0\nvtk output\nASCII\nDATASET POLYDATA\nPOINTS " << nr_points << " float" << '\n';// Iterate through the pointsfor (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 verticesfs << "\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 coordinatesfs << "\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); }
注意上面纹理的x和y的值,根据贴图的情况来看是否需要调换位置。
转载于:https://www.cnblogs.com/grandyang/p/6546701.html
PCL Save VTK File With Texture Coordinates 使用PCL库来保存带纹理坐标的VTK文件相关推荐
- PCL读取带rgb信息的asc文件C++
PCL读取带rgb信息的asc文件 基本描述 代码与使用 基本描述 本代码适用于x y z r g b格式的asc文件,如果读者的asc文件是其他的格式,请修改相应的代码.其实整个代码的核心是将r g ...
- matlab保存数据用什么指令_MATLAB文件操作及保存文件save load fopen | 学步园
一.保存文件 1.保存整个工作区 File->Save Workspace as...一个.mat文件 2.保存工作区的变量 在左工作区右击变量名,create M-File 3.save命令 ...
- R语言构建xgboost模型:模型的保存(xgb.save)和加载(xgb.load)、或者保存为R二进制文件(xgb.save.raw R binary vector)
R语言构建xgboost模型:模型的保存(xgb.save)和加载(xgb.load).或者保存为R二进制文件(xgb.save.raw,R binary vector) 目录
- OpenGL Texture Coordinates纹理坐标的实例
OpenGL simpletexcoords 先上图,再解答. 完整主要的源代码 源代码剖析 先上图,再解答. 完整主要的源代码 #include <vmath.h> #include & ...
- new file https 找不到路径_Python3用pathlib模块替代os.path进行文件路径的操作
本文使用 Zhihu On VSCode 创作并发布 在 Python 3.4 之前和路径相关操作函数都放在 os 模块里面,尤其是os.path这个子模块,可以说os.path模块非常常用.而在 P ...
- PCL之Ubuntu16.04下编译libfreenect2和PCL以支持KinectV2点云处理
转载于: https://shenxiaohai.me/2018/04/26/Ubuntu-freenect2-PCL/ 原因就是由于 OpenNI2.2 不支持 Kinect V2,导致我没法在 P ...
- pcl启动java代码_我的世界PCL启动器-Plain Craft Launcher(PCL启动器)下载 v1.0.9免费版--pc6下载站...
PlainCraftLauncherPCL启动器是我的世界游戏的一款启动器,免费.开源,支持在线/离线两种模式,即使你没有网络,也可以畅玩,允许玩家方便快捷地安装.管理.运行游戏. Plain Cra ...
- python中file是什么意思中文_15_【Python学习分享文章】_file(文件)及其操作
综述 - file(文件)的含义 Python 中的 file 不止使用 PC 时所说的单个文件,比如 .txt..exe 等这类文件,也包括"打开一个网址".程序间的通信数据等, ...
- android 录像工具,Android 屏幕录制(Surface\ Texture 录制)工具库
你是否常常因为产品需要录制屏幕而不要状态栏而烦闷 ?? 你是不是常常因为产品需要录制直播视频而加班 ?? 你是不是常常因为要对一个surface同时录制两种Texture 分别存在的视频 (!!??? ...
- Unity3d 导入图片 自动修改Texture Type为Sprite (2D and UI) 及设置 Packing Tag为文件夹名
版权声明:本文转自http://blog.csdn.net/huutu 转载请带上 http://www.liveslives.com/ http://blog.csdn.net/huutu/arti ...
最新文章
- 字节开启员工期权兑换,126美元每股;
- 欧拉函数/欧拉函数打表 lightoj1370(java/c++ )
- android模拟器启动没有拨号功能
- 程序员的职业素养-读书笔记
- C#基础之如何判断两个文件内容是否相同
- python为什么没有指针_Python 没有指针,如何解算法题?
- 操作系统Ubuntu(实验三四)
- Linux start-kernel
- python音乐推荐系统的设计与实现_基于协同过滤的音乐推荐系统
- 怎么用计算机知道密码,如何用电脑看到自家路由器的密码
- 解决方案:微信小程序下载文档出错downloadFile:fail url not in domain list
- 中企海外周报 | 华为在德国发布mate30系列手机;一汽新车亮相法兰克福车展
- Linux安装flux护眼软件
- 按月统计的sql语句
- HTML5设计更具有交互性的标签方法(含智能辅助设备使用的HTML5,翻译资料)
- java中between and什么意思,关于 oracle between and的用法!
- FME 安装破解及与ArGIS冲突的解决方法
- 新手做SEO迷茫时应该做什么
- Microsoft Project
- 循环神经网络-高级篇RNN Classifier
热门文章
- 微信小程序教程笔记5
- pytorch加载模型报错RuntimeError:Error(s) in loading state_dict for DataParallel
- Linux学习笔记(11)
- Caffe学习:Blobs, Layers, and Nets
- 基于深度学习的WLAN个体识别实践
- python中jieba分词快速入门
- 开源爬虫框架各有什么优缺点?
- java发送hotmail邮件,使用javamail将电子邮件发送到hotmail时遇到问题
- chrome 插件开发各种功能demo_Chrome扩展开发-编写一个浏览器插件
- latex 图片整行居中 /centering无效