S3DIS数据集解析为点云

  • S3DIS数据集解析
      • 数据格式
    • 1.直接解析pointcloud.mat文件
    • 2.通过data文件夹中的pose合成rgb和depth

个人解析代码GitHub:https://github.com/ybgdgh/s3dis_semantic

S3DIS数据集解析

S3DIS数据集是斯坦福大学开发的带有像素级语义标注的语义数据集,包含了rgb,depth,3d点云、mesh等。

官网:http://buildingparser.stanford.edu/dataset.html

官网github:https://github.com/alexsax/2D-3D-Semantics

数据格式

还原点云数据有多种方式,可以通过直接解析自带的mat文件进行解析,也可以通过合成rgb和深度图进行解析。本文以Area_1数据为例。

1.直接解析pointcloud.mat文件

数据集自带的mat文件包含了每一label的点云坐标、rgb,标注、物体体积、是否占有能属性组成。数据结构如下:

该mat文件包含一个struct结构体,结构体又往下分级。

可以用python直接解析该mat文件,本人对python不太熟悉,因此最后采用了将该mat文件转化为json脚本的形式,通过c++进行解析。

通过matlab解析json非常简单,只需要下载安装一个插件JSONlab,对应链接:https://github.com/fangq/jsonlab/#installation,

添加到matlab的toolkit文件加中,再将路径添加进行即可。matlab程序如下:

load('pointcloud.mat')
name_ALL = Area_1.Disjoint_Space;
for i=1:1:44name=savejson('',name_ALL(i));fid=fopen(['Adata_',num2str(i),'.json'],'w+');fprintf(fid,'%s',name);fclose(fid);fprintf('%s \n',i);
end

本次只针对一个场景即Area_1进行解析,因此只采集了object所有对象下的结构体,该结构体下又包含多个子类,每一类都有对应的一套属性。

每个对象的内容如下:

{"name": "conferenceRoom_1","AlignmentAngle": -0,"color": [0.5,0.5,0],"object": [{"name": "beam_1","RGB_color": [[71,64,54],[68,64,52],......[-15.296,40.53,2.19]]]}]
}

object结构体下包含了其他如坐标、Voxels等信息。在这里将所有对象的数据分别存入不同文件(避免文件过大)


通过这种方式,将点云文件转化为json格式,再通过c++读取即可。程序如下:

json解析函数根据官方提供的代码进行了修改,官方代码只是用来解析pose.josn数据的,这里用boost::property_tree::ptree来解析json格式。

#ifndef SEMANTIC2D3D_UTILS_H
#define SEMANTIC2D3D_UTILS_H#include <iostream>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <pcl/common/eigen.h>
#include <iostream>
#include <boost/foreach.hpp>
#include <vector>namespace Utils
{/** Gets the RGB_color from a pose file ptree and returns it**/
inline bool
getRGBcolor(const boost::property_tree::ptree &pt, std::vector<Eigen::Vector3d> &RGB)
{// Read in RGB_colorEigen::Vector3d rgb_point;int i = 0;boost::property_tree::ptree object = pt.get_child("object");BOOST_FOREACH (boost::property_tree::ptree::value_type &vtt, object){boost::property_tree::ptree pt_tree = vtt.second;boost::property_tree::ptree RGB_color = pt_tree.get_child("RGB_color");BOOST_FOREACH (boost::property_tree::ptree::value_type &v, RGB_color){boost::property_tree::ptree tree = v.second;BOOST_FOREACH (boost::property_tree::ptree::value_type &vt, tree){rgb_point[i] = vt.second.get_value<float>();i++;}i = 0;// std::cout << rgb_point.transpose() << std::endl;RGB.push_back(rgb_point);}}return true;
}inline bool
getXYZpoints(const boost::property_tree::ptree &pt, std::vector<Eigen::Vector3d> &XYZ)
{// Read in XYZ_colorEigen::Vector3d xyz_point;int i = 0;boost::property_tree::ptree object = pt.get_child("object");BOOST_FOREACH (boost::property_tree::ptree::value_type &vtt, object){boost::property_tree::ptree pt_tree = vtt.second;boost::property_tree::ptree point = pt_tree.get_child("points");BOOST_FOREACH (boost::property_tree::ptree::value_type &v, point){boost::property_tree::ptree tree = v.second;BOOST_FOREACH (boost::property_tree::ptree::value_type &vt, tree){xyz_point[i] = vt.second.get_value<float>();i++;}i = 0;// std::cout << rgb_point.transpose() << std::endl;XYZ.push_back(xyz_point);}}return true;
}/** Load in the json pose files into a boost::ptree **/
inline boost::property_tree::ptree
loadPoseFile(const std::string &json_filename)
{// Read in view_dictboost::property_tree::ptree pt;std::ifstream in(json_filename);std::stringstream buffer;buffer << in.rdbuf();read_json(buffer, pt);return pt;
}/** Debugging function to print out a boost::ptree **/
void print(boost::property_tree::ptree const &pt)
{using boost::property_tree::ptree;ptree::const_iterator end = pt.end();for (ptree::const_iterator it = pt.begin(); it != end; ++it){std::cout << it->first << ": " << it->second.get_value<std::string>() << std::endl;print(it->second);}
}
} // namespace Utils#endif // #ifndef SEMANTIC2D3D_UTILS_H

