本文主要是介绍『点云识别』隐性模型ISM(Implicit Shape Model),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
什么是隐性模型(ISM)?
当涉及到目标识别和检测时,隐式形状模型(ISM)是一种常用的方法。ISM通过分析目标的形状特征来辨别目标。
首先,用点云数据来表示目标的外形。点云数据就像是许多离散点的集合,每个点都有自己的位置信息。
然后,我们从这些点云数据中提取出一些有用的局部几何特征,比如点的法线方向、曲率等。这些特征能够告诉我们有关目标的形状信息。
接下来,我们将这些局部几何特征组合成特征向量,并用一种方法将其降低到较低的维度。这样做是为了减少计算负担并且更好地表示目标的形状。
然后,我们使用这些特征向量来构建一个“代码本”。代码本就像是一个由许多特征向量组成的库,而每个特征向量都代表了一个特定的目标类别。
最后,当我们有新的点云数据时,我们可以将其特征向量与代码本中的向量进行比较。通过计算它们之间的距离,我们可以判断新的点云数据是否属于某个特定的目标类别。
ISM的优点在于它可以很好地建模目标的形状特征,并且对噪声和数据缺失较为鲁棒。此外,ISM方法还相对高效。
然而,ISM在处理复杂场景中的目标识别可能会面临一些挑战,比如相似目标的区分、遮挡、观察角度变化等。
隐性模型与基于对应分组的方法的区别
ISM方法主要关注物体的形状特征,它使用点云数据中的局部几何特征来描述物体的形状。这些局部特征可以包括点的法线方向、曲率等。ISM通过将这些特征组合成特征向量,并构建一个代码本来表示物体形状。然后,通过比较输入点云与代码本中的特征向量来进行物体识别。
而基于对应分组的方法更关注点云中点之间的对应关系。它尝试找到点云中的点与其他点之间的配对关系,并利用这些对应关系来识别物体。这可以通过计算点对之间的距离或相似度来完成。
总的来说,ISM方法主要依靠特征向量和代码本进行物体识别,而基于对应分组的方法主要依靠点云中点的对应关系进行识别。
这两种方法各有优劣,适用于不同的应用场景。选择适合的方法取决于具体的需求和数据特点。
代码
#include <iostream>
#include <pcl/io/pcd_io.h>#include <pcl/features/normal_3d.h>
#include <pcl/features/feature.h>#include <pcl/visualization/cloud_viewer.h>
#include <pcl/features/fpfh.h>
#include <pcl/features/impl/fpfh.hpp>#include <pcl/recognition/implicit_shape_model.h>
#include <pcl/recognition/impl/implicit_shape_model.hpp>int main(){pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> normal_estimator; // 法线估计类normal_estimator.setRadiusSearch(25.0);std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr> training_clouds; // 用于存储所有的训练点云std::vector<pcl::PointCloud<pcl::Normal>::Ptr> training_normals; // 用于存储 训练点云的 法线特征std::vector<unsigned int> training_classes; // 训练地点云对应的类别std::vector<std::string> files;files.push_back("/home/jason/file/pcl-learning/13recognition识别/2隐式形状模型 ISM (Implicit Shape Model)/ism_train_cat.pcd");files.push_back("/home/jason/file/pcl-learning/13recognition识别/2隐式形状模型 ISM (Implicit Shape Model)/ism_train_horse.pcd");
// files.push_back("/home/jason/file/pcl-learning/13recognition识别/2隐式形状模型 ISM (Implicit Shape Model)/ism_train_michael.pcd");
// files.push_back("/home/jason/file/pcl-learning/13recognition识别/2隐式形状模型 ISM (Implicit Shape Model)/ism_train_wolf.pcd");
// files.push_back("/home/jason/file/pcl-learning/13recognition识别/2隐式形状模型 ISM (Implicit Shape Model)/ism_train_lioness.pcd");// 对训练数据点云 提取 法线特征for (size_t i = 0; i<files.size(); i++){pcl::PointCloud<pcl::PointXYZ>::Ptr tr_cloud(new pcl::PointCloud<pcl::PointXYZ>);if (pcl::io::loadPCDFile<pcl::PointXYZ>(files[0], *tr_cloud) == -1)return -1;pcl::PointCloud<pcl::Normal>::Ptr tr_normals(new pcl::PointCloud<pcl::Normal>);normal_estimator.setInputCloud(tr_cloud);normal_estimator.compute(*tr_normals);unsigned int tr_class = i;training_clouds.push_back(tr_cloud);training_normals.push_back(tr_normals);training_classes.push_back(tr_class);}// 隐式模型的训练和保存pcl::FPFHEstimation<pcl::PointXYZ, pcl::Normal, pcl::Histogram<153>>::Ptr fpfh(new pcl::FPFHEstimation<pcl::PointXYZ, pcl::Normal, pcl::Histogram<153>>); // 创建FPFHEstimation对象,用于估计FPFH特征fpfh->setRadiusSearch(30.0); // 设置搜索半径pcl::Feature<pcl::PointXYZ, pcl::Histogram<153>>::Ptr feature_estimate(fpfh); // 创建用于特征估计的Feature对象pcl::ism::ImplicitShapeModelEstimation<153, pcl::PointXYZ, pcl::Normal> ism; // 创建隐式特征性状估计对象ism.setFeatureEstimator(feature_estimate); // 设置特征估计器ism.setTrainingClouds(training_clouds);ism.setTrainingNormals(training_normals);ism.setTrainingClasses(training_classes);ism.setSamplingSize(2.0f); // 设置采样大小pcl::ism::ImplicitShapeModelEstimation<153, pcl::PointXYZ, pcl::Normal>::ISMModelPtr model =pcl::features::ISMModel::Ptr(new pcl::features::ISMModel); // 创建ISM模型ism.trainISM(model); // 训练ISM模型// std::string file("trained_ism_model.txt");
// model->saveModelToFile(file); // 将训练好的ISM模型保存到文件中
// model->loadModelFromfile(file); // 从文件中加载模型// 载入测试点云unsigned int testing_class = 0;pcl::PointCloud<pcl::PointXYZ>::Ptr testing_cloud(new pcl::PointCloud<pcl::PointXYZ>);if (pcl::io::loadPCDFile<pcl::PointXYZ>("/home/jason/file/pcl-learning/13recognition识别/2隐式形状模型 ISM (Implicit Shape Model)/ism_test_cat.pcd",*testing_cloud) < 0){std::cout << "test cloud file read err!" << std::endl;return -2;}// 估计测试点云 的 法线pcl::PointCloud<pcl::Normal>::Ptr testing_normals(new pcl::PointCloud<pcl::Normal>);normal_estimator.setInputCloud(testing_cloud);normal_estimator.compute(*testing_normals);// 处理给定的测试数据,生存投票列表pcl::features::ISMVoteList<pcl::PointXYZ>::Ptr vote_list = ism.findObjects(model,testing_cloud,testing_normals,testing_class);// 根据模型参数计算半径和标准差double radius = model->sigmas_[testing_class] * 10.0;double sigma = model->sigmas_[testing_class];// 寻找最强的峰值点std::vector<pcl::ISMPeak, Eigen::aligned_allocator<pcl::ISMPeak>> strongest_peaks;vote_list->findStrongestPeaks(strongest_peaks, testing_class, radius, sigma);// 创建带颜色信息的点云对象pcl::PointCloud<pcl::PointXYZRGB>::Ptr colored_cloud(new pcl::PointCloud<pcl::PointXYZRGB>);colored_cloud->height = 0;colored_cloud->width = 1;pcl::PointXYZRGB point;point.r = 255;point.g = 255;point.b = 255;// 将测试点云的点添加到带颜色的点云对象中for (size_t i_point = 0; i_point < testing_cloud->points.size(); i_point++){point.x = testing_cloud->points[i_point].x;point.y = testing_cloud->points[i_point].y;point.z = testing_cloud->points[i_point].z;colored_cloud->points.push_back(point);}colored_cloud->height += testing_cloud->points.size(); // 更新点云的高度// 设置峰值点的颜色并将其添加到带颜色的点云对象中point.r = 255;point.g = 0;point.b = 0;for (size_t i_vote = 0; i_vote < strongest_peaks.size(); i_vote++){point.x = strongest_peaks[i_vote].x;point.y = strongest_peaks[i_vote].y;point.z = strongest_peaks[i_vote].z;colored_cloud->points.push_back(point);}colored_cloud->height += strongest_peaks.size();pcl::visualization::CloudViewer viewer("Result viewer");viewer.showCloud(colored_cloud);while (!viewer.wasStopped()) {}return 0;}
我的电脑配置不高,这个算法特别耗时,我在网上找了代码的输出结果:
怎么说,如果猫的姿态变换了,它能识别出来??
参考:
PCL_Implicit Shape Model_隐式形状模型 ISM_yamgyutou的博客-CSDN博客
这篇关于『点云识别』隐性模型ISM(Implicit Shape Model)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!