如何通过PCL获取8×8规格的Spin Image描述符
解决PCL中Spin Image输出维度不符的问题
问题原因
你遇到的153维直方图是PCL SpinImageEstimation类的默认输出大小,而你设置的image_width=8对应应该是8×8=64维的直方图,问题出在输出类型的维度不匹配,以及可能缺少关键参数的正确配置。
解决步骤
1. 指定正确的输出直方图类型
将输出类型从默认的pcl::Histogram<153>改为pcl::Histogram<64>,确保和你设置的8×8分箱对应。
2. 确保输入法线
Spin Image描述符依赖点的法线信息,必须为SpinImageEstimation设置输入法线(如果没有法线,需要先用pcl::NormalEstimation计算)。
3. 正确设置搜索半径
搜索半径需要和image_width匹配,每个分箱的大小为半径 / image_width。例如,若希望每个分箱对应0.01米的径向范围,半径应设为8 * 0.01 = 0.08米。
4. 显式配置参数(可选但推荐)
手动设置直方图大小,确保和image_width的设置一致,避免歧义。
示例代码
#include <pcl/point_types.h> #include <pcl/features/spin_image.h> #include <pcl/features/normal_3d.h> #include <pcl/search/kdtree.h> int main() { // 加载或初始化你的点云 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>); // 如果没有法线,先计算法线 pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>); pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> ne; ne.setInputCloud(cloud); pcl::search::KdTree<pcl::PointXYZ>::Ptr tree_norm(new pcl::search::KdTree<pcl::PointXYZ>); ne.setSearchMethod(tree_norm); ne.setRadiusSearch(0.05); // 根据点云尺度调整 ne.compute(*normals); // 初始化SpinImageEstimation,输出64维直方图(8×8) pcl::SpinImageEstimation<pcl::PointXYZ, pcl::Normal, pcl::Histogram<64>> spin_image; spin_image.setInputCloud(cloud); spin_image.setInputNormals(normals); // 设置搜索方法 pcl::search::KdTree<pcl::PointXYZ>::Ptr tree_spin(new pcl::search::KdTree<pcl::PointXYZ>); spin_image.setSearchMethod(tree_spin); // 设置搜索半径:对应8个分箱,每个分箱0.01米 spin_image.setRadiusSearch(0.08); // 设置Spin Image宽度为8 spin_image.setImageWidth(8); // 显式设置直方图大小为64(可选,setImageWidth已自动设置) spin_image.setHistogramSize(64); // 计算Spin Image描述符 pcl::PointCloud<pcl::Histogram<64>> spin_images; spin_image.compute(spin_images); // 此时每个点的直方图为64维,对应8×8的Spin Image return 0; }
注意事项
- 搜索半径的取值需要结合你的点云实际尺度调整,过小会导致直方图稀疏,过大则会降低描述符的区分度。
- 若点云密度不均匀,可考虑使用
setKSearch代替setRadiusSearch,指定固定数量的邻域点进行计算。
内容的提问来源于stack exchange,提问作者Apo
相关产品推荐
相关产品推荐

