下面是一个简单的读取PCD文件并显示的代码:

  1. #include <iostream>
  2.  
  3. #include <pcl/io/pcd_io.h>
  4. #include <pcl/point_types.h>
  5. #include <boost/thread/thread.hpp>
  6. #include <pcl/visualization/pcl_visualizer.h>
  7.  
  8. void main()
  9. {
  10. /* Create Point Cloud */
  11. pcl::PointCloud<pcl::PointXYZRGBA>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGBA>);
  12.  
  13. /* Read PCD File */
  14. /* Read Wrong */
  15. if (- == pcl::io::loadPCDFile<pcl::PointXYZRGBA>("table_scene_lms400.pcd", *cloud))
  16. {
  17. return;
  18. }
  19.  
  20. /* Then show the point cloud */
  21. boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("office chair model"));
  22. viewer->setBackgroundColor(, , );
  23.  
  24. pcl::visualization::PointCloudColorHandlerRGBField<pcl::PointXYZRGBA> rgba(cloud); //Maybe set the cloud to he handler rgba?
  25. viewer->addPointCloud<pcl::PointXYZRGBA>(cloud, rgba, "sample cloud"); //Add a Point Cloud (templated) to screen. Q:Some questions here
  26. viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, , "sample cloud"); //Set the rendering properties
  27.  
  28. //viewer->addCoordinateSystem(1.0); //Adds 3D axes describing a coordinate system to screen at 0,0,0
  29. viewer->initCameraParameters (); //Initialize camera parameters with some default values.
  30.  
  31. /* Show the point cloud */
  32. while (!viewer->wasStopped ())
  33. {
  34. viewer->spinOnce (); //updates the screen loop
  35. boost::this_thread::sleep (boost::posix_time::microseconds ());
  36. }
  37. }
  1. pcl::io::loadPCDFile用于读取一个PCD文件至一个PointCloud类型,这里就是将table_scene_lms400.pcd文件里的数据读取至cloud里。
  1. PCL文档里关于pcl::io::loadPCDFile的实现有3个,我目前只看了第一种。
  1.  
  1. 下面看看loadPCDFilenamespace io里的实现:

template<typename PointT> inline int
loadPCDFile (const std::string &file_name, pcl::PointCloud<PointT> &cloud)
{
    pcl::PCDReader p;
    return (p.read (file_name, cloud));
}

可以看到loadPCDFile 这个内联函数,就是调用了一下pcl::PCDReader里的read函数。

继续看PCDReader函数:

  1. template<typename PointT> int
  2. read (const std::string &file_name, pcl::PointCloud<PointT> &cloud, const int offset = 0)
  3. {
  4. pcl::PCLPointCloud2 blob;
  5. int pcd_version;
  6. int res = read (file_name, blob, cloud.sensor_origin_, cloud.sensor_orientation_, pcd_version, offset);
  7.  
  8. // If no error, convert the data
  9. if (res == 0)
  10. pcl::fromPCLPointCloud2 (blob, cloud);
  11. return (res);
    }

