Spin Image特征描述子

这里主要研究PCL库中的Spin Image描述子,具体文献如下:

  1. Johnson, A.E., Spin-Images: A Representation for 3-D Surface Matching. Carnegie Mellon University, 1997.
  2. Johnson, A.E. and M. Hebert, Surface matching for object recognition in complex three-dimensional scenes. Image and Vision Computing, 1998. 16(9): p. 635-651.
  3. Johnson, A.E. and M. Hebert, Using spin images for efficient object recognition in cluttered 3D scenes. IEEE Transactions on Pattern Analysis and Machine Intelligence, 1999. 21(5): p. 433-449.

Spin Image的主要参数有:

  1. image_width_:图片宽度,是指图片有多少格 (行和列的格子数目是一样的,都是通过这个参数设置);
  2. search_radius_点的搜索半径,即圆柱坐标系的R,也是查找点的时候设置的查找半径,即FLANN中的R;
  3. bin_size:即图片格子的大小,对应图片的分辨率 该参数由image_width_和search_radius_共同决定,pcl库中的代码如下:
  // OK, we are interested in the points of the cylinder of height 2*r and
  // base radius r, where r = m_dBinSize * in_iImageWidth
  // it can be embedded to the sphere of radius sqrt(2) * m_dBinSize * in_iImageWidth
  // suppose that points are uniformly distributed, so we lose ~40%
  // according to the volumes ratio
  double bin_size = 0.0;
  if (is_radial_)
    bin_size = search_radius_ / image_width_;  
  else
    bin_size = search_radius_ / image_width_ / sqrt(2.0);
  1. min_pts_neighb_:该参数限定了圆柱坐标系内出现的最少点数,即R半径范围内的点数要大于该值,否则会出现中断;
  2. support_angle_cos_:该参数限定R半径内搜索到的点的法线与关键点的法线的夹角,该值是余弦值,范围在0-1之间,该参数可以减少与关键点法线方向相反的点,增加鲁棒性,对应文献的说法是:“However, a small support angle is necessary for robustness to clutter and occlusion.”

2D点到spin image的转变
2-D points 转为spin image的转变是通过线性插值实现,原理如下图:
线性插值示意图
最后将spin image矩阵转为直方图的形式。

PCL提取spin image的代码如下:

// Feature_demo.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
#include <vector>
#include <pcl/io/ply_io.h>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/features/normal_3d.h>
#include <pcl/features/spin_image.h>
//#include "spin_image.h"
//#include "spin_image.hpp"

int main(int, char** argv)
{
	std::string filename = "E:/3DData/santong/scene/01.ply";
	std::cout << "Reading " << filename << std::endl;
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);

	if (pcl::io::loadPLYFile <pcl::PointXYZ>(filename.c_str(), *cloud) == -1)
		// load the file
	{
		PCL_ERROR("Couldn't read file");
		return (-1);
	}
	std::cout << "Loaded " << cloud->points.size() << " points." << std::endl;

	// Compute the normals
	pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> normal_estimation;
	normal_estimation.setInputCloud(cloud);

	pcl::search::KdTree<pcl::PointXYZ>::Ptr kdtree(new pcl::search::KdTree<pcl::PointXYZ>);
	normal_estimation.setSearchMethod(kdtree);

	pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud< pcl::Normal>);
	//normal_estimation.setRadiusSearch(30);
	normal_estimation.setKSearch(8);
	normal_estimation.compute(*normals);

	// Setup spin image computation
	pcl::SpinImageEstimation<pcl::PointXYZ, pcl::Normal, pcl::Histogram<153> > spin_image_descriptor(8, 0.5, 10);
	spin_image_descriptor.setInputCloud(cloud);
	spin_image_descriptor.setInputNormals(normals);

	// Use the same KdTree from the normal estimation
	spin_image_descriptor.setSearchMethod(kdtree);
	pcl::PointCloud<pcl::Histogram<153> >::Ptr spin_images(new pcl::PointCloud<pcl::Histogram<153> >);
	spin_image_descriptor.setRadiusSearch(8);

	// Actually compute the spin images
	spin_image_descriptor.compute(*spin_images);
	std::cout << "SI output points.size (): " << spin_images->points.size() << std::endl;

	// Display and retrieve the spin image descriptor vector for the first point.
	pcl::Histogram<153> first_descriptor = spin_images->points[0];
	std::cout << first_descriptor << std::endl;

	return 0;
}

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值