コード
#include "stdafx.h"
#include <iostream>
#include <pcl/ModelCoefficients.h>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/sample_consensus/method_types.h>
#include <pcl/sample_consensus/model_types.h>
#include <pcl/segmentation/sac_segmentation.h>
#include <pcl/filters/extract_indices.h>
pcl::PointCloud<pcl::PointXYZ>::Ptr Detect_wall(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, bool TF)
{
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_output (new pcl::PointCloud<pcl::PointXYZ>);
pcl::ModelCoefficients::Ptr coefficients (new pcl::ModelCoefficients);
pcl::PointIndices::Ptr inliers (new pcl::PointIndices);
pcl::SACSegmentation<pcl::PointXYZ> seg;
seg.setOptimizeCoefficients (true);
// Mandatory
seg.setModelType (pcl::SACMODEL_PLANE);//検出するモデルのタイプを指定
seg.setMethodType (pcl::SAC_RANSAC);//検出に使用する方法を指定
seg.setDistanceThreshold (0.01);//
seg.setInputCloud (cloud);
seg.segment (*inliers, *coefficients);
pcl::ExtractIndices<pcl::PointXYZ> extract;
extract.setInputCloud(cloud);
extract.setIndices(inliers);
extract.setNegative(TF);//Trueの場合出力は検出された壁以外のデータ falseの場合は壁のデータ
extract.filter(*cloud_output);
return cloud_output;//出力
}
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;
std::string name = argv[1];
name.erase(name.length() - 4);
Filename << name << "_wall.pcd";
pcl::io::savePCDFileBinary(Filename.str(), *Detect_wall(cloud, false));
Filename.str("");
Filename << name << "_remaining.pcd";
pcl::io::savePCDFileBinary(Filename.str(), *Detect_wall(cloud, true));
return (0);
}
実行結果
無人空間などでSLAMを行う際にはこの平面の検出が重要になってくることがある。今回は壁の検出に関連する機能以外は使用していないが、処理の高速化、軽量化のためにダウンサンプリングやスムージングを行うのも良いかもしれない。実行結果のみからではOctreeを使用したものと変化が無いように感じられるが、このプログラムの場合入力するファイルはひとつで良い。
0 件のコメント:
コメントを投稿