2015年3月3日火曜日

Outlier(外れ値、異常値)を除去するプログラム

 Kinectなどの3次元点群を取得するセンサーは便利であるが、度々ある点の座標値が以上であったりすることがある。こういった点のことをよくノイズだとかエラーだとか外れ値という。原理的にこれは発生しうる。またこれらを放置すると、法線の正確な計算など後に適用される処理に悪影響を与えるので除去しなければならない。
 除去の原理は簡単に言うと各点からその近隣の全ての点への平均距離を用いる。

コード
#include "stdafx.h"
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/filters/statistical_outlier_removal.h>
#include <pcl/filters/radius_outlier_removal.h>
#include <pcl/filters/conditional_removal.h>

pcl::PointCloud<pcl::PointXYZ> Remove_outliers(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud)
{
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered (new pcl::PointCloud<pcl::PointXYZ>);
     pcl::StatisticalOutlierRemoval<pcl::PointXYZ> sor;
    sor.setInputCloud (cloud);//外れ値を除去する点群を入力
    sor.setMeanK (50);//MeanKを設定
    sor.setStddevMulThresh (0.1);
    sor.setNegative (false);//外れ値を出力する場合はtrueにする
    sor.filter (*cloud_filtered);//出力
    return *cloud_filtered;
}


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 << "_outlier.pcd";
   
   
    pcl::io::savePCDFileBinary (Filename.str(), Remove_outliers(cloud));

    return (0);
}


 手頃なデータがなかったので実行結果は表示できていない。sor.setNegativetrueに設定すれば除去される外れ値の点群を出力できる。もちろん2つ点群の格納場所を作れば2つ同時に出力できる。

0 件のコメント:

コメントを投稿