PCL点云库入门——PCL库中点云数据拓扑关系之K-D树(KDtree)

1、点云的拓扑邻域

        在三维空间数据处理的领域中,点云的邻域概念显得尤为关键,它不仅链接了点云数据之间的拓扑结构,而且在构建点云间的拓扑关系时起到了桥梁的作用。这种关系的建立,使得我们能够以一种高效、迅速的方式管理庞大的三维点云数据集。想象一下,成千上万的点,每一个都携带着位置、颜色、反射率等信息,它们通过邻域的连接,形成了一个复杂而有序的网络。这不仅为点云数据的精简提供了可能,使得我们可以去除冗余的点而不损失关键信息,还为点云分割提供了依据,使得我们可以根据不同的特征将点云分成有意义的子集。此外,点云识别、点云配准以及点云曲面重建等后续处理工作,都依赖于这种拓扑关系的精确构建。通过邻域的分析,我们可以识别出点云中的物体,将它们与数据库中的模型进行匹配,甚至可以将来自不同视角的点云数据进行精确对齐。最终,这些处理工作共同为三维重建、虚拟现实、机器人导航等应用提供了坚实的基础,推动了这些领域技术的发展和创新。

1.1 、点云的邻域类型

        邻域是数学和拓扑学中的概念,在三维点云数据中,表示有一定空间位置分布的离散点集且包含了采样点云数据的一个集合。假如一个物体的点云数据用V表示,结构若干空间换分之后,A为V中的一部分点云数据,P为A的一个点云数据点,则称A为点云P的邻域,用集合关系表示为如下:

P\epsilon A\subseteq V

        对于点云数据集P,p为P中的一个点云,点云p的邻域可以用索引集合Ni来表示,通过对下标i的操作,就能访问到与点云p有关系的点云数据。点云数据空间分部决定了邻域的类型,在三维点云数据处理中常见的有K邻域、Voronoi邻域和BSP邻域,其中K邻域在很多点云处理算法较为常用。三种邻域类型的图示如图1。由于K领域较常见,下面仅对K领域进行简要的讲解。

1.1.1、K领域 

        K邻域就是表示目标点云p,与K个欧式距最近点云组成的一个点云数据集,邻域内的点云数据满足下面的关系式子:

 式中:\prod为排列值从小到大,i\epsilon \left [ 1,k-1 \right ]K邻域的点云索引集合为:

         K邻域另外一种以半径R为球的定义,目标点云p为球心,在半径R内的球内搜索满足条件的点云组成K邻域,具体按照自己的需求来选择数据点K个,另外还按半径R距离的方式构建K邻域

1.2、 建立点云拓扑关系的常有方法

        为了构建点云数据的拓扑关系,一种直接的方法是计算与目标点云数据最近的点之间的绝对距离,从而确定拓扑链接的依据。然而,这种方法在处理大规模的点云数据集时,效率显得非常低下,这并不利于对数据进行整体的处理和分析。为了提高处理效率,空间索引技术在建立点云数据的拓扑关系中得到了广泛的应用。空间索引技术通过构建特定的数据结构,可以快速定位和检索点云数据中的点,从而大大提高了数据处理的速度和效率。一些著名的空间索引结构包括空间栅栏法、KDB树、R树、K-D树、四叉树、八叉树以及BSP树等。这些空间索引结构各有其特点和适用场景,在三维点云数据处理领域,栅栏法、K-D树(KDtree树)和八叉树(Octree树)尤其受到青睐,因为它们在处理大规模三维数据时,能够提供更为高效和准确的数据组织和检索方式。在PCL库中提供的有K-D树(KDtree树)和八叉树(Octree树)两种方法,本节和下节将对这两个方法进行讲解和代码示例。

2、KD树(KDtree)

2.1、 KDtree基本理论

        K-D树是一种用于构建K维空间中数据集之间访问关系的数据结构,KDTree就是二叉查找树(Binary Search Tree,BST)的变种。它在三维点云的空间划分和最近邻域搜索方面尤为便捷。在离散点云数据集中,每个独立的点都由K-D树的非空叶子节点表示,从而构建起离散点集之间的拓扑关系。接下来,我将简要介绍K-D树在空间划分和最近邻域搜索。

