本周主要任务:学习PCL点云库,掌握利用PCL对点云处理的方法

任务时间:2014年9月1日-2014年9月7日

任务完成情况:完成了读取单幅xml深度数据,并重建三维点云并显示

任务涉及基本方法:

  1.xml文件读取

    http://www.cnblogs.com/xzd1575/p/3958172.html

  2.OpenCV矩阵运算

    http://www.cnblogs.com/xzd1575/p/3959120.html

    http://www.cnblogs.com/xzd1575/p/3959113.html

  3.PCL点云基本数据类型

    http://www.cnblogs.com/xzd1575/p/3958192.html

    http://www.cnblogs.com/xzd1575/p/3959181.html

  4.CMake的基本使用方法

    http://www.cnblogs.com/xzd1575/p/3959223.html   

程序如下:(包含xml2pcd.cpp 和 CMakeLists.txt)

1.xml2pcd.cpp

  1. //xml2pcd.cpp
  2. //函数:main()
  3. //功能:从.xml文件导入一张深度图像数据,利用数据重建三维点云,并保存到.pcd文件中
  4. //输入:导入文件名,输出文件名 例:可执行文件根目录下,命令行输入 xml2pcd depth1.xml.
  5. //创建时间:2014/09/03
  6. //最近更新时间:2014/09/07
  7. //创建者:肖泽东
  8.  
  9. #include <iostream>
  10. #include <iomanip>
  11. #include <pcl/io/pcd_io.h>
  12. #include <pcl/io/io.h>
  13. #include <pcl/point_types.h>
  14. #include <pcl/visualization/cloud_viewer.h>
  15. #include <pcl/console/parse.h>
  16. #include <opencv2/opencv.hpp>
  17. #include <string>
  18. #include <stdexcept>
  19.  
  20. static const int depthWidth = ;
  21. static const int depthHeight = ;
  22.  
  23. void showHelp(char* program_name)
  24. {
  25. std::cout << std::endl;
  26. std::cout << "Usage: " << program_name << " depth_filename.xml " << std::endl;
  27. std::cout << "-h: Show this help." << std::endl;
  28. }
  29.  
  30. int main (int argc, char** argv)
  31. {
  32. // 显示帮助文档
  33. if(pcl::console::find_switch (argc,argv,"-h") || pcl::console::find_switch(argc,argv,"--help"))
  34. {
  35. showHelp(argv[]);
  36. return ;
  37. }
  38.  
  39. //从程序输入参量中获取深度文件名|xml 文件
  40. std::vector<int> filenames;
  41. bool file_is_xml = false;
  42.  
  43. filenames = pcl::console::parse_file_extension_argument(argc,argv,".xml");
  44.  
  45. if (filenames.size() != )
  46. {
  47. showHelp(argv[]);
  48. return -;
  49. }
  50. else
  51. {
  52. file_is_xml = true;
  53. }
  54.  
  55. //定义相关变量
  56. pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_ptr (new pcl::PointCloud<pcl::PointXYZ>);
  57. pcl::PointCloud<pcl::PointXYZ>& cloud = *cloud_ptr; //点云
  58. cv::FileStorage fs; //OpenCV 读XML文件流
  59. cv::Mat DepthData; //深度数据矩阵
  60. std::string filename = argv[filenames[]];
  61. // 待读取.XML文件名
  62.  
  63. //读取深度数据并显示深度图
  64. fs.open(filename,cv::FileStorage::READ); //打开指定.xml文件
  65. if(!fs.isOpened())
  66. {
  67. std::cerr << "Error: cannot open .xml file";
  68. return -;
  69. }
  70. fs["Depth_Data"] >> DepthData; //深度数据从文件导入至变量
  71. fs.release(); //释放xml文件
  72.  
  73. //使用内参数矩阵进行摄像机坐标下的重建
  74. //设置内参数矩阵,并对其求逆
  75. float fc[] ={366.4484,356.6881}; //内参数 焦距参数
  76. //float fc[2] = {0};
  77. float cc[] ={265.3251,208.0765}; //内参数 图像中心参数
  78. //float cc[2] = {0};
  79. float K[][] = {fc[], , cc[], , fc[], cc[], , , }; //摄像机内参数矩阵K
  80. cv::Mat mK = cv::Mat(,,CV_32FC1,K); //内参数K Mat类型变量
  81. cv::Mat mInvK(,,CV_32FC1);
  82.  
  83. //将K数组值赋给Mat变量mK,并打印显示内参数矩阵
  84. //std::cout << "The intrinsic parameter matrix is :" << std::endl;
  85. //std::cout << mK << std::endl;
  86.  
  87. //内参数矩阵mK求逆,并打印显示其逆矩阵
  88. try //异常处理 针对K为奇异矩阵不可逆的情况
  89. {
  90. if (invert(mK,mInvK,cv::DECOMP_LU)) //矩阵求逆,如果矩阵为奇异矩阵,条件不成立
  91. {
  92. //std::cout << mInvK << std::endl;//打印显示矩阵数据
  93. }
  94. else //K为奇异矩阵
  95. {
  96. throw std::invalid_argument("Error:Intrinsic parameter K is singular.");
  97. //抛出异常“K为奇异矩阵”
  98. }
  99. }
  100. catch(std::invalid_argument& e) //获取异常情况
  101. {
  102. std::cerr << e.what() << std::endl; //打印异常提醒
  103. return -;
  104. }
  105.  
  106. //初始化点云数据PCD文件头
  107. cloud.width = depthHeight * depthWidth;
  108. cloud.height = ;
  109. cloud.is_dense = false;
  110. cloud.points.resize (cloud.width * cloud.height);
  111.  
  112. //使用深度数据,重建三维点云
  113. int row = , col = , pointId = ;
  114. for (row = ;row < depthHeight;row++)// row == y 遍历深度矩阵所有行
  115. {
  116. unsigned short* data = DepthData.ptr<unsigned short>(row);
  117. for(col = ;col < depthWidth;col++)// col == x 遍历深度矩阵所有列
  118. {
  119. if(*data> && *data<) //取0.5m-1.5m范围深度数据
  120. {
  121. pointId ++;
  122. // [X,Y,Z]' = depth[x,y] * inv_K * [x,y,1]
  123. cloud.points[pointId].x = *data * (col * mInvK.at<float>(,) +
  124. row * mInvK.at<float>(,) + mInvK.at<float>(,)); //X
  125.  
  126. cloud.points[pointId].y = *data * (col * mInvK.at<float>(,) +
  127. row * mInvK.at<float>(,) + mInvK.at<float>(,)); //Y
  128.  
  129. cloud.points[pointId].z = *data; //Z
  130.  
  131. *data++ = (unsigned int)((*data - 500.0) * 255.0 / 1000.0) << ; //左移八位,data类型是16位,2^16 对应 256
  132. }
  133. else // 其他范围数据无操作
  134. {
  135. *data++ = ; //只显示对应区域的深度图
  136. }
  137. }
  138.  
  139. }
  140. //显示深度图
  141. cv::imshow(filename,DepthData);//显示截取深度数据
  142. cv::waitKey(); //等待50ms 用于等待显示完毕,防止显示图像不响应
  143.  
  144. //重新给pcd文件头赋值
  145. cloud.width = pointId; //unorgnized 数据,列宽即为点云个数,行数为1
  146. cloud.points.resize(cloud.width * cloud.height); //点云数据个数
  147.  
  148. //显示重建得到的点云数据
  149. pcl::visualization::CloudViewer viewer(filename);
  150. viewer.showCloud(cloud_ptr);
  151.  
  152. //保存点云数据
  153. pcl::io::savePCDFileASCII (filename+".pcd", cloud);
  154. std::cerr << "Saved " << cloud.points.size () << " data points to test_pcd.pcd." << std::endl;
  155.  
  156. //保持程序运行
  157. std::cout << std::endl << "Choose Depth Image Window and press ‘q’ to exit" << std::endl;
  158. while(!viewer.wasStopped())
  159. {
  160. if(cv::waitKey() == 'q')
  161. return();
  162. }
  163. return ();
  164. }