以上给出了解析json中点云坐标和rgb的程序。可根据文件树添加其他数据的解析程序,json的解析方式是一样的,只需要调整一下解析程序中的层数和对应的name即可。

主函数如下,主要是通过调用点云数据和rgb数据进行整体点云的拼接。由于点云数量过大,因此最后还是按文件分别保存了pcd文件。

#include <opencv2/opencv.hpp>
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui/highgui.hpp"#include <vector>
#include <string>
#include <Eigen/Core>
#include <unistd.h>
#include <fstream>
#include <cstring>#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/visualization/cloud_viewer.h>
#include <pcl/common/common_headers.h>
#include <pcl/io/io.h>
#include <pcl/point_types.h>
#include <pcl/io/ply_io.h>
#include <pcl/io/obj_io.h>
#include <pcl/PolygonMesh.h>
#include <pcl/point_cloud.h>
#include <pcl/io/vtk_lib_io.h>#include "pcl_utils.h"using namespace std;
using namespace Eigen;
using namespace cv;
using namespace pcl;int main(int argc, char **argv)
{string filename = "point_data/";vector<String> files_json; //存放文件路径glob(filename, files_json, true);// 使用智能指针,创建一个空点云。这种指针用完会自动释放。PointCloud<PointXYZRGB>::Ptr cloud(new PointCloud<PointXYZRGB>);// PointCloud<PointXYZRGB>::Ptr cloud_sum(new PointCloud<PointXYZRGB>);// for (int i = 0; i < files_json.size(); i++)// {// cout << "name : " << files_json[i] << endl;// pcl::io::loadPCDFile(files_json[i], *cloud);// *cloud_sum = *cloud_sum + *cloud;// cloud->points.clear();// cout << "sum " << i << " / " << files_json.size() <<  "done" << endl;// }// pcl::io::savePCDFile("cloud_sum.pcd", *cloud_sum);boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("3D Viewer"));viewer->setBackgroundColor(0, 0, 0);for (int i = 2; i < files_json.size(); i++){boost::property_tree::ptree pose_pt = Utils::loadPoseFile(files_json[i]);string name = pose_pt.get<string>("name");cout << "name : " << name << endl;// string global_name = pose_pt.get<string>("global_name");std::vector<Eigen::Vector3d> RGB_color;if (!Utils::getRGBcolor(pose_pt, RGB_color));std::vector<Eigen::Vector3d> points;if (!Utils::getXYZpoints(pose_pt, points));cout << "read date done.." << endl;// cout << "global_name : " << global_name << endl;// cout << "RGB_color_size : " << RGB_color.size() << endl;// cout << "points_size : " << points.size() << endl;for (int j = 0; j < RGB_color.size(); j++){pcl::PointXYZRGB point;point.x = points[j](0);point.y = points[j](1);point.z = points[j](2);point.b = RGB_color[j](2);point.g = RGB_color[j](1);point.r = RGB_color[j](0);cloud->push_back(point);}cout << i << "point number :" << cloud->points.size() << endl;String ss = "pointcloud_" + name + ".pcd";pcl::io::savePCDFile(ss, *cloud);// 清除数据并退出cloud->points.clear();cout << "Point cloud saved." << endl;cout << "next pcd reading..." << endl;}cloud->width = 1;cloud->height = cloud->points.size();depth_cloud->width = 1;depth_cloud->height = cloud->points.size();pcl::visualization::PointCloudColorHandlerRGBField<pcl::PointXYZRGB> rgb_cloud(cloud);viewer->addPointCloud<pcl::PointXYZRGB>(cloud, rgb_cloud, "sample cloud");viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "sample cloud");viewer->addCoordinateSystem(1.0);while (!viewer->wasStopped()){viewer->spinOnce(100);boost::this_thread::sleep(boost::posix_time::microseconds(100000));}cv::waitKey(0);viewer->removeAllPointClouds();return 0;
}

由此可以生成以文件为单位的点云数据,取其中一个生成的点云如图:

程序中注释的部分为最后将所有的点云pcd文件合成一个点云的代码,最后Area_1的整体点云效果如图:

本人i7-8700HQ+16g内存仍然很卡。

2.通过data文件夹中的pose合成rgb和depth

之前一直在用这种方式做,调了整整两天的程序终于调通了,结果发现数据中的depth很有问题,合成的图片深度分层很严重,而且分层比较均匀,不像是程序的问题。采用的方法是通过读取data文件夹下的pose.json文件获取对应的相机位姿,再根据相机内参,将depth投影到空间去,并附上rgb信息。然而最后因结果不好而放弃。且自己合成点云非常消耗计算量,电脑跑一会就卡的要死,最好不要采用这种方式,直接使用mat文件中的数据即可。