2.1.1 、KDtree空间划分

        K-D树的空间划分是基于数据集的维度进行的。树的叶子节点存储K维的数据点,而非叶子节点则代表对应维度的划分线。在进行空间划分时,我们首先让划分线平行于K维中的某一维参考轴,将空间中的数据点分为两部分:一部分大于该维度上的参考值,另一部分小于该维度上的参考值。然后,根据这两部分的不同属性,决定(K-1)维空间的划分方向,并继续划分,直至空间被划分至一维。之后,返回到K维,重复上述操作,直到满足特定条件为止。上述提到的参考值,通常是该维度下所有数据点的平均值或接近平均值的数值。

        在三维点云数据的空间划分中,K-D树首先使用X轴来确定划分面。具体操作如下:计算点云数据中所有X坐标的平均值,然后通过这个均值点作一个平行于YOZ平面的分割面,将点云分布的空间分为两部分。接着,在K-D树的下一层,即通过YOZ平面分割得到的子空间中,计算所有Y坐标的平均值,通过这个均值点作一个平行于XOZ平面的分割面,再次将点云分布的空间分割为子空间。最后,在K-D树的再下一层,即通过XOZ平面分割得到的子空间中,计算所有Z坐标的平均值,通过这个均值点作一个平行于XOY平面的分割面,将点云分布的空间再次分割为子空间。递归执行这三个步骤,直至完成整个空间的划分。

         三维K-D树则是分别用X-Y-Z-X轴为参考轴,根据约束的条件确定分割面,将分布在三维空间的数据划分到K-D树的叶子节点中,三维示意图见图2。

2.1.2、KDtree空间划分示例

        下面以二维的KD树例,进行空间划分说明。假设有如下由七个二维数据组成的二维数据集:

X = { ( 3 , 7 ) , ( 2 , 6 ) , ( 0 , 5 ) , ( 1 , 8 ) , ( 7 , 5 ) , ( 5 , 4 ) , ( 6 , 7 ) }

        第1次划分:按照第1维特征(x轴特征)进行划分,选取( 3 , 7 ) 为根节点将整个点集划分为左右两部分(蓝色线为分界线),结果如下:

        第2次划分:按照第2维特征(y轴特征)进行划分,分别以( 2 , 6 )和( 7 , 5 )为根节点将左右两平面划分为上下两个平面(绿色线为分界线) ,结果如下:

        最终的KD-Tree结构,黄色线上的点是叶子节点 ,完成划分。

2.1.3、KDtree的最近邻域搜索

        在三维点云数据处理中,最常用K-D树最近邻域搜索算法,其目标是根据给定目标点云找到树中最近的K邻域,由于K-D树左子树小于根节点,右子树大于根节点的特点,能够很快的排除一些不必要访问的空间,搜索速度很快。

2.1.4、KDtree邻域搜索示例

        继续上面的二维KD-Tree例子。假设待查询点为( 5 , 5.5 ),如下:

        二分查找,与根节点的第1维特征进行比较,由于5 > 3 ,因此进入右子树(红色部分)。计算与根节点的距离d i s t = 2.5 作为当前最短距离。

        二分查找,与右半平面分割线上节点的第2维特征进行比较,由于5.5 > 5 ,因此进入该节点的右子树(橙色部分)。计算与( 7 , 5 ) 的距离d i s t ≈ 2.0616 小于当前最短距离,因此更新当前最短距离。

        二分查找,计算与叶子节点( 6 , 7 ) 的距离d i s t ≈ 1.8028 ,小于当前最短距离,因此更新当前最短距离。由于搜索到了叶子节点,接下来开始回溯 。

        以待查询点为圆心,当前最短距离为半径作圆,与( 7 , 5 ) 所在的分割线相交,因此对节点( 7 , 5 ) 的另一子树进行搜索。

          计算与叶子节点( 5 , 4 ) 在距离d i s t = 1.5,小于当前最短距离,因此更新当前最短距离,继续进行回溯。由于以待查询点为圆心,当前最短距离为半径的圆与其他分割线无交点,因此认为节点( 5 , 4 ) 即为待查询点的最近邻,最短距离为1.5,搜索完毕。

        注意:K-D树在数据维度较小时(如小于50),搜索效率很快,当维度大于100时,搜索效率会随着维度的增加而下降。一般而言数据的规模满足N>>2的D次方,搜索速度高效。

