2015年3月4日水曜日

点群データの特徴を抽出する Viewpoint Feature Histogram

 物体検出などを行う際にはかならずと言っていいほどデータから特徴を抽出する。2次元においてはそういった特徴は無数に存在するが、比較的最近研究が行われるようになった3次元の点群においてはまだ数えるほどしかない。(2次元で使用される特徴量を3次元点群からも抽出できるようにしたものもある)PCLではいくつか点群から抽出する特徴量があり、その一つがViewpoint Feature Histogramである。PCLが提供している機能には他にもPFH(Point Feature Histogram)やFPFH(Fast Point Feature Histogram)などもある。それらについてはまた記事にする。


コード
#include "stdafx.h"

#include <pcl/point_types.h>
#include <pcl/features/vfh.h>
#include <pcl/io/pcd_io.h>
#include <pcl/features/normal_3d.h>

pcl::PointCloud<pcl::Normal>::Ptr surface_normals(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud)
{
    pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> ne;
    ne.setInputCloud (cloud);//法線の計算を行いたい点群を指定する

    pcl::search::KdTree<pcl::PointXYZ>::Ptr tree (new pcl::search::KdTree<pcl::PointXYZ> ());//KDTREEを作る
    ne.setSearchMethod (tree);//検索方法にKDTREEを指定する

    pcl::PointCloud<pcl::Normal>::Ptr cloud_normals (new pcl::PointCloud<pcl::Normal>);//法線情報を入れる変数

    ne.setRadiusSearch (0.005);//検索する半径を指定する

    ne.compute (*cloud_normals);//法線情報の出力先を指定する

    return cloud_normals;
}


pcl::PointCloud<pcl::VFHSignature308>::Ptr Extract_VFH(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud)
{
    pcl::PointCloud<pcl::Normal>::Ptr cloud_normals (new pcl::PointCloud<pcl::Normal> ());
    pcl::VFHEstimation<pcl::PointXYZ, pcl::Normal, pcl::VFHSignature308> vfh;
    pcl::PointCloud<pcl::VFHSignature308>::Ptr vfhs (new pcl::PointCloud<pcl::VFHSignature308> ());
   
    cloud_normals = surface_normals(cloud);
   
    vfh.setInputCloud (cloud);
    vfh.setInputNormals (cloud_normals);

    pcl::search::KdTree<pcl::PointXYZ>::Ptr tree (new pcl::search::KdTree<pcl::PointXYZ> ());
    vfh.setSearchMethod (tree);

   
    vfh.compute (*vfhs);
    return vfhs;
}


int _tmain(int argc, _TCHAR* argv[])
{
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
    pcl::io::loadPCDFile(argv[1], *cloud);
       
    std::stringstream Filename;
    string name = argv[1];
    name.erase(name.length() - 4);
    Filename << name << "_vfh.pcd";
    std::cout << Filename.str() << std::endl;
    pcl::io::savePCDFile(Filename.str(), *Extract_VFH(cloud));

    return (0);
}


 実行結果




ダウンサンプリングによって点群の数を約3分の1程度まで減少させた2つのモデルからVFHを抽出しても得られるヒストグラムはまったく一緒である。

1 件のコメント:

  1. 興味深い内容ありがとうございます。
    自分も大学でpclを使っています。
    1つ質問なのですが、ヒストグラムを表示させるのに、OpenGLを使用していますか?それともPCLにヒストグラムを表示させるライブラリーがあるのでしょうか?
    お返事していただけると幸いです。 よろしくお願いします。

    返信削除