2.CMakeLists.txt

  1. cmake_minimum_required(VERSION 2.6 FATAL_ERROR)
  2.  
  3. project(Reseach_Project1)
  4.  
  5. find_package(PCL 1.3 REQUIRED)
  6. find_package(OpenCV REQUIRED)
  7.  
  8. include_directories(${PCL_INCLUDE_DIRS})
  9. link_directories(${PCL_LIBRARY_DIRS})
  10. add_definitions(${PCL_DEFINITIONS})
  11.  
  12. add_executable(xml2pcd xml2pcd.cpp)
  13. target_link_libraries(xml2pcd ${PCL_LIBRARIES} ${OpenCV_LIBS})

第一周:读取XML深度数据并将其重建为三维点云的更多相关文章

  1. C#读取xml节点数据方法小结

    本文实例总结了C#读取xml节点数据的方法.分享给大家供大家参考.具体如下: 第一种: 使用XPath XML的路径我配置在web.config 的appSettings节点下 <appSett ...

  2. JS读取XML文件数据并以table显示数据(兼容IE火狐)

    先看xml文件: <?xml version="1.0" standalone="yes"?> <student> <stuinf ...

  3. C# 递归读取XML菜单数据

    在博客园注册了有4年了,很遗憾至今仍未发表过博客,趁周末有空发表第一篇博客.小生不才,在此献丑了! 最近在研究一些关于C#的一些技术,纵观之前的开发项目的经验,做系统时显示系统菜单的功能总是喜欢把数据 ...

  4. JAVA读取XML文件数据

    XML文档内容如下: <?xml version="1.0" encoding="UTF-8"?> <root> <field t ...

  5. PHP读取XML文件数据

    XML文件 <?xml version="1.0" encoding="UTF-8"?> <node> <student> ...

  6. PLSQL读取XML的数据

    最近公司做的几个项目,都是通过EBS与外部系统的Web Service进行数据的交互,而调用Web Service的时候,我们所传送的数据,都是按照约定的XML格式来传递,所以EBS接收到数据之后,需 ...

  7. Python中如何读取xml的数据

    <?xml version="1.0" encoding="utf-8" ?> - <catalog> <maxid>4&l ...

  8. R语言XML格式数据导入与处理

    数据解析 XML是一种可扩展标记语言,它被设计用来传输和存储数据.XML是各种应用程序之间进行数据传输的最常用的工具.它与Access,Oracle和SQL Server等数据库不同,数据库提供了更强 ...

  9. jQuery、JS读取xml文件里的内容(JS先通过document.implementation.createDocument方法将xml转换成document对象,jQuery将读取到的xml转成table)

    xml文件:test.xml <?xml version="1.0"?> <note> <to>George</to> <fr ...

