『点云识别』隐性模型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;

}

我的电脑配置不高,这个算法特别耗时,我在网上找了代码的输出结果:

 绿色是要测试点云,灰色是colored_cloud,在猫中可以看到有一个红色质心。

 

怎么说,如果猫的姿态变换了,它能识别出来??

参考:

PCL_Implicit Shape Model_隐式形状模型 ISM_yamgyutou的博客-CSDN博客

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值