コード
#include "stdafx.h"
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/common/io.h>
#include <pcl/keypoints/sift_keypoint.h>
#include <pcl/features/normal_3d.h>
#include <pcl/visualization/pcl_visualizer.h>
pcl::PointCloud<pcl::PointNormal>::Ptr Surface_normals(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud)
{
pcl::NormalEstimation<pcl::PointXYZ, pcl::PointNormal> 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::PointNormal>::Ptr cloud_normals (new pcl::PointCloud<pcl::PointNormal>);//法線情報を入れる変数
ne.setRadiusSearch (0.5);//検索する半径を指定する
ne.compute (*cloud_normals);//法線情報の出力先を指定する
return cloud_normals;
}
pcl::PointCloud<pcl::PointWithScale> Extract_SIFT(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, pcl::PointCloud<pcl::PointNormal>::Ptr cloud_normals)
{
// SIFT特徴量計算のためのパラメータ
const float min_scale = 0.01f;
const int n_octaves = 3;
const int n_scales_per_octave = 4;
const float min_contrast = 0.001f;
pcl::SIFTKeypoint<pcl::PointNormal, pcl::PointWithScale> sift;
pcl::PointCloud<pcl::PointWithScale> result;
pcl::search::KdTree<pcl::PointNormal>::Ptr tree(new pcl::search::KdTree<pcl::PointNormal> ());
sift.setSearchMethod(tree);
sift.setScales(min_scale, n_octaves, n_scales_per_octave);
sift.setMinimumContrast(0.00);
sift.setInputCloud(cloud_normals);
sift.compute(result);
std::cout << "No of SIFT points in the result are " << result.points.size () << std::endl;
return result;
}
int _tmain(int argc, _TCHAR* argv[])
{
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
pcl::io::loadPCDFile<pcl::PointXYZ> (argv[1], *cloud);
pcl::PointCloud<pcl::PointNormal>::Ptr cloud_normals (new pcl::PointCloud<pcl::PointNormal>);
cloud_normals = Surface_normals(cloud);
// XYZの情報をcloudからSurface_normals(cloud)にXYZとして加える
for(size_t i = 0; i < cloud_normals->points.size(); ++i)
{
cloud_normals->points[i].x = cloud->points[i].x;
cloud_normals->points[i].y = cloud->points[i].y;
cloud_normals->points[i].z = cloud->points[i].z;
}
// 視覚化のためSIFT計算の結果をcloud_tempにコピー
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_temp (new pcl::PointCloud<pcl::PointXYZ>);
copyPointCloud(Extract_SIFT(cloud, cloud_normals), *cloud_temp);
std::cout << "SIFT points in the cloud_temp are " << cloud_temp->points.size () << std::endl;
// 入力点群と計算された特徴点を表示
pcl::visualization::PCLVisualizer viewer("PCL Viewer");
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> keypoints_color_handler (cloud_temp, 0, 255, 0);
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> cloud_color_handler (cloud, 255, 0, 0);
viewer.setBackgroundColor( 0.0, 0.0, 0.0 );
viewer.addPointCloud(cloud, cloud_color_handler, "cloud");
viewer.addPointCloud(cloud_temp, keypoints_color_handler, "keypoints");
viewer.setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 7, "keypoints");
while(!viewer.wasStopped ())
{
viewer.spinOnce ();
}
return (0);
}
実行結果
赤の点が入力した点群、緑の点がSIFT特徴量として計算された点である。本来ならば色の情報も使うべきであるが現在色情報のついたデータがないため後日実行することにする。
0 件のコメント:
コメントを投稿