随机推荐

  1. HDU 5744 Keep On Movin

    Keep On Movin Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Tot ...

  2. delphi 操作 word

        uses  ComObj,word2000   procedure TForm1.ExportWord(); var FWord :Variant; FDoc :Variant; i,Row: ...

  3. 使用IP欺骗Loadrunner并发测试小结

    测试要求:   在本次测试中,我需要并发50个User,每一个User占用一个独立的IP,并且只执行一次脚本.脚本中发起两个请求,其中第一次请求返回200后才执行第二个请求.使用win7 OS.   ...

  4. QT4.7.4-vs2008和vs2010的安装并编写测试程序

    QT的安装着实费了我好大的劲,之前试过QT5.1.0与VS2010的安装,但是因为设置的地方太多,程序运行总是不成功,所以最后选用QT4.7.4和VS2008与VS2010来编写程序.写这篇文章来总结 ...

  5. VS中使用QT调用R脚本

    一开始想直接把R编译成库然后调用R,后来查了n多资料,发现VS中是无法办到的,官方也给出了一句话,大概意思就是没可能在VS中使用R提供的C++接口,大概是涉及到了底层的ABI的原因,具体也不太清楚. ...

  6. mybatis系列-13-resultMap总结

    resultType: 作用: 将查询结果按照sql列名pojo属性名一致性映射到pojo中. 场合: 常见一些明细记录的展示,比如用户购买商品明细,将关联查询信息全部展示在页面时,此时可直接使用re ...

  7. Azure终于支持大容量虚拟机了-最高32核,448G内存

    Azure终于支持大容量虚拟机了-最高32核,448G内存 最近微软Azure虚拟机旗下的大容量G系列虚拟机通用版本正式上线.G系列虚拟机方案提供公有云领域最大的内存容量.最强处理能力以及空间可观的本 ...

  8. Linux服务器集群系统(一)(转)

    add by zhj:虽然是2002年的文章,但读来还是收益良多.在 章文嵩:谈LVS及阿里开源背后的精彩故事 中LVS发起人及主要贡献者谈了LVS的开发过程及阿里开源的一些故事 原文:http:// ...

  9. Spring+Quartz 整合二:调度管理与定时任务分离

    新的应用场景:很多时候,我们常常会遇到需要动态的添加或修改任务,而spring中所提供的定时任务组件却只能够通过修改xml中trigger的配置才能控制定时任务的时间以及任务的启用或停止,这在带给我们 ...

  10. 问题-XE8报Object factory for class{xx-xx-xx-xx-xx} is missing. To register it, you can drop component[TFDGUIxWaitCursor] into your project.

    问题现象:XE8开发数据访问程序时放入了FDPhysMSSQLDriverLink1.FDConnection1.FDConnection1.FDQuery1.DBGrid1,设计期没法,运行期报&q ...