2.2、PCL库中的KDtree

        PCL库中实现的KDtree方法在两个模块都有,分别是kdtreesearch模块,但是功能都是一样的。下面仅对Kdtree模块中的进行说明,另外的一个模块后序用到时在展开,基本功能都差不多。

        PCL库的KDtree是基于第三库FLANN封装实现的,有pcl::KdTree<PointT>pcl::KdTreeFLANN<PointT>两个模板类实现,其中pcl::KdTree<PointT>基础类,pcl::KdTreeFLANN<PointT>pcl::KdTree<PointT>的子类,两个类实现了R半径距离K个最近点的K领域搜索方法。主要的函数方法有如下表内容。

主要函数

简要说明

virtual void setInputCloud (const PointCloudConstPtr &cloud,

 const IndicesConstPtr &indices = IndicesConstPtr ())

设置需要构建KDtree树的点云,参数:点云和对应点云的索引(默认可以不用输入)。

virtual int  nearestKSearch (const PointT &p_q, int k,  std::vector<int> &k_indices, std::vector<float> &k_sqr_distances) const = 0;

K个领域搜索函数接口,参数:参考点、搜索的K个数、K个的点对应的索引和K个点与参考点之间的距离平方(从小到大排列)。

 virtual int  radiusSearch (const PointT &p_q, double radius, std::vector<int> &k_indices,

 std::vector<float> &k_sqr_distances, unsigned int max_nn = 0) const = 0;

R半径搜索函数接口,参数:参考点、半径r、r半径内的点对应的索引和r半径内点与参考点之间的距离平方(从小到大排列)。

template <typename PointTDiff> inline int  nearestKSearchT (const PointTDiff &point, int k,

 std::vector<int> &k_indices, std::vector<float> &k_sqr_distances) const

K个领域搜索函数接口,参数:模版点类型、搜索的K个数、K个的点对应的索引和K个点与参考点之间的距离平方(从小到大排列)

 template <typename PointTDiff> inline int radiusSearchT (const PointTDiff &point, double radius, std::vector<int> &k_indices, std::vector<float> &k_sqr_distances, unsigned int max_nn = 0) const

R半径搜索函数接口,参数:模版点类型、半径r、r半径内的点对应的索引和r半径内点与参考点之间的距离平方(从小到大排列)。

 inline void setPointRepresentation (const PointRepresentationConstPtr &point_representation)

设置N维数据构建KDtree树,参数:N维的点数据。

2.3、PCL库中的KDtree的代码示例

        新建文件 PCLKDtreemain.cpp,内容如下,示例代码中进行R半径距离和K个最近点的K领域搜索示例,和结果可视化,具体内容参考代码。

