点群を処理するpclで平面を除去する手法はチュートリアルにもありますが,取得している点群内のすべてのを平面を除去する手法がみつからなかったので,載せておきます(^^)/
例えば,取得した点群から人のみを取り出したいとき,平面はどう考えても人ではないので,すべての平面は除去しておくと後処理が軽くなります(^^♪

コード(C++)は以下の感じ

// 全ての平面を除去(下記の平面除去関数をこんな感じでwhile文で使う)
while (true){
	bool flag = planeRemoval(pc, this->planeThreshold);
	if (flag){
		break;
	}
}
//平面除去関数
bool planeRemoval(pcl::PointCloud::Ptr cloud, double threshold){
	// 点群が0でないか確認
	if (cloud->points.size() == 0){
		std::cout << "no cloud data" << std::endl;
		return true;
	}

	// 平面検出(pclのチュートリアル通り)
	pcl::SACSegmentation seg;
	seg.setOptimizeCoefficients(true);
	pcl::ModelCoefficients::Ptr coefficients(new pcl::ModelCoefficients);
	pcl::PointIndices::Ptr inliers(new pcl::PointIndices);

	seg.setInputCloud(cloud);
	seg.setModelType(pcl::SACMODEL_PLANE); //モデル
	seg.setMethodType(pcl::SAC_RANSAC);	//検出手法
	seg.setMaxIterations(200);
	seg.setDistanceThreshold(threshold); //閾値
	seg.segment(*inliers, *coefficients);

	// 平面除去を終わらせるかどうか:検出した平面が,前の平面除去した状態の点群のfinishRemovePlaneRatioで指定された割合未満の点群サイズであれば,それは平面でないとみなして点群除去処理を終了(finishRemovePlaneRatioは0.0~1.0:環境に合わせてください)
	if (inliers->indices.size() < cloud->points.size() * finishRemovePlaneRatio){
		return true;
	}

	// 平面除去
	pcl::ExtractIndices extract;
	extract.setInputCloud(cloud);
	extract.setIndices(inliers);
	extract.setNegative(true); // true にすると平面を除去、false にすると平面以外を除去
	extract.filter(*cloud);
	std::cout << "remove plane" << std::endl;

	return false;
}

ほとんどpclの平面除去のチュートリアルですね( ..)φメモメモ

アルゴリズムとしては以下のような感じです.

  1. pclの関数で平面検出する.点群内で一番大きな平面が選択される.
  2. 検出された平面の点群サイズが,平面検出を実行した点群サイズのある割合(fibishRemovePlaneRatio)未満であれば,それは小さすぎるから平面ではないと判断し,平面除去終了.そうでなければ平面除去する.
  3. 平面除去された点群を再び平面検出&除去にかける(1に戻る)

まぁ,簡単な処理ですね(^_-)-☆ググったら以外に見つからなかったので,書き残しておきます!(^^)!

Categories:

No responses yet

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA