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

#include <iostream>

#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <boost/thread/thread.hpp>
#include <pcl/visualization/pcl_visualizer.h> void main()
{
/* Create Point Cloud */
pcl::PointCloud<pcl::PointXYZRGBA>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGBA>); /* Read PCD File */
/* Read Wrong */
if (- == pcl::io::loadPCDFile<pcl::PointXYZRGBA>("table_scene_lms400.pcd", *cloud))
{
return;
} /* Then show the point cloud */
boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("office chair model"));
viewer->setBackgroundColor(, , ); pcl::visualization::PointCloudColorHandlerRGBField<pcl::PointXYZRGBA> rgba(cloud); //Maybe set the cloud to he handler rgba?
viewer->addPointCloud<pcl::PointXYZRGBA>(cloud, rgba, "sample cloud"); //Add a Point Cloud (templated) to screen. Q:Some questions here
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, , "sample cloud"); //Set the rendering properties //viewer->addCoordinateSystem(1.0); //Adds 3D axes describing a coordinate system to screen at 0,0,0
viewer->initCameraParameters (); //Initialize camera parameters with some default values. /* Show the point cloud */
while (!viewer->wasStopped ())
{
viewer->spinOnce (); //updates the screen loop
boost::this_thread::sleep (boost::posix_time::microseconds ());
}
}
pcl::io::loadPCDFile用于读取一个PCD文件至一个PointCloud类型,这里就是将table_scene_lms400.pcd文件里的数据读取至cloud里。
在PCL文档里关于pcl::io::loadPCDFile的实现有3个,我目前只看了第一种。

下面看看loadPCDFile在namespace 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函数:

template<typename PointT> int
read (const std::string &file_name, pcl::PointCloud<PointT> &cloud, const int offset = 0)
{
pcl::PCLPointCloud2 blob;
int pcd_version;
int res = read (file_name, blob, cloud.sensor_origin_, cloud.sensor_orientation_, pcd_version, offset); // If no error, convert the data
if (res == 0)
pcl::fromPCLPointCloud2 (blob, cloud);
return (res);
}

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

