PCL 3D-SIFT关键点检测(Z方向梯度约束
目录
一、概述
1.1原理
1.2实现步骤
1.3应用场景
二、代码实现
2.1关键函数
2.1.1 SIFT关键点检测
2.1.2 可视化函数
2.2完整代码
三、实现效果
PCL点云算法汇总及实战案例汇总的目录地址链接:
PCL点云算法与项目实战案例汇总(长期更新)
一、概述
3D-SIFT关键点检测是SIFT算法在三维点云中的扩展应用。与二维图像的SIFT类似,它通过尺度空间的构建和局部特征检测来提取点云的关键点。在三维点云中,SIFT可以通过计算每个点在Z方向的梯度,找到具有几何显著特征的关键点,适用于物体识别、特征匹配、点云配准等应用场景。
1.1原理
SIFT(Scale-Invariant Feature Transform)算法通过建立图像的尺度空间来提取关键点。在三维点云中,我们可以通过分析Z轴方向的变化(梯度)来检测点云的关键点。其核心步骤包括:
- 尺度空间构建:通过不同尺度的高斯核卷积,构造尺度空间,使得算法能够在不同的尺度下检测关键点。最小尺度通过参数 min_scale 设置,尺度空间的层数和每个层次的尺度数量由 n_octaves 和 n_scales_per_octave 控制。
- 关键点检测:通过对尺度空间的极值点检测来提取关键点,极值点通过比较邻域点在不同尺度下的响应得到。为了减少检测到的无效点,需要设置最小对比度 min_contrast,以过滤掉噪声。
- 梯度估计:利用Z方向的变化,估计点云中每个点的局部梯度,作为响应值。Z轴梯度用于构建响应函数,并检测局部极值。
参数解释
- min_scale:最小尺度,控制高斯核的最小标准差。
- n_octaves:尺度空间的层数。
- n_scales_per_octave:每个层次的尺度数量。
- min_contrast:最小对比度,用于过滤掉低响应值的点。
1.2实现步骤
- 加载点云数据。
- 初始化SIFT关键点提取器,设置所需的参数(如尺度、对比度等)。
- 通过SIFT算法提取点云中的关键点,并将结果转换为标准的XYZ点云格式。
- 可视化原始点云和提取的SIFT关键点。
1.3应用场景
- 三维物体识别:通过SIFT提取点云的关键点进行特征匹配和物体识别。
- 点云配准:利用关键点信息对不同视角的点云进行精确对齐。
- 特征提取:用于三维重建、机器人导航等领域中的特征提取和环境感知。
二、代码实现
2.1关键函数
2.1.1 SIFT关键点检测
void extractSIFTKeypoints(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, pcl::PointCloud<pcl::PointWithScale>::Ptr keypoints)
{// 设置SIFT算法参数const float min_scale = 0.001f; // 设置尺度空间中最小尺度的标准偏差 const int n_octaves = 3; // 设置尺度空间层数,越小则特征点越多 const int n_scales_per_octave = 15; // 设置尺度空间中计算的尺度个数const float min_contrast = 0.0001f; // 设置限制关键点检测的阈值 // 创建SIFT关键点检测对象pcl::SIFTKeypoint<pcl::PointXYZ, pcl::PointWithScale> sift;sift.setInputCloud(cloud); // 设置输入点云pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ> ());sift.setSearchMethod(tree); // 设置KdTree搜索sift.setScales(min_scale, n_octaves, n_scales_per_octave); // 设置尺度范围sift.setMinimumContrast(min_contrast); // 设置最小对比度// 执行SIFT关键点检测sift.compute(*keypoints);
}
2.1.2 可视化函数
void visualizeSIFTKeypoints(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr keypoints)
{boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("SIFT Keypoints Viewer"));int v1(0), v2(0);viewer->createViewPort(0, 0.0, 0.5, 1.0, v1);viewer->setBackgroundColor(1.0, 1.0, 1.0, v1); // 设置白色背景viewer->addText("Original Point Cloud", 10, 10, "v1_text", v1);viewer->createViewPort(0.5, 0.0, 1.0, 1.0, v2);viewer->setBackgroundColor(0.98, 0.98, 0.98, v2); // 设置灰色背景viewer->addText("SIFT Keypoints", 10, 10, "v2_text", v2);// 原始点云显示为绿色pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> original_color(cloud, 0, 255, 0);viewer->addPointCloud(cloud, original_color, "original_cloud", v1);// 关键点显示为红色pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> keypoints_color(keypoints, 255, 0, 0);viewer->addPointCloud(keypoints, keypoints_color, "keypoints_cloud", v2);// 设置点大小viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 5, "keypoints_cloud");// 添加坐标系viewer->addCoordinateSystem(1.0);while (!viewer->wasStopped()){viewer->spinOnce(100);boost::this_thread::sleep(boost::posix_time::microseconds(100000));}
}
2.2完整代码
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/keypoints/sift_keypoint.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/common/time.h>
#include <boost/thread/thread.hpp>// 基于Z梯度估计3D点云的SIFT关键点
namespace pcl
{template<>struct SIFTKeypointFieldSelector<PointXYZ>{inline floatoperator () (const PointXYZ& p) const{return p.z;}};
}// 提取SIFT关键点
void extractSIFTKeypoints(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, pcl::PointCloud<pcl::PointWithScale>::Ptr keypoints)
{const float min_scale = 0.001f; // 设置尺度空间中最小尺度的标准偏差 const int n_octaves = 3; // 设置尺度空间层数,越小则特征点越多 const int n_scales_per_octave = 15; // 设置尺度空间中计算的尺度个数const float min_contrast = 0.0001f; // 设置限制关键点检测的阈值 // 创建SIFT关键点检测对象pcl::SIFTKeypoint<pcl::PointXYZ, pcl::PointWithScale> sift;sift.setInputCloud(cloud); // 设置输入点云pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>());sift.setSearchMethod(tree); // 设置KdTree搜索sift.setScales(min_scale, n_octaves, n_scales_per_octave); // 设置尺度范围sift.setMinimumContrast(min_contrast); // 设置最小对比度// 执行SIFT关键点检测sift.compute(*keypoints);
}// 可视化SIFT关键点
void visualizeSIFTKeypoints(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr keypoints)
{boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("SIFT Keypoints Viewer"));int v1(0), v2(0);viewer->createViewPort(0, 0.0, 0.5, 1.0, v1);viewer->setBackgroundColor(1.0, 1.0, 1.0, v1); // 设置白色背景viewer->addText("Original Point Cloud", 10, 10, "v1_text", v1);viewer->createViewPort(0.5, 0.0, 1.0, 1.0, v2);viewer->setBackgroundColor(0.98, 0.98, 0.98, v2); // 设置灰色背景viewer->addText("SIFT Keypoints", 10, 10, "v2_text", v2);// 原始点云显示为绿色pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> original_color(cloud, 0, 255, 0);viewer->addPointCloud(cloud, original_color, "original_cloud", v1);// 关键点显示为红色pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> keypoints_color(keypoints, 255, 0, 0);viewer->addPointCloud(keypoints, keypoints_color, "keypoints_cloud", v2);// 设置点大小viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "keypoints_cloud");// 添加坐标系viewer->addCoordinateSystem(0.1);while (!viewer->wasStopped()){viewer->spinOnce(100);boost::this_thread::sleep(boost::posix_time::microseconds(100000));}
}int main(int argc, char* argv[])
{pcl::StopWatch watch; // 计时器pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_xyz(new pcl::PointCloud<pcl::PointXYZ>);pcl::io::loadPCDFile("bunny.pcd", *cloud_xyz);// 提取SIFT关键点pcl::PointCloud<pcl::PointWithScale>::Ptr sift_keypoints(new pcl::PointCloud<pcl::PointWithScale>);extractSIFTKeypoints(cloud_xyz, sift_keypoints);// 将SIFT关键点转换为标准XYZ格式pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_temp(new pcl::PointCloud<pcl::PointXYZ>);pcl::copyPointCloud(*sift_keypoints, *cloud_temp);std::cout << "Extracted " << sift_keypoints->size() << " keypoints" << std::endl;std::cout << "SIFT关键点提取用时: " << watch.getTimeSeconds() << "秒" << std::endl;// 可视化输入点云和SIFT关键点visualizeSIFTKeypoints(cloud_xyz, cloud_temp);return 0;
}
三、实现效果