/*****************************************************************//**
* \file   PCLKDtreemain.cpp
* \brief  
*
* \author YZS
* \date   December 2024
*********************************************************************/
#include<iostream>
#include <vector>
#include <ctime>
#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
#include <pcl/io/auto_io.h>
#include <pcl/kdtree/kdtree_flann.h>
#include <pcl/search/kdtree.h>
#include <pcl/visualization/pcl_visualizer.h>
using namespace std;
void PCLKDtreeUse()
{// 随机种子初始化srand(time(NULL));pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);// 生成点云数据1000个cloud->width = 3000;cloud->height = 1;  cloud->points.resize(cloud->width * cloud->height);for (size_t i = 0; i < cloud->points.size(); ++i) {cloud->points[i].x = 1024.0f * rand() / (RAND_MAX + 1.0f);cloud->points[i].y = 1024.0f * rand() / (RAND_MAX + 1.0f);cloud->points[i].z = 1024.0f * rand() / (RAND_MAX + 1.0f);}pcl::KdTreeFLANN<pcl::PointXYZ> kdtree;//pcl::search::KdTree<pcl::PointXYZ> kdtree;//设置搜索的空间,点云数据cloudkdtree.setInputCloud(cloud);// 生成一个查询点pcl::PointXYZ searchPoint;searchPoint.x = 1024.0f * rand() / (RAND_MAX + 1.0f);searchPoint.y = 1024.0f * rand() / (RAND_MAX + 1.0f);searchPoint.z = 1024.0f * rand() / (RAND_MAX + 1.0f);// 方式1:K个最近邻域搜索int K = 100;//表示搜索100个临近点std::vector<int>KNSearch(K);//  保存搜索到的临近点的索引std::vector<float> KNSquaredDistance(K);//保存对应临近点的距离的平方std::cout << "K nearest neighbor search at (" << searchPoint.x<< " " << searchPoint.y<< " " << searchPoint.z<< ") with K=" << K << std::endl;//保存K个领域的点云数据pcl::PointCloud<pcl::PointXYZ>::Ptr cloudK(new pcl::PointCloud<pcl::PointXYZ>);if (kdtree.nearestKSearch(searchPoint, K, KNSearch, KNSquaredDistance) > 0) {for (size_t i = 0; i < KNSearch.size(); ++i){std::cout << "    " << cloud->points[KNSearch[i]].x<< " " << cloud->points[KNSearch[i]].y<< " " << cloud->points[KNSearch[i]].z<< " (距离平方: " << KNSquaredDistance[i] << ")" <<  std::endl;pcl::PointXYZ pt;pt.getVector3fMap() =  cloud->points[KNSearch[i]].getVector3fMap();cloudK->points.emplace_back(pt);}}// 方式2:R半径邻域搜索std::vector<int> radiusSearch;std::vector<float>radiusSquaredDistance;// R半径值float radius = 300.0f;std::cout << "Neighbors within radius search at (" << searchPoint.x<< " " << searchPoint.y<< " " << searchPoint.z<< ") with radius=" << radius << std::endl;//保存R半径领域的点云数据pcl::PointCloud<pcl::PointXYZ>::Ptr cloudR(new pcl::PointCloud<pcl::PointXYZ>);if (kdtree.radiusSearch(searchPoint, radius, radiusSearch,  radiusSquaredDistance) > 0) {for (size_t i = 0; i < radiusSearch.size(); ++i) {std::cout << "    " << cloud->points[radiusSearch[i]].x<< " " << cloud->points[radiusSearch[i]].y<< " " << cloud->points[radiusSearch[i]].z<< " (距离平方:: " << radiusSquaredDistance[i] << ")" <<  std::endl;pcl::PointXYZ pt;pt.getVector3fMap() =  cloud->points[radiusSearch[i]].getVector3fMap();cloudR->points.emplace_back(pt);}}//K个邻域的结果可视化--双窗口// PCLVisualizer对象pcl::visualization::PCLVisualizer viewer("DoubleVIS");//创建左右窗口的ID v1和v2int v1(0);int v2(1);//设置V1窗口尺寸和背景颜色viewer.createViewPort(0.0, 0.0, 0.5, 1, v1);viewer.setBackgroundColor(0, 0, 0, v1);//设置V2窗口尺寸和背景颜色viewer.createViewPort(0.5, 0.0, 1, 1, v2);viewer.setBackgroundColor(0.1, 0.1, 0.1, v2);//设置cloud1的渲染颜色,点云的ID和指定可视化窗口v1pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ>   cloud1_color(cloud, 255, 255, 255);viewer.addPointCloud(cloud, cloud1_color, "cloud1", v1);//设置cloud2的渲染颜色,点云的ID和指定可视化窗口v2pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ>   cloud2_color(cloud, 250, 255, 255);viewer.addPointCloud(cloud, cloud2_color, "cloud2", v2);//添加cloudK到可视化窗口v1中pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ>   cloudk_color(cloudK, 255, 0, 0);viewer.addPointCloud(cloudK, cloudk_color, "cloudk", v1);viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE,  3, "cloudk");//添加cloudR到可视化窗口v2中pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ>   cloudr_color(cloudK, 0, 255, 0);viewer.addPointCloud(cloudR, cloudr_color, "cloudr", v2);viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE,  3, "cloudr");// 可视化循环主体while (!viewer.wasStopped()){viewer.spinOnce();}
}
int main(int argc,char *argv[])
{PCLKDtreeUse();std::cout<<"Hello PCL!"<<std::endl;std::system("pause");return 0;
}

       可视化 结果:

        至此完成第七节PCL库中点云数据拓扑关系之K-D树简单学习,下一节我们将进入《PCL库中点云数据拓扑关系之OCtree》的学习。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/493567.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【bodgeito】攻防实战记录