最后在pdc_io.cpp里找到代码:

  1. int
  2. pcl::PCDReader::read (const std::string &file_name, pcl::PCLPointCloud2 &cloud,
  3. Eigen::Vector4f &origin, Eigen::Quaternionf &orientation, int &pcd_version,
  4. const int offset)
  5. {
  6. pcl::console::TicToc tt;
  7. tt.tic ();
  8.  
  9. int data_type;
  10. unsigned int data_idx;
  11.  
  12. int res = readHeader (file_name, cloud, origin, orientation, pcd_version, data_type, data_idx, offset);
  13.  
  14. if (res < )
  15. return (res);
  16.  
  17. unsigned int idx = ;
  18.  
  19. // Get the number of points the cloud should have
  20. unsigned int nr_points = cloud.width * cloud.height;
  21.  
  22. // Setting the is_dense property to true by default
  23. cloud.is_dense = true;
  24.  
  25. if (file_name == "" || !boost::filesystem::exists (file_name))
  26. {
  27. PCL_ERROR ("[pcl::PCDReader::read] Could not find file '%s'.\n", file_name.c_str ());
  28. return (-);
  29. }
  30.  
  31. // if ascii
  32. if (data_type == )
  33. {
  34. // Re-open the file (readHeader closes it)
  35. std::ifstream fs;
  36. fs.open (file_name.c_str ());
  37. if (!fs.is_open () || fs.fail ())
  38. {
  39. PCL_ERROR ("[pcl::PCDReader::read] Could not open file %s.\n", file_name.c_str ());
  40. return (-);
  41. }
  42.  
  43. fs.seekg (data_idx);
  44.  
  45. std::string line;
  46. std::vector<std::string> st;
  47.  
  48. // Read the rest of the file
  49. try
  50. {
  51. while (idx < nr_points && !fs.eof ())
  52. {
  53. getline (fs, line);
  54. // Ignore empty lines
  55. if (line == "")
  56. continue;
  57.  
  58. // Tokenize the line
  59. boost::trim (line);
  60. boost::split (st, line, boost::is_any_of ("\t\r "), boost::token_compress_on);
  61.  
  62. if (idx >= nr_points)
  63. {
  64. PCL_WARN ("[pcl::PCDReader::read] input file %s has more points (%d) than advertised (%d)!\n", file_name.c_str (), idx, nr_points);
  65. break;
  66. }
  67.  
  68. size_t total = ;
  69. // Copy data
  70. for (unsigned int d = ; d < static_cast<unsigned int> (cloud.fields.size ()); ++d)
  71. {
  72. // Ignore invalid padded dimensions that are inherited from binary data
  73. if (cloud.fields[d].name == "_")
  74. {
  75. total += cloud.fields[d].count; // jump over this many elements in the string token
  76. continue;
  77. }
  78. for (unsigned int c = ; c < cloud.fields[d].count; ++c)
  79. {
  80. switch (cloud.fields[d].datatype)
  81. {
  82. case pcl::PCLPointField::INT8:
  83. {
  84. copyStringValue<pcl::traits::asType<pcl::PCLPointField::INT8>::type> (
  85. st.at (total + c), cloud, idx, d, c);
  86. break;
  87. }
  88. case pcl::PCLPointField::UINT8:
  89. {
  90. copyStringValue<pcl::traits::asType<pcl::PCLPointField::UINT8>::type> (
  91. st.at (total + c), cloud, idx, d, c);
  92. break;
  93. }
  94. case pcl::PCLPointField::INT16:
  95. {
  96. copyStringValue<pcl::traits::asType<pcl::PCLPointField::INT16>::type> (
  97. st.at (total + c), cloud, idx, d, c);
  98. break;
  99. }
  100. case pcl::PCLPointField::UINT16:
  101. {
  102. copyStringValue<pcl::traits::asType<pcl::PCLPointField::UINT16>::type> (
  103. st.at (total + c), cloud, idx, d, c);
  104. break;
  105. }
  106. case pcl::PCLPointField::INT32:
  107. {
  108. copyStringValue<pcl::traits::asType<pcl::PCLPointField::INT32>::type> (
  109. st.at (total + c), cloud, idx, d, c);
  110. break;
  111. }
  112. case pcl::PCLPointField::UINT32:
  113. {
  114. copyStringValue<pcl::traits::asType<pcl::PCLPointField::UINT32>::type> (
  115. st.at (total + c), cloud, idx, d, c);
  116. break;
  117. }
  118. case pcl::PCLPointField::FLOAT32:
  119. {
  120. copyStringValue<pcl::traits::asType<pcl::PCLPointField::FLOAT32>::type> (
  121. st.at (total + c), cloud, idx, d, c);
  122. break;
  123. }
  124. case pcl::PCLPointField::FLOAT64:
  125. {
  126. copyStringValue<pcl::traits::asType<pcl::PCLPointField::FLOAT64>::type> (
  127. st.at (total + c), cloud, idx, d, c);
  128. break;
  129. }
  130. default:
  131. PCL_WARN ("[pcl::PCDReader::read] Incorrect field data type specified (%d)!\n",cloud.fields[d].datatype);
  132. break;
  133. }
  134. }
  135. total += cloud.fields[d].count; // jump over this many elements in the string token
  136. }
  137. idx++;
  138. }
  139. }
  140. catch (const char *exception)
  141. {
  142. PCL_ERROR ("[pcl::PCDReader::read] %s\n", exception);
  143. fs.close ();
  144. return (-);
  145. }
  146.  
  147. // Close file
  148. fs.close ();
  149. }
  150. else
  151. /// ---[ Binary mode only
  152. /// We must re-open the file and read with mmap () for binary
  153. {
  154. // Open for reading
  155. int fd = pcl_open (file_name.c_str (), O_RDONLY);
  156. if (fd == -)
  157. {
  158. PCL_ERROR ("[pcl::PCDReader::read] Failure to open file %s\n", file_name.c_str () );
  159. return (-);
  160. }
  161.  
  162. // Seek at the given offset
  163. off_t result = pcl_lseek (fd, offset, SEEK_SET);
  164. if (result < )
  165. {
  166. pcl_close (fd);
  167. PCL_ERROR ("[pcl::PCDReader::read] lseek errno: %d strerror: %s\n", errno, strerror (errno));
  168. PCL_ERROR ("[pcl::PCDReader::read] Error during lseek ()!\n");
  169. return (-);
  170. }
  171.  
  172. size_t data_size = data_idx + cloud.data.size ();
  173. // Prepare the map
  174. #ifdef _WIN32
  175. // As we don't know the real size of data (compressed or not),
  176. // we set dwMaximumSizeHigh = dwMaximumSizeLow = 0 so as to map the whole file
  177. HANDLE fm = CreateFileMapping ((HANDLE) _get_osfhandle (fd), NULL, PAGE_READONLY, , , NULL);
  178. // As we don't know the real size of data (compressed or not),
  179. // we set dwNumberOfBytesToMap = 0 so as to map the whole file
  180. char *map = static_cast<char*>(MapViewOfFile (fm, FILE_MAP_READ, , , ));
  181. if (map == NULL)
  182. {
  183. CloseHandle (fm);
  184. pcl_close (fd);
  185. PCL_ERROR ("[pcl::PCDReader::read] Error mapping view of file, %s\n", file_name.c_str ());
  186. return (-);
  187. }
  188. #else
  189. char *map = static_cast<char*> (mmap (, data_size, PROT_READ, MAP_SHARED, fd, ));
  190. if (map == reinterpret_cast<char*> (-)) // MAP_FAILED
  191. {
  192. pcl_close (fd);
  193. PCL_ERROR ("[pcl::PCDReader::read] Error preparing mmap for binary PCD file.\n");
  194. return (-);
  195. }
  196. #endif
  197.  
  198. /// ---[ Binary compressed mode only
  199. if (data_type == )
  200. {
  201. // Uncompress the data first
  202. unsigned int compressed_size, uncompressed_size;
  203. memcpy (&compressed_size, &map[data_idx + ], sizeof (unsigned int));
  204. memcpy (&uncompressed_size, &map[data_idx + ], sizeof (unsigned int));
  205. PCL_DEBUG ("[pcl::PCDReader::read] Read a binary compressed file with %u bytes compressed and %u original.\n", compressed_size, uncompressed_size);
  206. // For all those weird situations where the compressed data is actually LARGER than the uncompressed one
  207. // (we really ought to check this in the compressor and copy the original data in those cases)
  208. if (data_size < compressed_size || uncompressed_size < compressed_size)
  209. {
  210. PCL_DEBUG ("[pcl::PCDReader::read] Allocated data size (%zu) or uncompressed size (%zu) smaller than compressed size (%u). Need to remap.\n", data_size, uncompressed_size, compressed_size);
  211. #ifdef _WIN32
  212. UnmapViewOfFile (map);
  213. data_size = compressed_size + data_idx + ;
  214. map = static_cast<char*>(MapViewOfFile (fm, FILE_MAP_READ, , , data_size));
  215. #else
  216. munmap (map, data_size);
  217. data_size = compressed_size + data_idx + ;
  218. map = static_cast<char*> (mmap (, data_size, PROT_READ, MAP_SHARED, fd, ));
  219. #endif
  220. }
  221.  
  222. if (uncompressed_size != cloud.data.size ())
  223. {
  224. PCL_WARN ("[pcl::PCDReader::read] The estimated cloud.data size (%u) is different than the saved uncompressed value (%u)! Data corruption?\n",
  225. cloud.data.size (), uncompressed_size);
  226. cloud.data.resize (uncompressed_size);
  227. }
  228.  
  229. char *buf = static_cast<char*> (malloc (data_size));
  230. // The size of the uncompressed data better be the same as what we stored in the header
  231. unsigned int tmp_size = pcl::lzfDecompress (&map[data_idx + ], compressed_size, buf, static_cast<unsigned int> (data_size));
  232. if (tmp_size != uncompressed_size)
  233. {
  234. free (buf);
  235. pcl_close (fd);
  236. PCL_ERROR ("[pcl::PCDReader::read] Size of decompressed lzf data (%u) does not match value stored in PCD header (%u). Errno: %d\n", tmp_size, uncompressed_size, errno);
  237. return (-);
  238. }
  239.  
  240. // Get the fields sizes
  241. std::vector<pcl::PCLPointField> fields (cloud.fields.size ());
  242. std::vector<int> fields_sizes (cloud.fields.size ());
  243. int nri = , fsize = ;
  244. for (size_t i = ; i < cloud.fields.size (); ++i)
  245. {
  246. if (cloud.fields[i].name == "_")
  247. continue;
  248. fields_sizes[nri] = cloud.fields[i].count * pcl::getFieldSize (cloud.fields[i].datatype);
  249. fsize += fields_sizes[nri];
  250. fields[nri] = cloud.fields[i];
  251. ++nri;
  252. }
  253. fields.resize (nri);
  254. fields_sizes.resize (nri);
  255.  
  256. // Unpack the xxyyzz to xyz
  257. std::vector<char*> pters (fields.size ());
  258. int toff = ;
  259. for (size_t i = ; i < pters.size (); ++i)
  260. {
  261. pters[i] = &buf[toff];
  262. toff += fields_sizes[i] * cloud.width * cloud.height;
  263. }
  264. // Copy it to the cloud
  265. for (size_t i = ; i < cloud.width * cloud.height; ++i)
  266. {
  267. for (size_t j = ; j < pters.size (); ++j)
  268. {
  269. memcpy (&cloud.data[i * fsize + fields[j].offset], pters[j], fields_sizes[j]);
  270. // Increment the pointer
  271. pters[j] += fields_sizes[j];
  272. }
  273. }
  274. //memcpy (&cloud.data[0], &buf[0], uncompressed_size);
  275.  
  276. free (buf);
  277. }
  278. else
  279. // Copy the data
  280. memcpy (&cloud.data[], &map[] + data_idx, cloud.data.size ());
  281.  
  282. // Unmap the pages of memory
  283. #ifdef _WIN32
  284. UnmapViewOfFile (map);
  285. CloseHandle (fm);
  286. #else
  287. if (munmap (map, data_size) == -)
  288. {
  289. pcl_close (fd);
  290. PCL_ERROR ("[pcl::PCDReader::read] Munmap failure\n");
  291. return (-);
  292. }
  293. #endif
  294. pcl_close (fd);
  295. }
  296.  
  297. if ((idx != nr_points) && (data_type == ))
  298. {
  299. PCL_ERROR ("[pcl::PCDReader::read] Number of points read (%d) is different than expected (%d)\n", idx, nr_points);
  300. return (-);
  301. }
  302.  
  303. // No need to do any extra checks if the data type is ASCII
  304. if (data_type != )
  305. {
  306. int point_size = static_cast<int> (cloud.data.size () / (cloud.height * cloud.width));
  307. // Once copied, we need to go over each field and check if it has NaN/Inf values and assign cloud.is_dense to true or false
  308. for (uint32_t i = ; i < cloud.width * cloud.height; ++i)
  309. {
  310. for (unsigned int d = ; d < static_cast<unsigned int> (cloud.fields.size ()); ++d)
  311. {
  312. for (uint32_t c = ; c < cloud.fields[d].count; ++c)
  313. {
  314. switch (cloud.fields[d].datatype)
  315. {
  316. case pcl::PCLPointField::INT8:
  317. {
  318. if (!isValueFinite<pcl::traits::asType<pcl::PCLPointField::INT8>::type>(cloud, i, point_size, d, c))
  319. cloud.is_dense = false;
  320. break;
  321. }
  322. case pcl::PCLPointField::UINT8:
  323. {
  324. if (!isValueFinite<pcl::traits::asType<pcl::PCLPointField::UINT8>::type>(cloud, i, point_size, d, c))
  325. cloud.is_dense = false;
  326. break;
  327. }
  328. case pcl::PCLPointField::INT16:
  329. {
  330. if (!isValueFinite<pcl::traits::asType<pcl::PCLPointField::INT16>::type>(cloud, i, point_size, d, c))
  331. cloud.is_dense = false;
  332. break;
  333. }
  334. case pcl::PCLPointField::UINT16:
  335. {
  336. if (!isValueFinite<pcl::traits::asType<pcl::PCLPointField::UINT16>::type>(cloud, i, point_size, d, c))
  337. cloud.is_dense = false;
  338. break;
  339. }
  340. case pcl::PCLPointField::INT32:
  341. {
  342. if (!isValueFinite<pcl::traits::asType<pcl::PCLPointField::INT32>::type>(cloud, i, point_size, d, c))
  343. cloud.is_dense = false;
  344. break;
  345. }
  346. case pcl::PCLPointField::UINT32:
  347. {
  348. if (!isValueFinite<pcl::traits::asType<pcl::PCLPointField::UINT32>::type>(cloud, i, point_size, d, c))
  349. cloud.is_dense = false;
  350. break;
  351. }
  352. case pcl::PCLPointField::FLOAT32:
  353. {
  354. if (!isValueFinite<pcl::traits::asType<pcl::PCLPointField::FLOAT32>::type>(cloud, i, point_size, d, c))
  355. cloud.is_dense = false;
  356. break;
  357. }
  358. case pcl::PCLPointField::FLOAT64:
  359. {
  360. if (!isValueFinite<pcl::traits::asType<pcl::PCLPointField::FLOAT64>::type>(cloud, i, point_size, d, c))
  361. cloud.is_dense = false;
  362. break;
  363. }
  364. }
  365. }
  366. }
  367. }
  368. }
  369. double total_time = tt.toc ();
  370. PCL_DEBUG ("[pcl::PCDReader::read] Loaded %s as a %s cloud in %g ms with %d points. Available dimensions: %s.\n",
  371. file_name.c_str (), cloud.is_dense ? "dense" : "non-dense", total_time,
  372. cloud.width * cloud.height, pcl::getFieldsList (cloud).c_str ());
  373. return ();
  374. }