S3DIS数据集解析为点云相关推荐

  1. 点云语义分割:pointnet++训练S3DIS数据集

    文章目录 一.数据预处理 二.训练 三.测试 四.6折交叉验证 tensorflow版本的pointnet++没有关于S3DIS数据集训练代码,我尝试参考ScanNet的训练代码改写成训练S3DIS数 ...

  2. Pointnet语义分割任务S3DIS数据集上的注意点

    前言 Pointnet的网络结构和源码解释,已在之前写了次总结,本次主要针对论文中的数据集以.h5为TensorFlow的输入格式进行解释,记录如何制作H5文件,以提供给TensorFlow,PyTo ...

  3. S3DIS数据集学习笔记

    1.整体介绍 S3DIS是一个大型的3d室内数据集.S3DIS数据集共五个区域 共271个房间 每个区域有多个物体,每个物体的类别有一个对应的txt文件,txt文件中存储的都是点的坐标和颜色信息,其类 ...

  4. KITTI数据集下载(百度云)

    目前KITTI官网提供的链接国内还无法下载,网络上的资源也大部分失效了,我把数据集重新上传到百度云方便大家下载.网盘包含以下文件: data_object_calib data_object_imag ...

  5. 【免费活动】解析腾讯云音视频通信三大核心网络技术实战与创新

    随着互联网的发展越来越成熟,移动终端成为我们人手必备的生活用品,云计算的普及与高速发展,4G.5G网络的瓜熟蒂落,我们真正的进入了全真互联网时代.2020年,一场突如其来的疫情,很多传统行业不得不将线 ...

  6. 解析腾讯云音视频通信三大核心网络技术实战与创新

    随着互联网的发展越来越成熟,移动终端成为我们人手必备的生活用品,云计算的普及与高速发展,4G.5G网络的瓜熟蒂落,我们真正的进入了全真互联网时代.2020年,一场突如其来的疫情,很多传统行业不得不将线 ...

  7. 【转】DICOM命令集和数据集解析!!

    转自:DICOM命令集和数据集解析 - 微笑的艾米 - 博客园 摘   要:本文通过分析一个典型的DICOM消息,详细地解析了DICOM命令集和数据集的构成方式和其含义.并在此基础上,提出了一种实现D ...

  8. ImageNet2012数据集完整版百度云下载

    ImageNet2012数据集完整版百度云下载 (欢迎关注"我爱计算机视觉",一个有价值有深度的公众号~) ImageNet2012的图像分类数据,在计算机视觉领域非常重要,它是深 ...

  9. KDD CUP 99 数据集解析、挖掘与下载

    KDD CUP 99 数据集解析.挖掘与下载 数据特征描述 一个网络连接定义为在某个时间内从开始到结束的TCP数据包序列,并且在这段时间内,数据在预定义的协议下(如TCP.UDP)从源IP地址到目的I ...

最新文章

  1. 多种方式测量AMP328频率响应
  2. 初等数学O 集合论基础 第三节 序关系
  3. 解决VMware虚拟机安装的ubuntu显示屏幕小的问题
  4. 藁城一中2021年高考成绩查询,2017藁城一中录取分数线及高考成绩情况
  5. Flex布局里的align-self属性
  6. 企业级IM应该帮助员工提高绩效,避免无关的信息干扰
  7. 万能驱动安装器_Windows驱动安装指南
  8. 织梦自定义表单地区联动类型不可用的解决办法
  9. 2017.9.6 外星人 思考记录
  10. edxp显示未安装_智能水表安装使用注意事项
  11. 2021年深度学习哪些方向比较新颖,处于上升期或者朝阳阶段,比较有研究潜力?
  12. 一次mongoengine查询速度慢的优化
  13. 如何提取多层json数据 python_Postgre数据库字段Json内容提取(基于Python)
  14. Windows 使用浮动键盘语言栏
  15. docker执行容器内的shell_为什么不建议把数据库部署在docker容器内?
  16. Terrasolid安装与破解
  17. 【matlab图像处理】图像处理的经典操作
  18. 贝塞尔插值曲线绘制软件设计
  19. 联合国会常务委员会明确破产法规:Arun Jaitley
  20. [ CTF ] WriteUp- 2022年第三届“网鼎杯”网络安全大赛(白虎组)

热门文章

  1. 从显示一张图片开始学习OpenGL ES
  2. 【微服务实战之Docker容器】第一章-下载及安装
  3. candence pcb走线等长_PCB走线角度选择 - PCB Layout 跳坑指南 - 吴川斌的博客
  4. 心跳机制 heartbeat
  5. java 错误1335_安装JAVA的JDK时出现,错误1335? – 手机爱问
  6. NR PRACH(三)时域位置
  7. 模型预测控制(MPC)——动态矩阵控制(DMC)
  8. Qt中的UI文件介绍
  9. 为什么计算机会出现两个用户,Win7登录时有2个账户|为什么电脑开机时有二个账户...
  10. 学校学业水平测试软件,中小学生学业水平测试