近年Point Cloudを使用した環境認識技術が発展してきており、多くのロボットにこの技術が採用されています。自分もこの波に乗ろうと、去年卒業発表の時にPointCloudを使用したプログラムを書いたのを覚えています。(結果は・・・うん、まぁ・・・)
PointCloudを扱うライブラリとして特に有名なのがPCL(Point Cloud Library)と呼ばれるものです。(
http://pointclouds.org/)このサイトのチュートリアルは自分も去年、大変お世話になりました。
昨日久しぶりに、PCLを勉強し直そうと、VoxelGridのチュートリアルを写して、Makeをかけてみたのですが・・・Makeが通らない。どうも自分のverでは使用できない型があったみたいです。
PCLはver 1.7.xをリリースしており、それ以前のverでは使用できない機能も多く増えています。その1.7.xで採用されている「PCLPointCloud2」という型が自分の使用している1.6.0には存在しなかったのが原因みたいです。
では、1.6.0でPCLだけを使用してこのVoxelGridを使うことはできないか、普通に出来ます。実際このVoxelGridは古いverでも使用されており、PCLPointCloud2を使用しなくても作ることは可能です。実際ほとんど変更しませんでした。
以下にソースコードを載せます。
#include<iostream>
#include<pcl/io/pcd_io.h>
#include<pcl/point_types.h>
#include<pcl/filters/voxel_grid.h>
int main(int argc, char **argv)
{
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ> ());
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered (new pcl::PointCloud<pcl::PointXYZ> ());
pcl::PCDReader reader;
reader.read("pcdファイル名", *cloud);
std::cerr<<"PointCloud befor filtering: " << cloud->width * cloud->height << "data points ( " << pcl::getFieldsList (*cloud) << ").";
pcl::VoxelGrid<pcl::PointXYZ> sor;
sor.setInputCloud(cloud);
sor.setLeafSize(0.1f, 0.1f, 0.1f);
sor.filter(*cloud_filtered);
std::cerr<<"PointCloud after filtering: " << cloud_filtered->width * cloud_filtered->height << "data points (" << pcl::getFieldsList(*cloud_filtered) <<").";
pcl::PCDWriter writer;
writer.write("保存ファイル名", *cloud_filtered, false);
return(0);
}
大まかな場所はチュートリアルと同様で、変更点は赤字で書いた部分です。この変更は、PCLPointCloud2の部分を1.6.0などで使用されていたpcl::PointCloud<pcl::PointXYZ>を使用している点。あとはPCDWriterを使用する際の引数がPointCloud<pcl::PointXYZ>で使用できるようなようにしている点だけです。
PCL ver 1.6.0でもPointCloud2を扱うことはできるようです。ただ、型がsensor_msgs::PointCloud2となっており、この型はROSのメッセージ型で、もしかしたらPCL単体では使用できない可能性があります。(未確認)
正直この問題は自分が以前のverを使用しているのが問題であり、最新のverに更新すれば問題ないと思うが・・・諸事情により乗り換えられないのが・・・・
これは、早めにその諸事情を解決して、1.7.xに乗り換えたほうが良さそうですね。
(何か問題、間違いがあれば変更しますー)