相关文章:
PCL 3D-SIFT关键点检测(Z方向梯度约束
目录 一、概述 1.1原理 1.2实现步骤 1.3应用场景 二、代码实现 2.1关键函数 2.1.1 SIFT关键点检测 2.1.2 可视化函数 2.2完整代码 三、实现效果 PCL点云算法汇总及实战案例汇总的目录地址链接: PCL点云算法与项目实战案例汇总(长期更新&#…...
肺结节分割与提取系统(基于传统图像处理方法)
Matlab肺结节分割(肺结节提取)源程序,GUI人机界面版本。使用传统图像分割方法,非深度学习方法。使用LIDC-IDRI数据集。 工作如下: 1、读取图像。读取原始dicom格式的CT图像,并显示,绘制灰度直方图; 2、图像…...
ESP32 COAP 客户端观察者模式下,GET服务器的例程
目录 环境准备 示例代码 代码解释 初始化: CoAP 上下文和会话: 注册响应处理函数: 创建和发送 GET 请求: 处理响应: 主循环: 注意事项 ESP32 是一款功能强大的微控制器,支持多种通信协议,包括 CoAP(Constrained Application Protocol)。CoAP 是一种专为物联…...
【Kubernetes】常见面试题汇总(五十七)
目录 125. K8S 创建服务 status 为 ErrlmagePull? 126.不能进入指定容器内部? 特别说明: 题目 1-68 属于【Kubernetes】的常规概念题,即 “ 汇总(一)~(二十二)” 。 题目 …...
Java 设计模式 构建者模式
文章目录 1 概念2 使用方法1 创建步骤:2 使用步骤: 参考 1 概念 builder模式又叫建造者模式,属于创建型模式 作用:将一个复杂对象的构建与他的表示分离,可以一步一步构建对象,而不是使用构造函数构造一次…...
建设企业网站如何建
首先,企业网站是企业数字化转型的重要组成部分。在数字化浪潮的冲击下,企业需要通过建设网站来实现信息化管理,提高工作效率。通过企业网站,企业可以便捷地发布最新产品信息、公司新闻、招聘信息等,极大地提升了信息传…...
C++ inline 的更进一步理解
文章目录 1.概述2.ODR(One Definition Rule)问题3.范例测试代码4.好坏分析 ODR: One Definition Rule,即单一定义规则, C 语言中非常重要的一项规则,它确保程序的行为一致性并避免链接时出现冲突。ODR 的核心思想是在整个程序中,每…...
海康威视云台相机图像获取
直接上代码: import cv2# 替换为正确的RTSP链接 rtsp_url rtsp://admin:abcd12345192.168.1.64:554/h264/ch1/main/av_stream cap cv2.VideoCapture(rtsp_url)if not cap.isOpened():print("无法打开视频流,检查RTSP URL和凭证") else:whil…...
什么是词嵌入(Word Embedding)
1. 什么是词嵌入(Word Embedding) ⾃然语⾔是⼀套⽤来表达含义的复杂系统。在这套系统中,词是表义的基本单元。顾名思义,词向量是⽤来表⽰词的向量,也可被认为是词的特征向量或表征。把词映射为实数域向量的技术也叫词嵌⼊(word e…...
LSTM时间序列模型实战——预测上证指数走势
LSTM时间序列模型实战——预测上证指数走势 关于作者 作者:小白熊 作者简介:精通python、matlab、c#语言,擅长机器学习,深度学习,机器视觉,目标检测,图像分类,姿态识别,…...
基于 STM32F407 的 SPI Flash下载算法
目录 一、概述二、自制 FLM 文件1、修改使用的芯片2、修改输出算法的名称3、其它设置4、修改配置文件 FlashDev.c5、文件 FlashPrg.c 的实现 三、验证算法 一、概述 本文将介绍如何使用 MDK 创建 STM32F407 的 SPI Flash 下载算法。 其中,SPI Flash 芯片使用的是 W…...
力扣之1355.活动参与者
题目: Sql 测试用例: Create table If Not Exists Friends (id int, name varchar(30), activity varchar(30)); Create table If Not Exists Activities (id int, name varchar(30)); Truncate table Friends; insert into Friends (id, name, acti…...
数据资产治理:构建敏捷与安全的数据管理体系
在当今数字化的盛况下,作为核心资产的数据已经越发受到企业的重视。但是随着公司的逐步壮大,如何分析这些数据以及如何有效治理数据资产,以确保安全性、合规性以及易用性,是企业面临的重大挑战。数聚股份将从多年从业经验深度探讨…...
Nodejs连接Mysql笔记
框架搭建 安装Node.js 首先,确保你已经在系统上安装了Node.js和npm(Node Packaged Modules)。你可以通过以下命令检查是否已经安装:shell 或者 node -v 或者 npm -v 数据库连接代码 1.导入MySQL2库 npm install mysql2 2.在文件…...
Canvas:AI协作的新维度
在人工智能的浪潮中,OpenAI的最新力作Canvas,不仅是一款新工具,它标志着人工智能协作方式的一次革命性飞跃。Canvas为写作和编程提供了一个全新的交互界面,让用户能够与ChatGPT进行更紧密、更直观的协作。 Canvas的…...
【深度学习】— softmax回归、网络架构、softmax 运算、小批量样本的向量化、交叉熵
【深度学习】— softmax回归、网络架构、softmax 运算、小批量样本的向量化、交叉熵 3.4 Softmax 回归3.4.1 分类问题3.4.2 网络架构 3.4.3 全连接层的参数开销3.4.4 softmax 运算3.4.5 小批量样本的向量化3.4.6 损失函数对数似然softmax 的导数 3.4.7 信息论基础熵信息量重新审…...
C# Wpf 图片按照鼠标中心缩放和平移
C# Wpf 图片按照鼠标中心缩放和平移 1、缩放事件 MouseWheel(object sender, MouseWheelEventArgs e)2、平移相关的事件 MouseMove(object sender, MouseEventArgs e) MouseDown(object sender, MouseButtonEventArgs e) MouseUp(object sender, MouseButtonEventArgs e)3、…...
网络安全产品类型
1. 防火墙(Firewall) 功能:防火墙是网络安全的第一道防线,通过检查进出网络的流量来阻止未经授权的访问。它可以基于预定义的安全规则,过滤数据包和阻止恶意通信。 类型: 硬件防火墙:以专用设备…...
【开源风云】从若依系列脚手架汲取编程之道(五)
📕开源风云系列 🍊本系列将从开源名将若依出发,探究优质开源项目脚手架汲取编程之道。 🍉从不分离版本开写到前后端分离版,再到微服务版本,乃至其中好玩的一系列增强Plus操作。 🍈希望你具备如下…...
金融市场的衍生品交易及其风险管理探讨
金融衍生品市场是现代金融体系的重要组成部分,其交易量和复杂性在过去几十年中迅速增长。衍生品,如期权、期货、掉期等,因其灵活性和杠杆效应,广泛应用于风险管理、投机和资产配置等多个领域。本文将探讨金融衍生品交易的关键特点…...
vscode里如何用git
打开vs终端执行如下: 1 初始化 Git 仓库(如果尚未初始化) git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...
大学生职业发展与就业创业指导教学评价
这里是引用 作为软工2203/2204班的学生,我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要,而您认真负责的教学态度,让课程的每一部分都充满了实用价值。 尤其让我…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
Docker 本地安装 mysql 数据库
Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker ;并安装。 基础操作不再赘述。 打开 macOS 终端,开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...
JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...
GitFlow 工作模式(详解)
今天再学项目的过程中遇到使用gitflow模式管理代码,因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存,无论是github还是gittee,都是一种基于git去保存代码的形式,这样保存代码…...
08. C#入门系列【类的基本概念】:开启编程世界的奇妙冒险
C#入门系列【类的基本概念】:开启编程世界的奇妙冒险 嘿,各位编程小白探险家!欢迎来到 C# 的奇幻大陆!今天咱们要深入探索这片大陆上至关重要的 “建筑”—— 类!别害怕,跟着我,保准让你轻松搞…...
【JVM】Java虚拟机(二)——垃圾回收
目录 一、如何判断对象可以回收 (一)引用计数法 (二)可达性分析算法 二、垃圾回收算法 (一)标记清除 (二)标记整理 (三)复制 (四ÿ…...
从“安全密码”到测试体系:Gitee Test 赋能关键领域软件质量保障
关键领域软件测试的"安全密码":Gitee Test如何破解行业痛点 在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的"神经中枢"。从国防军工到能源电力,从金融交易到交通管控,这些关乎国计民生的关键领域…...
uniapp 集成腾讯云 IM 富媒体消息(地理位置/文件)
UniApp 集成腾讯云 IM 富媒体消息全攻略(地理位置/文件) 一、功能实现原理 腾讯云 IM 通过 消息扩展机制 支持富媒体类型,核心实现方式: 标准消息类型:直接使用 SDK 内置类型(文件、图片等)自…...