int
pcl::PCDReader::read (const std::string &file_name, pcl::PCLPointCloud2 &cloud,
Eigen::Vector4f &origin, Eigen::Quaternionf &orientation, int &pcd_version,
const int offset)
{
pcl::console::TicToc tt;
tt.tic (); int data_type;
unsigned int data_idx; int res = readHeader (file_name, cloud, origin, orientation, pcd_version, data_type, data_idx, offset); if (res < )
return (res); unsigned int idx = ; // Get the number of points the cloud should have
unsigned int nr_points = cloud.width * cloud.height; // Setting the is_dense property to true by default
cloud.is_dense = true; if (file_name == "" || !boost::filesystem::exists (file_name))
{
PCL_ERROR ("[pcl::PCDReader::read] Could not find file '%s'.\n", file_name.c_str ());
return (-);
} // if ascii
if (data_type == )
{
// Re-open the file (readHeader closes it)
std::ifstream fs;
fs.open (file_name.c_str ());
if (!fs.is_open () || fs.fail ())
{
PCL_ERROR ("[pcl::PCDReader::read] Could not open file %s.\n", file_name.c_str ());
return (-);
} fs.seekg (data_idx); std::string line;
std::vector<std::string> st; // Read the rest of the file
try
{
while (idx < nr_points && !fs.eof ())
{
getline (fs, line);
// Ignore empty lines
if (line == "")
continue; // Tokenize the line
boost::trim (line);
boost::split (st, line, boost::is_any_of ("\t\r "), boost::token_compress_on); if (idx >= nr_points)
{
PCL_WARN ("[pcl::PCDReader::read] input file %s has more points (%d) than advertised (%d)!\n", file_name.c_str (), idx, nr_points);
break;
} size_t total = ;
// Copy data
for (unsigned int d = ; d < static_cast<unsigned int> (cloud.fields.size ()); ++d)
{
// Ignore invalid padded dimensions that are inherited from binary data
if (cloud.fields[d].name == "_")
{
total += cloud.fields[d].count; // jump over this many elements in the string token
continue;
}
for (unsigned int c = ; c < cloud.fields[d].count; ++c)
{
switch (cloud.fields[d].datatype)
{
case pcl::PCLPointField::INT8:
{
copyStringValue<pcl::traits::asType<pcl::PCLPointField::INT8>::type> (
st.at (total + c), cloud, idx, d, c);
break;
}
case pcl::PCLPointField::UINT8:
{
copyStringValue<pcl::traits::asType<pcl::PCLPointField::UINT8>::type> (
st.at (total + c), cloud, idx, d, c);
break;
}
case pcl::PCLPointField::INT16:
{
copyStringValue<pcl::traits::asType<pcl::PCLPointField::INT16>::type> (
st.at (total + c), cloud, idx, d, c);
break;
}
case pcl::PCLPointField::UINT16:
{
copyStringValue<pcl::traits::asType<pcl::PCLPointField::UINT16>::type> (
st.at (total + c), cloud, idx, d, c);
break;
}
case pcl::PCLPointField::INT32:
{
copyStringValue<pcl::traits::asType<pcl::PCLPointField::INT32>::type> (
st.at (total + c), cloud, idx, d, c);
break;
}
case pcl::PCLPointField::UINT32:
{
copyStringValue<pcl::traits::asType<pcl::PCLPointField::UINT32>::type> (
st.at (total + c), cloud, idx, d, c);
break;
}
case pcl::PCLPointField::FLOAT32:
{
copyStringValue<pcl::traits::asType<pcl::PCLPointField::FLOAT32>::type> (
st.at (total + c), cloud, idx, d, c);
break;
}
case pcl::PCLPointField::FLOAT64:
{
copyStringValue<pcl::traits::asType<pcl::PCLPointField::FLOAT64>::type> (
st.at (total + c), cloud, idx, d, c);
break;
}
default:
PCL_WARN ("[pcl::PCDReader::read] Incorrect field data type specified (%d)!\n",cloud.fields[d].datatype);
break;
}
}
total += cloud.fields[d].count; // jump over this many elements in the string token
}
idx++;
}
}
catch (const char *exception)
{
PCL_ERROR ("[pcl::PCDReader::read] %s\n", exception);
fs.close ();
return (-);
} // Close file
fs.close ();
}
else
/// ---[ Binary mode only
/// We must re-open the file and read with mmap () for binary
{
// Open for reading
int fd = pcl_open (file_name.c_str (), O_RDONLY);
if (fd == -)
{
PCL_ERROR ("[pcl::PCDReader::read] Failure to open file %s\n", file_name.c_str () );
return (-);
} // Seek at the given offset
off_t result = pcl_lseek (fd, offset, SEEK_SET);
if (result < )
{
pcl_close (fd);
PCL_ERROR ("[pcl::PCDReader::read] lseek errno: %d strerror: %s\n", errno, strerror (errno));
PCL_ERROR ("[pcl::PCDReader::read] Error during lseek ()!\n");
return (-);
} size_t data_size = data_idx + cloud.data.size ();
// Prepare the map
#ifdef _WIN32
// As we don't know the real size of data (compressed or not),
// we set dwMaximumSizeHigh = dwMaximumSizeLow = 0 so as to map the whole file
HANDLE fm = CreateFileMapping ((HANDLE) _get_osfhandle (fd), NULL, PAGE_READONLY, , , NULL);
// As we don't know the real size of data (compressed or not),
// we set dwNumberOfBytesToMap = 0 so as to map the whole file
char *map = static_cast<char*>(MapViewOfFile (fm, FILE_MAP_READ, , , ));
if (map == NULL)
{
CloseHandle (fm);
pcl_close (fd);
PCL_ERROR ("[pcl::PCDReader::read] Error mapping view of file, %s\n", file_name.c_str ());
return (-);
}
#else
char *map = static_cast<char*> (mmap (, data_size, PROT_READ, MAP_SHARED, fd, ));
if (map == reinterpret_cast<char*> (-)) // MAP_FAILED
{
pcl_close (fd);
PCL_ERROR ("[pcl::PCDReader::read] Error preparing mmap for binary PCD file.\n");
return (-);
}
#endif /// ---[ Binary compressed mode only
if (data_type == )
{
// Uncompress the data first
unsigned int compressed_size, uncompressed_size;
memcpy (&compressed_size, &map[data_idx + ], sizeof (unsigned int));
memcpy (&uncompressed_size, &map[data_idx + ], sizeof (unsigned int));
PCL_DEBUG ("[pcl::PCDReader::read] Read a binary compressed file with %u bytes compressed and %u original.\n", compressed_size, uncompressed_size);
// For all those weird situations where the compressed data is actually LARGER than the uncompressed one
// (we really ought to check this in the compressor and copy the original data in those cases)
if (data_size < compressed_size || uncompressed_size < compressed_size)
{
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);
#ifdef _WIN32
UnmapViewOfFile (map);
data_size = compressed_size + data_idx + ;
map = static_cast<char*>(MapViewOfFile (fm, FILE_MAP_READ, , , data_size));
#else
munmap (map, data_size);
data_size = compressed_size + data_idx + ;
map = static_cast<char*> (mmap (, data_size, PROT_READ, MAP_SHARED, fd, ));
#endif
} if (uncompressed_size != cloud.data.size ())
{
PCL_WARN ("[pcl::PCDReader::read] The estimated cloud.data size (%u) is different than the saved uncompressed value (%u)! Data corruption?\n",
cloud.data.size (), uncompressed_size);
cloud.data.resize (uncompressed_size);
} char *buf = static_cast<char*> (malloc (data_size));
// The size of the uncompressed data better be the same as what we stored in the header
unsigned int tmp_size = pcl::lzfDecompress (&map[data_idx + ], compressed_size, buf, static_cast<unsigned int> (data_size));
if (tmp_size != uncompressed_size)
{
free (buf);
pcl_close (fd);
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);
return (-);
} // Get the fields sizes
std::vector<pcl::PCLPointField> fields (cloud.fields.size ());
std::vector<int> fields_sizes (cloud.fields.size ());
int nri = , fsize = ;
for (size_t i = ; i < cloud.fields.size (); ++i)
{
if (cloud.fields[i].name == "_")
continue;
fields_sizes[nri] = cloud.fields[i].count * pcl::getFieldSize (cloud.fields[i].datatype);
fsize += fields_sizes[nri];
fields[nri] = cloud.fields[i];
++nri;
}
fields.resize (nri);
fields_sizes.resize (nri); // Unpack the xxyyzz to xyz
std::vector<char*> pters (fields.size ());
int toff = ;
for (size_t i = ; i < pters.size (); ++i)
{
pters[i] = &buf[toff];
toff += fields_sizes[i] * cloud.width * cloud.height;
}
// Copy it to the cloud
for (size_t i = ; i < cloud.width * cloud.height; ++i)
{
for (size_t j = ; j < pters.size (); ++j)
{
memcpy (&cloud.data[i * fsize + fields[j].offset], pters[j], fields_sizes[j]);
// Increment the pointer
pters[j] += fields_sizes[j];
}
}
//memcpy (&cloud.data[0], &buf[0], uncompressed_size); free (buf);
}
else
// Copy the data
memcpy (&cloud.data[], &map[] + data_idx, cloud.data.size ()); // Unmap the pages of memory
#ifdef _WIN32
UnmapViewOfFile (map);
CloseHandle (fm);
#else
if (munmap (map, data_size) == -)
{
pcl_close (fd);
PCL_ERROR ("[pcl::PCDReader::read] Munmap failure\n");
return (-);
}
#endif
pcl_close (fd);
} if ((idx != nr_points) && (data_type == ))
{
PCL_ERROR ("[pcl::PCDReader::read] Number of points read (%d) is different than expected (%d)\n", idx, nr_points);
return (-);
} // No need to do any extra checks if the data type is ASCII
if (data_type != )
{
int point_size = static_cast<int> (cloud.data.size () / (cloud.height * cloud.width));
// 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
for (uint32_t i = ; i < cloud.width * cloud.height; ++i)
{
for (unsigned int d = ; d < static_cast<unsigned int> (cloud.fields.size ()); ++d)
{
for (uint32_t c = ; c < cloud.fields[d].count; ++c)
{
switch (cloud.fields[d].datatype)
{
case pcl::PCLPointField::INT8:
{
if (!isValueFinite<pcl::traits::asType<pcl::PCLPointField::INT8>::type>(cloud, i, point_size, d, c))
cloud.is_dense = false;
break;
}
case pcl::PCLPointField::UINT8:
{
if (!isValueFinite<pcl::traits::asType<pcl::PCLPointField::UINT8>::type>(cloud, i, point_size, d, c))
cloud.is_dense = false;
break;
}
case pcl::PCLPointField::INT16:
{
if (!isValueFinite<pcl::traits::asType<pcl::PCLPointField::INT16>::type>(cloud, i, point_size, d, c))
cloud.is_dense = false;
break;
}
case pcl::PCLPointField::UINT16:
{
if (!isValueFinite<pcl::traits::asType<pcl::PCLPointField::UINT16>::type>(cloud, i, point_size, d, c))
cloud.is_dense = false;
break;
}
case pcl::PCLPointField::INT32:
{
if (!isValueFinite<pcl::traits::asType<pcl::PCLPointField::INT32>::type>(cloud, i, point_size, d, c))
cloud.is_dense = false;
break;
}
case pcl::PCLPointField::UINT32:
{
if (!isValueFinite<pcl::traits::asType<pcl::PCLPointField::UINT32>::type>(cloud, i, point_size, d, c))
cloud.is_dense = false;
break;
}
case pcl::PCLPointField::FLOAT32:
{
if (!isValueFinite<pcl::traits::asType<pcl::PCLPointField::FLOAT32>::type>(cloud, i, point_size, d, c))
cloud.is_dense = false;
break;
}
case pcl::PCLPointField::FLOAT64:
{
if (!isValueFinite<pcl::traits::asType<pcl::PCLPointField::FLOAT64>::type>(cloud, i, point_size, d, c))
cloud.is_dense = false;
break;
}
}
}
}
}
}
double total_time = tt.toc ();
PCL_DEBUG ("[pcl::PCDReader::read] Loaded %s as a %s cloud in %g ms with %d points. Available dimensions: %s.\n",
file_name.c_str (), cloud.is_dense ? "dense" : "non-dense", total_time,
cloud.width * cloud.height, pcl::getFieldsList (cloud).c_str ());
return ();
}

