(一)读取PCD文件
下面是一个简单的读取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文件的更多相关文章
- PCD文件格式详解及在PCL下读取PCD文件
一.PCD简介 1.1 PCD版本 在点云库PCL 1.0发布之前,PCD文件格式就已经发展更新了许多版本.这些新旧不同的版本用PCD_Vx来编号(例如PCD_V5.PCD_V6和PCD_V7等),分 ...
- PCL读取PCD文件的数据
1.pcd文件——rabbit.pcd 链接:https://pan.baidu.com/s/1v6mjPjwd7fIqUSjlIGTIGQ提取码:zspx 新建项目pcl rabbit.pcd 和p ...
- PCL点云库中怎样读取指定的PCD文件,又一次命名,处理后保存到指定目录
我一直想把处理后的pcd文件重命名,然后放到指定的目录,尝试了好久最终做到了: 比方我想读取 "table_scene_lms400.pcd" 把它进行滤波处理,重命名为 &qu ...
- 从PCD文件写入和读取点云数据
(1)学习向PCD文件写入点云数据 建立工程文件ch2,然后新建write_pcd.cpp CMakeLists.txt两个文件 write_pcd.cpp : #include <iostr ...
- 从PCD文件中读取点云数据
博客转载自:http://www.pclcn.org/study/shownews.php?lang=cn&id=84 在本小节我们学习如何从PCD文件中读取点云数据. 代码 章例1文件夹中, ...
- Unity3D移动平台动态读取外部文件全解析
前言: 一直有个想法,就是把工作中遇到的坑通过自己的深挖,总结成一套相同问题的解决方案供各位同行拍砖探讨.眼瞅着2015年第一个工作日就要来到了,小匹夫也休息的差不多了,寻思着也该写点东西活动活动大脑 ...
- PCD文件去除曲率的脚本
在写一个重建算法的时候需要用到点坐标和法向的数据文件,于是向利用pcl中的法向计算模块来生成法向.输出后法向文件中包含曲率信息,但是这是不需要的.于是自己写了一个python小脚本实现格式转换. #- ...
- python读取caffemodel文件
caffemodel是二进制的protobuf文件,利用protobuf的python接口可以读取它,解析出需要的内容 不少算法都是用预训练模型在自己数据上微调,即加载"caffemodel ...
- informatica读取FTP文件
以下为一个完整的informatica读取ftp文件,并导入到系统中. 第一步: 通过shell脚本下载压缩包文件 /server/infa_shared/crm_prod/shell/ftpFrom ...
随机推荐
- C# WinForm 中 MessageBox的使用详解
1.C# WinForm 中 MessageBox的使用详解:http://www.cnblogs.com/bq-blog/archive/2012/07/27/2611810.html
- Windows 2012 R2图标以及字体颜色发生变化更改成默认设置
1. 在桌面按"Win+R",然后输出regedit.2. 定位到HKEY_CURRENT_USER\Control panel\Colors3. 对照下面提供给您的初始化颜色的注 ...
- UDP异步通信
先看效果图 Server: using System; using System.Collections.Generic; using System.Text; using System.Net; u ...
- ELK日志管理之——logstash配置语法
Logstash 设计了自己的 DSL -- 有点像 Puppet 的 DSL,或许因为都是用 Ruby 语言写的吧 -- 包括有区域,注释,数据类型(布尔值,字符串,数值,数组,哈希),条件判断,字 ...
- 转js中this指向的简明解答
JS中的this对象详解 JS中this关键字很常见,但是它似乎变幻莫测,让人抓狂.这篇文章就来揭示其中的奥秘. 借助阮一峰老师的话:它代表函数运行时,自动生成的一个内部对象,只能在函数内部使用. ...
- JS对象复制
在JavaScript很多人复制一个对象的时候都是直接用"=",因为大家都觉得脚本语言是没有指针.引用.地址之类的,所以直接用"="就可以把一个对象复制给另外一 ...
- ff
public class MyListenerProcessor implements BeanPostProcessor { @Override public Object postProcessB ...
- 内核对TCP REUSEPORT的优化
Q&A 当有人问起我关于reuseport的一些事的时候,我们的对话基本如下:Q1:什么是reuseport?A1:reuseport是一种套接字复用机制,它允许你将多个套接字bind在同一个 ...
- MySQL 5.6 & 5.7最优配置模板
摘自:http://mp.weixin.qq.com/s?__biz=MjM5MjIxNDA4NA==&mid=207854835&idx=1&sn=c998031ae6816 ...
- VS2012智能提示消失的解决方法
1.点击电脑左下角的“开始菜单”->"所有程序"->Microsoft Visual Studio 2012->Visual Studio Tools->V ...