python读取pcd文件_(一)读取PCD文件
下面是一個簡單的讀取PCD文件并顯示的代碼:
#include
#include
#include
#include
#include
void main()
{
/* Create Point Cloud */
pcl::PointCloud<:pointxyzrgba>::Ptr cloud(new pcl::PointCloud<:pointxyzrgba>);
/* Read PCD File */
/* Read Wrong */
if (- == pcl::io::loadPCDFile<:pointxyzrgba>("table_scene_lms400.pcd", *cloud))
{
return;
}
/* Then show the point cloud */
boost::shared_ptr<:visualization::pclvisualizer> viewer(new pcl::visualization::PCLVisualizer("office chair model"));
viewer->setBackgroundColor(, , );
pcl::visualization::PointCloudColorHandlerRGBField<:pointxyzrgba> rgba(cloud); //Maybe set the cloud to he handler rgba?
viewer->addPointCloud<: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文件里的數(shù)據(jù)讀取至cloud里。
在PCL文檔里關(guān)于pcl::io::loadPCDFile的實現(xiàn)有3個,我目前只看了第一種。
下面看看loadPCDFile在namespace io里的實現(xiàn):
template inline int
loadPCDFile (const std::string &file_name, pcl::PointCloud &cloud)
{
pcl::PCDReader p;
return (p.read (file_name, cloud));
}
可以看到loadPCDFile 這個內(nèi)聯(lián)函數(shù),就是調(diào)用了一下pcl::PCDReader里的read函數(shù)。
繼續(xù)看PCDReader函數(shù):
template int
read (const std::string &file_name, pcl::PointCloud &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<: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 (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<:traits::astype>::type> (
st.at (total + c), cloud, idx, d, c);
break;
}
case pcl::PCLPointField::UINT8:
{
copyStringValue<:traits::astype>::type> (
st.at (total + c), cloud, idx, d, c);
break;
}
case pcl::PCLPointField::INT16:
{
copyStringValue<:traits::astype>::type> (
st.at (total + c), cloud, idx, d, c);
break;
}
case pcl::PCLPointField::UINT16:
{
copyStringValue<:traits::astype>::type> (
st.at (total + c), cloud, idx, d, c);
break;
}
case pcl::PCLPointField::INT32:
{
copyStringValue<:traits::astype>::type> (
st.at (total + c), cloud, idx, d, c);
break;
}
case pcl::PCLPointField::UINT32:
{
copyStringValue<:traits::astype>::type> (
st.at (total + c), cloud, idx, d, c);
break;
}
case pcl::PCLPointField::FLOAT32:
{
copyStringValue<:traits::astype>::type> (
st.at (total + c), cloud, idx, d, c);
break;
}
case pcl::PCLPointField::FLOAT64:
{
copyStringValue<:traits::astype>::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(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 (mmap (, data_size, PROT_READ, MAP_SHARED, fd, ));
if (map == reinterpret_cast (-)) // 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(MapViewOfFile (fm, FILE_MAP_READ, , , data_size));
#else
munmap (map, data_size);
data_size = compressed_size + data_idx + ;
map = static_cast (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 (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 (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<:pclpointfield> fields (cloud.fields.size ());
std::vector 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 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 (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 (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<:traits::astype>::type>(cloud, i, point_size, d, c))
cloud.is_dense = false;
break;
}
case pcl::PCLPointField::UINT8:
{
if (!isValueFinite<:traits::astype>::type>(cloud, i, point_size, d, c))
cloud.is_dense = false;
break;
}
case pcl::PCLPointField::INT16:
{
if (!isValueFinite<:traits::astype>::type>(cloud, i, point_size, d, c))
cloud.is_dense = false;
break;
}
case pcl::PCLPointField::UINT16:
{
if (!isValueFinite<:traits::astype>::type>(cloud, i, point_size, d, c))
cloud.is_dense = false;
break;
}
case pcl::PCLPointField::INT32:
{
if (!isValueFinite<:traits::astype>::type>(cloud, i, point_size, d, c))
cloud.is_dense = false;
break;
}
case pcl::PCLPointField::UINT32:
{
if (!isValueFinite<:traits::astype>::type>(cloud, i, point_size, d, c))
cloud.is_dense = false;
break;
}
case pcl::PCLPointField::FLOAT32:
{
if (!isValueFinite<:traits::astype>::type>(cloud, i, point_size, d, c))
cloud.is_dense = false;
break;
}
case pcl::PCLPointField::FLOAT64:
{
if (!isValueFinite<:traits::astype>::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兩種情況,根據(jù)其不同采取不同的方法讀取剩余的內(nèi)容;
3.binary數(shù)據(jù)的情況還需要對數(shù)據(jù)進行check;
這段代碼的細節(jié)處理暫時先這樣了,以后再看看為什么ascii和binary的處理不一樣,有什么不一樣。
PCD文件格式詳解及在PCL下讀取PCD文件
一.PCD簡介 1.1 PCD版本 在點云庫PCL 1.0發(fā)布之前,PCD文件格式就已經(jīng)發(fā)展更新了許多版本.這些新舊不同的版本用PCD_Vx來編號(例如PCD_V5.PCD_V6和PCD_V7等),分 ...
PCL讀取PCD文件的數(shù)據(jù)
1.pcd文件——rabbit.pcd 鏈接:https://pan.baidu.com/s/1v6mjPjwd7fIqUSjlIGTIGQ提取碼:zspx 新建項目pcl rabbit.pcd 和p ...
PCL點云庫中怎樣讀取指定的PCD文件,又一次命名,處理后保存到指定目錄
我一直想把處理后的pcd文件重命名,然后放到指定的目錄,嘗試了好久最終做到了: 比方我想讀取? "table_scene_lms400.pcd" 把它進行濾波處理,重命名為 &qu ...
從PCD文件寫入和讀取點云數(shù)據(jù)
(1)學(xué)習向PCD文件寫入點云數(shù)據(jù) 建立工程文件ch2,然后新建write_pcd.cpp? CMakeLists.txt兩個文件 write_pcd.cpp : #include
從PCD文件中讀取點云數(shù)據(jù)
博客轉(zhuǎn)載自:http://www.pclcn.org/study/shownews.php?lang=cn&id=84 在本小節(jié)我們學(xué)習如何從PCD文件中讀取點云數(shù)據(jù). 代碼 章例1文件夾中, ...
Unity3D移動平臺動態(tài)讀取外部文件全解析
前言: 一直有個想法,就是把工作中遇到的坑通過自己的深挖,總結(jié)成一套相同問題的解決方案供各位同行拍磚探討.眼瞅著2015年第一個工作日就要來到了,小匹夫也休息的差不多了,尋思著也該寫點東西活動活動大腦 ...
PCD文件去除曲率的腳本
在寫一個重建算法的時候需要用到點坐標和法向的數(shù)據(jù)文件,于是向利用pcl中的法向計算模塊來生成法向.輸出后法向文件中包含曲率信息,但是這是不需要的.于是自己寫了一個python小腳本實現(xiàn)格式轉(zhuǎn)換. #- ...
python讀取caffemodel文件
caffemodel是二進制的protobuf文件,利用protobuf的python接口可以讀取它,解析出需要的內(nèi)容 不少算法都是用預(yù)訓(xùn)練模型在自己數(shù)據(jù)上微調(diào),即加載"caffemodel ...
informatica讀取FTP文件
以下為一個完整的informatica讀取ftp文件,并導(dǎo)入到系統(tǒng)中. 第一步: 通過shell腳本下載壓縮包文件 /server/infa_shared/crm_prod/shell/ftpFrom ...
隨機推薦
那些年因為粗心導(dǎo)致的外鏈css無效
css文件三種引用的三種方式: 1.外鏈: 注:如果使用外鏈式絕對不可以忘記 re ...
MySQL數(shù)據(jù)庫集群進行正確配置步驟
MySQL數(shù)據(jù)庫集群進行正確配置步驟 2010-06-09 10:47 arrowcat 博客園 字號:T | T 我們今天是要和大家一起分享的是對MySQL數(shù)據(jù)庫集群進行正確配置,我前兩天在相關(guān)網(wǎng)站 ...
jquery利用event.which方法獲取鍵盤輸入值的代碼
jquery利用event.which方法獲取鍵盤輸入值的代碼,需要的朋友可以參考下. 實例 顯示按了哪個鍵: $("input").keydown(function(event) ...
leetcode Search Insert Position Python
#Given a sorted array and a target value, return the index if the target is found. If #not, return t ...
OpenCV 開發(fā)環(huán)境環(huán)境搭建(win10+vs2015+opencv 3.0)
OpenCV?3.0 for windows(下載地址:http://opencv.org/): 本測試中,OpenCV安裝目錄:D:\Program Files\opencv,筆者操作系統(tǒng)為64位. ...
ASP.NET Web API消息處理管道:Self Host下的消息處理管道[下篇]
ASP.NET Web API消息處理管道:Self Host下的消息處理管道[下篇] 我們知道ASP.NET Web API借助于HttpSelfHostServer以Self Host模式寄宿于當 ...
筆記之monkey自定義腳本
自定義腳本的穩(wěn)定性測試 常規(guī)MOnkey測試執(zhí)行的是隨機的事件流,但如果只是想讓Monkey測試某個特定場景者時候就需要用到自定義腳本,Monkey支持執(zhí)行用戶自定義腳本的測試,用戶之需要按照Monk ...
Cocos Creator下刪除AnySDK步驟
1.刪除?frameworks/runtime-src/Classes?下的 jsb_anysdk_basic_conversions.cpp manualanysdkbindings.cpp jsb ...
python---tornado初識(1)
# coding:utf8 # __author: Administrator # date: 2018/3/6 0006 # /usr/bin/env python import tornado.i ...
總結(jié)
以上是生活随笔為你收集整理的python读取pcd文件_(一)读取PCD文件的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Epicor开发实例
- 下一篇: websocket python爬虫_p