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操作。 🍈希望你具备如下…...
金融市场的衍生品交易及其风险管理探讨
金融衍生品市场是现代金融体系的重要组成部分,其交易量和复杂性在过去几十年中迅速增长。衍生品,如期权、期货、掉期等,因其灵活性和杠杆效应,广泛应用于风险管理、投机和资产配置等多个领域。本文将探讨金融衍生品交易的关键特点…...
[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解
突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 安全措施依赖问题 GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...
OkHttp 中实现断点续传 demo
在 OkHttp 中实现断点续传主要通过以下步骤完成,核心是利用 HTTP 协议的 Range 请求头指定下载范围: 实现原理 Range 请求头:向服务器请求文件的特定字节范围(如 Range: bytes1024-) 本地文件记录:保存已…...
自然语言处理——循环神经网络
自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元(GRU)长短期记忆神经网络(LSTM)…...
【论文阅读28】-CNN-BiLSTM-Attention-(2024)
本文把滑坡位移序列拆开、筛优质因子,再用 CNN-BiLSTM-Attention 来动态预测每个子序列,最后重构出总位移,预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵(S…...
Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)
Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习) 一、Aspose.PDF 简介二、说明(⚠️仅供学习与研究使用)三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...
深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用
文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么?1.1.2 感知机的工作原理 1.2 感知机的简单应用:基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...
逻辑回归暴力训练预测金融欺诈
简述 「使用逻辑回归暴力预测金融欺诈,并不断增加特征维度持续测试」的做法,体现了一种逐步建模与迭代验证的实验思路,在金融欺诈检测中非常有价值,本文作为一篇回顾性记录了早年间公司给某行做反欺诈预测用到的技术和思路。百度…...
HubSpot推出与ChatGPT的深度集成引发兴奋与担忧
上周三,HubSpot宣布已构建与ChatGPT的深度集成,这一消息在HubSpot用户和营销技术观察者中引发了极大的兴奋,但同时也存在一些关于数据安全的担忧。 许多网络声音声称,这对SaaS应用程序和人工智能而言是一场范式转变。 但向任何技…...
Linux部署私有文件管理系统MinIO
最近需要用到一个文件管理服务,但是又不想花钱,所以就想着自己搭建一个,刚好我们用的一个开源框架已经集成了MinIO,所以就选了这个 我这边对文件服务性能要求不是太高,单机版就可以 安装非常简单,几个命令就…...