这里的大致流程就是:

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. 使用visio 2007对现有的数据库进行反向工程

    假如你有一个数据库并且想对这个数据库进行ER图的描绘:又或者你想绘制一个ER图,但发觉绘制效率太低,对visio不熟悉,而你对数据库的操作却了如指掌.这时候你可以利用Visio的反向工程对已有的数据库 ...

  2. vs2015 现用插件

    1.abphelper abp app自动生成接口和input output 2.ankhsvn svn插件 3.c#outline2015 大括号折叠 4.codemaid 格式化 5.go to ...

  3. [刘阳Java]_MyBatis_动态SQL标签用法_第7讲

    1.MyBatis的动态SQL是基于OGNL表达式的,它可以帮助我们方便的在SQL语句中实现某些逻辑. 2.MyBatis中用于实现动态SQL的元素主要有 if choose(when,otherwi ...

  4. 伸缩盒 Flexible Box(旧)

    box-orient  box-pack    box-align  box-flex   box-flex-group  box-ordinal-group   box-direction  box ...

  5. sk_buff封装和解封装网络数据包的过程详解(转载)

    http://dog250.blog.51cto.com/2466061/1612791 可以说sk_buff结构体是Linux网络协议栈的核心中的核心,几乎所有的操作都是围绕sk_buff这个结构体 ...

  6. Robot Framework入门学习1 安装部署详解

    安装注意: 目前Robot framework-ride不支持python3,安装时请下载python2.7版本. Robot Framework安装时出现了一点小问题,网上没有找到直接的介绍,现将安 ...

  7. JAVA生成随机数

    java中一般有两种随机数,一个是Math中random()方法,一个是Random类. 一.Math.random() 随即生成0<x<1的小数. 实例:如何写,生成随机生成出0~100 ...

  8. char、wchar_t、strlen、wcslen

    第一部分: strlen函数的宽字符版是wcslen(wide-character string length:宽字符串长度),并且在STRING.H(其中也说明了strlen)和WCHAR.H中均有 ...

  9. mac 10.11.6,Xcode8下,ruby2.3安装,Cocoapods安装~

    适用环境 mac: 10.11.6 Xcode:8.1 命令执行步骤(安装ruby2.3前准备工作) 查看ruby更新源 gem sources  -L 删除默认官方或者淘宝,新增 https://g ...

  10. ready与onload区别一

    <!DOCTYPE html><html> <head> <title>ready与onload区别一</title> <meta c ...