ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

点云特征点提取

2022-02-01 21:31:21  阅读:283  来源: 互联网

标签:PointCloud 提取 特征 harris pcl 点云 include cloud 关键点


1.Harris关键点提取并可视化

#include <iostream>
#include <pcl/console/parse.h>
#include <pcl/console/print.h>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
#include <pcl/keypoints/harris_3d.h> // Harris3D关键点检测
#include <pcl/visualization/pcl_visualizer.h>
#include <boost/thread/thread.hpp>
#include<pcl/filters/filter.h>
int
main(int argc, char** argv)
{
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
    if (pcl::io::loadPCDFile<pcl::PointXYZ>("source.pcd", *cloud) == -1) // load the file
    {
        pcl::console::print_error("Couldn't read file %s!\n");
        return (-1);
    }
    std::vector<int>nan_indicies;
    pcl::removeNaNFromPointCloud(*cloud, *cloud, nan_indicies);
    cout << "从输入点云中读取:" << cloud->points.size() << "个点" << endl;



    //-----------------------------Harris关键点提取----------------------------------
    //注意此处PCL的point类型设置为<pcl::PointXYZI>,即除了x、y、z坐标还必须包含强度信息
    //因为Harris的评估值保存在输出点云的(I)分量中,Harris输出点云中的(I)非传统点云中的
    //强度信息,因此后续在保存和可视化输出点云的时候需要通过点的索引来重新获取。
    //-------------------------------------------------------------------------------
    pcl::HarrisKeypoint3D <pcl::PointXYZ, pcl::PointXYZI> harris;
    pcl::PointCloud<pcl::PointXYZI>::Ptr Harris_keypoints(new pcl::PointCloud<pcl::PointXYZI>);

    harris.setInputCloud(cloud);     // 提供指向输入数据集的指针
    harris.setMethod(harris.LOWE);   // 设置要计算响应的方法(可以不设置)
    harris.setRadius(0.3);          // 设置法线估计和非极大值抑制的半径。
    harris.setRadiusSearch(0.2);    // 设置用于关键点检测的最近邻居的球半径
    harris.setNonMaxSupression(true);// 是否应该应用非最大值抑制
    harris.setThreshold(0.02);     // 设置角点检测阈值,只有当非极大值抑制设置为true时才有效
    harris.setRefine(true);          // 检测到的关键点是否需要细化,设置为true时,关键点为点云中的点
    harris.setNumberOfThreads(6);    // 初始化调度程序并设置要使用的线程数
    harris.compute(*Harris_keypoints);


    cout << "提取关键点" << Harris_keypoints->points.size() << "个" << endl;
    pcl::PointCloud<pcl::PointXYZ>::Ptr keypoints(new pcl::PointCloud<pcl::PointXYZ>);
    //-----------------------获取关键点的索引-------------------------
    pcl::PointIndicesConstPtr keypoints2_indices = harris.getKeypointsIndices();
    //pcl::PointXYZI格式无法正确保存和显示,这里通过索引从原始点云中获取位于点云中特征点
    pcl::copyPointCloud(*cloud, *keypoints2_indices, *keypoints);
    //pcl::io::savePCDFile("keypointsrgb.pcd", *keypoints, true);
    //----------------------------可视化-----------------------------
    boost::shared_ptr<pcl::visualization::PCLVisualizer>viewer(new pcl::visualization::PCLVisualizer("显示点云"));
    viewer->setBackgroundColor(255, 255, 255);  //设置背景颜色为白色
    viewer->setWindowName("Harris3D关键点检测");
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> harris_color_handler(keypoints, 255, 0, 0);
    viewer->addPointCloud<pcl::PointXYZ>(keypoints, harris_color_handler, "Harris_keypoints");
    viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 5, "Harris_keypoints");
    viewer->addPointCloud(cloud, "input_cloud");
    viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 0, 1, 0, "input_cloud");
    while (!viewer->wasStopped())
    {
        viewer->spinOnce(100);
        boost::this_thread::sleep(boost::posix_time::microseconds(1000));
    }

    return (0);
}

2.SIFT关键点提取

#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>
#include <pcl/console/time.h>
using namespace std;

namespace pcl
{
    template<>
    struct SIFTKeypointFieldSelector<PointXYZ>
    {
        inline float
            operator () (const PointXYZ& p) const
        {
            return p.z;
        }
    };
}

int
main(int argc, char* argv[])
{

    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_xyz(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::io::loadPCDFile("source.pcd", *cloud_xyz);//将第二个命令行参数所代表的文件作为输入文件读入
    std::vector<int>nan_indicies;
    pcl::removeNaNFromPointCloud(*cloud_xyz, *cloud_xyz, nan_indicies);
    const float min_scale = 0.3;//尺度空间中最小尺度的标准偏差
    const int n_octaves = 3;//高斯金字塔中组的数目
    const int n_scales_per_octave = 5;//每组计算的尺度数目
    const float min_contrast = 0.02;//设置关键点检测的阈值

    //SIFT关键点检测
    pcl::SIFTKeypoint<pcl::PointXYZ, pcl::PointWithScale> sift;//创建sift关键点检测对象
    pcl::PointCloud<pcl::PointWithScale> result;//SIFT关键点提取结果
    sift.setInputCloud(cloud_xyz);//设置输入点云
    pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>());
    sift.setSearchMethod(tree);//创建一个空的kd树对象tree,并把它传递给sift检测对象
    sift.setScales(min_scale, n_octaves, n_scales_per_octave);//指定搜索关键点的尺度范围
    sift.setMinimumContrast(min_contrast);//设置限制关键点检测的阈值
    sift.compute(result);//执行sift关键点检测,保存结果在result

    //类型转换
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_temp(new pcl::PointCloud<pcl::PointXYZ>);
    copyPointCloud(result, *cloud_temp);//将点类型pcl::PointWithScale的数据转换为点类型pcl::PointXYZ的数据
    std::cout << result.size() << endl;
    //可视化输入点云和关键点
    pcl::visualization::PCLVisualizer viewer("Sift keypoint");
    viewer.setBackgroundColor(255, 255, 255);
    viewer.addPointCloud(cloud_xyz, "cloud");//在视窗中添加原始点云数据
    viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 0, 0, 0, "cloud");
    viewer.addPointCloud(cloud_temp, "keypoints");//将SIFT关键点添加至视窗
    viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 9, "keypoints");
    viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 0, 0, 255, "keypoints");

    while (!viewer.wasStopped())
    {
        viewer.spinOnce();
    }
    return 0;

}//sift关键点检测

3.Narf关键点提取

下次附上代码,有地方没运行。

标签:PointCloud,提取,特征,harris,pcl,点云,include,cloud,关键点
来源: https://blog.csdn.net/weixin_56004792/article/details/122764964

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有