这里的大致流程就是:

1.读取PCD和Header;

2.Header里的data有ascii还是binary两种情况,根据其不同采取不同的方法读取剩余的内容;

3.binary数据的情况还需要对数据进行check;

这段代码的细节处理暂时先这样了,以后再看看为什么ascii和binary的处理不一样,有什么不一样。

(一)读取PCD文件的更多相关文章

  1. PCD文件格式详解及在PCL下读取PCD文件

    一.PCD简介 1.1 PCD版本 在点云库PCL 1.0发布之前,PCD文件格式就已经发展更新了许多版本.这些新旧不同的版本用PCD_Vx来编号(例如PCD_V5.PCD_V6和PCD_V7等),分 ...

  2. PCL读取PCD文件的数据

    1.pcd文件——rabbit.pcd 链接:https://pan.baidu.com/s/1v6mjPjwd7fIqUSjlIGTIGQ提取码:zspx 新建项目pcl rabbit.pcd 和p ...

  3. PCL点云库中怎样读取指定的PCD文件,又一次命名,处理后保存到指定目录

    我一直想把处理后的pcd文件重命名,然后放到指定的目录,尝试了好久最终做到了: 比方我想读取  "table_scene_lms400.pcd" 把它进行滤波处理,重命名为 &qu ...

  4. 从PCD文件写入和读取点云数据

    (1)学习向PCD文件写入点云数据 建立工程文件ch2,然后新建write_pcd.cpp  CMakeLists.txt两个文件 write_pcd.cpp : #include <iostr ...

  5. 从PCD文件中读取点云数据

    博客转载自:http://www.pclcn.org/study/shownews.php?lang=cn&id=84 在本小节我们学习如何从PCD文件中读取点云数据. 代码 章例1文件夹中, ...

  6. Unity3D移动平台动态读取外部文件全解析

    前言: 一直有个想法,就是把工作中遇到的坑通过自己的深挖,总结成一套相同问题的解决方案供各位同行拍砖探讨.眼瞅着2015年第一个工作日就要来到了,小匹夫也休息的差不多了,寻思着也该写点东西活动活动大脑 ...

  7. PCD文件去除曲率的脚本

    在写一个重建算法的时候需要用到点坐标和法向的数据文件,于是向利用pcl中的法向计算模块来生成法向.输出后法向文件中包含曲率信息,但是这是不需要的.于是自己写了一个python小脚本实现格式转换. #- ...

  8. python读取caffemodel文件

    caffemodel是二进制的protobuf文件,利用protobuf的python接口可以读取它,解析出需要的内容 不少算法都是用预训练模型在自己数据上微调,即加载"caffemodel ...

  9. informatica读取FTP文件

    以下为一个完整的informatica读取ftp文件,并导入到系统中. 第一步: 通过shell脚本下载压缩包文件 /server/infa_shared/crm_prod/shell/ftpFrom ...

