PCLではダウンサンプリングと呼ばれる手法が用いられる。このダウンサンプリングは一定の範囲内にある点の中心に新たな点を配し、それ以外の点は全て削除する機能である。ちなみにこのダウンサンプリングの正式な名前はVoxelGridFilterという。点群の密度は状況によって大きく変わるのでここでは点群情報の体積から範囲を決定する。
コード
#include "stdafx.h"
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/io/io.h>
#include <pcl/point_types.h>
#include <pcl/filters/voxel_grid.h>
pcl::PointCloud<pcl::PointXYZ> voxel_grid(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud)
{
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered (new pcl::PointCloud<pcl::PointXYZ>);
double max_height = 0, max_width = 0, max_length = 0;
double min_height = 0, min_width = 0, min_length = 0;
double height = 0, width = 0, length = 0;
for(size_t i = 0; i < cloud->points.size(); i++){//入力点群の縦横高さの最大値と最小値を計算する
if(max_height > cloud->points[i].z)
max_height = max_height;
else
max_height = cloud->points[i].z;
if(max_width > cloud->points[i].y)
max_width = max_width;
else
max_width = cloud->points[i].y;
if(max_length > cloud->points[i].x)
max_length = max_length;
else
max_length = cloud->points[i].x;
if(min_height < cloud->points[i].z)
min_height = min_height;
else
min_height = cloud->points[i].z;
if(min_width < cloud->points[i].y)
min_width = min_width;
else
min_width = cloud->points[i].y;
if(min_length < cloud->points[i].x)
min_length = min_length;
else
min_length = cloud->points[i].x;
}
height = fabs(max_height) + fabs(min_height);
width = fabs(max_width) + fabs(min_width);
length = fabs(max_length) + fabs(min_length);
double model_volume = 0, voxel_volume, voxel_length = 0;
model_volume = height * width * length;
voxel_volume = model_volume / 150000;
voxel_length = pow(voxel_volume, 1.0 / 3.0);
pcl::VoxelGrid<pcl::PointXYZ> sor;
sor.setInputCloud (cloud);
//sor.setLeafSize (0.01f, 0.01f, 0.01f);
sor.setLeafSize(voxel_length, voxel_length, voxel_length);
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;
std::string name = argv[1];
name.erase(name.length()-4);
Filename << name << "_voxel.pcd";
pcl::io::savePCDFileBinary(Filename.str(), voxel_grid(cloud));
return (0);
}
実行結果
このプログラムによって点群の数を減らし、処理速度の向上などを見込む事ができる。しかし、この処理はPassThroughFilterと同様、点が有用であるかどうか問わずに削除を行うので注意が必要。もしそれが嫌だったら高機能なコンピュータを容易するかGPUに処理を手伝わせるなどする必要がある。自分はGPUに処理の一部を投げる方法はまだ知らない。
0 件のコメント:
コメントを投稿