也许有一天我们再相逢&#xff0c;睁开眼睛看清楚&#xff0c;我才是英雄。 进入网站整体浏览网页 点击页面评分进入关卡 一般搭建之后这里都是红色的&#xff0c;黄色是代表接近&#xff0c;绿色代表过关 首先来到搜索处本着见框就插的原则 构造payload输入 <script>…

【1.排序】

排序 笔记记录 1.排序的基本概念1.1 排序的定义 2. 插入排序2.1 直接插入排序2.2 折半插入排序2.3 希尔排序 3. 交换排序3.1 冒泡排序3.2 快速排序 4. 选择排序4.1 简单选择排序4.2 堆排序 5. 归并排序、基数排序和计数排序5.1 归并排序4.2 基数排序4.3 计数排序 6. 各种内部排…

杂七杂八的网络安全知识

一、信息安全概述 1.信息与信息安全 信息与信息技术 信息奠基人&#xff1a;香农&#xff1a;信息是用来消除随机不确定性的东西 信息的定义&#xff1a;信息是有意义的数据&#xff0c;是一种要适当保护的资产。数据经过加工处理之后&#xff0c;就成为信息。而信息需要经…

Loki 微服务模式组件介绍

目录 一、简介 二、架构图 三、组件介绍 Distributor&#xff08;分发器&#xff09; Ingester&#xff08;存储器&#xff09; Querier&#xff08;查询器&#xff09; Query Frontend&#xff08;查询前端&#xff09; Index Gateway&#xff08;索引网关&#xff09…

基于LabVIEW的USRP信道测量开发

随着无线通信技术的不断发展&#xff0c;基于软件无线电的设备&#xff08;如USRP&#xff09;在信道测量、无线通信测试等领域扮演着重要角色。通过LabVIEW与USRP的结合&#xff0c;开发者可以实现信号生成、接收及信道估计等功能。尽管LabVIEW提供了丰富的信号处理工具和图形…

STM32-笔记5-按键点灯(中断方法)

1、复制03-流水灯项目&#xff0c;重命名06-按键点灯&#xff08;中断法&#xff09; 在\Drivers\BSP目录下创建一个文件夹exti&#xff0c;在该文件夹下&#xff0c;创建两个文件exti.c和exti.h文件&#xff0c;并且把这两个文件加载到项目中&#xff0c;打开项目工程文件 加载…

windwos defender实现白名单效果(除了指定应用或端口其它一律禁止)禁止服务器上网

一、应用场景说明 当我们的一台windows服务器中毒&#xff0c;变成别人肉鸡&#xff0c;不断向外请示非法网站或攻击其它服务器。 要彻底清除相关木马或病毒往往需要的时间比较长&#xff0c;比较有效的方法是禁止服务器主动向外发包除了网站端口和远程程序除外。 其实这就是一…

【AI学习】Huggingface复刻Test-time Compute Scaling技术

OpenAI ChatGPT o1 背后的关键技术Test-time Compute Scaling&#xff0c;Huggingface实现并开源了&#xff01; Hugging Face 团队发布了一篇关于“开源模型中的推理阶段计算扩展”&#xff08;Test-time Compute Scaling&#xff09; 的研究文章。Hugging Face 团队通过复现…

Word图片嵌入格式不正确的解决办法

问题描述: 如图, 粘贴到word的图片只显示底部一部分 解决方法: 第一步 先将图片嵌入文本行中 第二步 再将图片设置为正文格式 然后就出来了

【活动邀请·深圳】深圳COC社区 深圳 AWS UG 2024 re:Invent re:Cap

re:Invent 是全球云计算领域的顶级盛会&#xff0c;每年都会吸引来自世界各地的技术领袖、创新者和实践者汇聚一堂&#xff0c;分享最新的技术成果和创新实践&#xff0c;深圳 UG 作为亚马逊云科技技术社区的重要组成部分&#xff0c;将借助 re:Invent 的东风&#xff0c;举办此…