随机推荐

  1. SQL中EXISTS怎么用[转]

    SQL中EXISTS怎么用 1 2 3 4 分步阅读 EXISTS用于检查子查询是否至少会返回一行数据,该子查询实际上并不返回任何数据,而是返回值True或False 方法/步骤 1 EXISTS用于 ...

  2. ELK日志管理之——logstash配置语法

    Logstash 设计了自己的 DSL -- 有点像 Puppet 的 DSL,或许因为都是用 Ruby 语言写的吧 -- 包括有区域,注释,数据类型(布尔值,字符串,数值,数组,哈希),条件判断,字 ...

  3. Unity 之 Shader 对Z深度的偏移

    对Z深度的偏移 Offset 指令给了我们一个操作正常的ZTest 检测结果的手段. Offset有两个参数,这两个参数理解起来不是很直观,而且具体实现是和硬件相关的 下面在实际例子中看他的效果 Sh ...

  4. Spring ioc容器

    一.ioc容器 ioc (inversion of  control)即控制反转,把某一个接口选择实现类的控制权转移给Spring容器来管理.调用类对该实现类的依赖关系由ioc容器注入(DI),传统的 ...

  5. 基于Xenomai和工控机的实时测控系统的研究

    http://www.docin.com/p-1006254643-f6.html

  6. [04]APUE:文件与目录

    [a] stat / lstat / fstat #include <sys/stat.h> int stat(const char *restrict pathname, struct ...

  7. android杂记

    1.ArrayAdapter requires the resource ID to be a TextView问题 listView.setAdapter(new ArrayAdapter<S ...

  8. Jpanel和container和jframe的区别

    Jpanel和container和jframe的区别 (2012-05-23 19:15:11) 转载▼ 标签: 杂谈 分类: room 看到上上面的几张图,container容器是位于最高层. 下面 ...

  9. OD使用教程11

    首先把安装好的软件拖入PEID,看看它是用什么语言写的    然后用OD载入程序,查找关键字,步骤看上一个笔记 双击到达代码处,发现这在一个跳转里面.可能第一反应是修改跳转,经试验后发现这是没用的所以 ...

  10. GCC4.8.2升级安装

    一.查看本机GCC版本: 使用gcc -v 查看本机版本信息,我的gcc版本为: gcc 版本 4.4.6 20120305 (Red Hat 4.4.6-4) (GCC) 二.升级或安装编译器: 1 ...