Intel-ECI之Codesys PLC + Ethercat 远端IO + Codesys IDE编程

目录 一、 准备工作 二、安装Codesys 软件 PLC 三、 使用Codesys IDE 编程测试 CODESYS* 是领先的独立于制造商的 IEC 61131-3 自动化软件&#xff0c;适用于工程控制系统。它用于 Intel Edge Controls for Industrial&#xff08;Intel ECI 或 ECI&#xff09;&#xff0c;…

渗透测试-前端加密分析之RSA加密登录(密钥来源服务器)

本文是高级前端加解密与验签实战的第6篇文章&#xff0c;本系列文章实验靶场为Yakit里自带的Vulinbox靶场&#xff0c;本文讲述的是绕过RSA加密来爆破登录。 分析 这里的代码跟上文的类似&#xff0c;但是加密的公钥是通过请求服务端获取的 http://127.0.0.1:8787/crypto/js/…

【Leecode】Leecode刷题之路第87天之扰乱字符串

题目出处 87-扰乱字符串-题目出处 题目描述 个人解法 思路&#xff1a; todo代码示例&#xff1a;&#xff08;Java&#xff09; todo复杂度分析 todo官方解法 87-扰乱字符串-官方解法 方法1&#xff1a;动态规划 思路&#xff1a; 代码示例&#xff1a;&#xff08;Java&…

Qt之串口设计-线程实现(十二)

Qt开发 系列文章 - Serial-port&#xff08;十二&#xff09; 目录 前言 一、SerialPort 二、实现方式 1.创建类 2.相关功能函数 3.用户使用 4.效果演示 5.拓展应用-实时刷新 总结 前言 Qt作为一个跨平台的应用程序开发框架&#xff0c;在串口编程方面提供了方便易用…

Restaurants WebAPI(三)——Serilog/

文章目录 项目地址一、Serilog使用1.1 安装 Serilog1.2 注册日志服务1.3 设置日志级别和详情1.4 配置到文件里1.5 给不同的环境配置日志1.5.1 配置appsettings.Development.json二、Swagger的使用三、自定义Exception中间件3.1 使用FluentValidation项目地址 教程作者:教程地址…

Tekscan压力分布测量系统:电池安全与质量提升的保障

随着科技的快速发展&#xff0c;电池技术在电动汽车、工业和消费电子等领域的重要性日益增加。Tekscan 压力分布测量系统针对这些领域的需求&#xff0c;成为推动电池技术进步和多领域创新的重要工具。 在锂离子电池的充放电过程中&#xff0c;热循环引起的膨胀和收缩对其性能和…

【WRF教程第3.1期】预处理系统 WPS 详解:以4.5版本为例

预处理系统 WPS 详解&#xff1a;以4.5版本为例 每个 WPS 程序的功能程序1&#xff1a;geogrid程序2&#xff1a;ungrib程序3&#xff1a;metgrid WPS运行&#xff08;Running the WPS&#xff09;步骤1&#xff1a;Define model domains with geogrid步骤2&#xff1a;Extract…

开源轮子 - Logback 和 Slf4j

spring boot内置&#xff1a;Logback 文章目录 spring boot内置&#xff1a;Logback一&#xff1a;Logback强在哪&#xff1f;二&#xff1a;简单使用三&#xff1a;把 log4j 转成 logback四&#xff1a;日志门面SLF4J1&#xff1a;什么是SLF4J2&#xff1a;SLF4J 解决了什么痛…

Linux下部署MySQL8.0集群 - 主从复制(一主两从)

目录 一、部署前准备 1、查看系统信息 # 查看系统版本 cat /etc/red* # 查看系统位数 getconf LONG_BIT[rootlocalhost ~]# cat /etc/red* CentOS Linux release 7.5.1804 (Core) [rootlocalhost ~]# getconf LONG_BIT 642、下载对应安装包 进入MySQL官网&#xff1a;https:…

springboot中的AOP以及面向切面编程思想

快速入门体验AOP aop中相关概念 实现导入依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> 新建aop文件夹,里面声明XXXAspect类 @Aspect // 声…