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

news2024/12/22 8:44:12

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;
       //设置搜索的空间,点云数据cloud
       kdtree.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和v2
       int 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和指定可视化窗口v1
       pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ>   cloud1_color(cloud, 255, 255, 255);
       viewer.addPointCloud(cloud, cloud1_color, "cloud1", v1);
       
       //设置cloud2的渲染颜色,点云的ID和指定可视化窗口v2
       pcl::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.coloradmin.cn/o/2263669.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Leecode刷题C语言之根据第k场考试的分数排序

执行结果:通过 执行用时和内存消耗如下&#xff1a; int gk 0;int compare(const void* a, const void* b) {int* ua *(int**)a;int* ub *(int**)b;return ub[gk] - ua[gk]; }int** sortTheStudents(int** score, int scoreSize, int* scoreColSize, int k, int* returnSiz…

由popover框一起的操作demo问题

场景&#xff1a; 当popover框弹出的时候&#xff0c;又有MessageBox 提示&#xff0c;此时关闭MessageBox 提示&#xff0c;popover就关闭了。将popover改为手动激活&#xff0c;可以解决这个问题&#xff0c;但是会引起另外一个问题&#xff0c;之前&#xff08;click触发的时…

QT修改运行窗口的图标

首先&#xff0c;在.pro下添加两行&#xff1a; Debug:DESTDIR $$PWD Release:DESTDIR $$PWD 指定目标文件的路径 指定生成的debug和release文件夹路径在当前项目下 上面是为了防止爆奇怪的错 右键项目添加新文件 选择QT-》QT Resource File 起个名&#xff0c;然后下一步…

降低Mobx技术债问题-React前端数据流方案调研整理

我们现在主要是使用Mobx&#xff0c;但是Mobx的易于上手和灵活度也带来了很多预期以外的问题&#xff0c;随着项目的增长我们的代码技术债变得愈加沉重&#xff0c;不同的模块杂糅一起、单一store无限膨胀。 为此我们的调研是希望能找到一个更好的state配置、数据流的约定方案。…

sql server索引优化语句

第一步 建一个测试表 --create table TestUsers --( -- Id int primary key identity(1,1), -- Username varchar(30) not null, -- Password varchar(10) not null, -- CreateDateTime datetime not null --)第二步 插入100w数据 大概1分钟执行时间 ----插入数据…

aioice里面candidate固定UDP端口测试

环境&#xff1a; aioice0.9.0 问题描述&#xff1a; aioice里面candidate固定UDP端口测试 解决方案&#xff1a; /miniconda3/envs/nerfstream/lib/python3.10/site-packages/aioice import hashlib import ipaddress import random from typing import Optional import…

Java(二十五)final关键字

Java中的final关键字在编写程序中,比较常用。尤其是在上文中的匿名内部类中。 final 表示最终,也可以称为完结器,表示对象是最终形态的,不可改变的意思。 使用final修饰的的类,是“断子绝孙”的。 一:final修饰成员变量 Final修饰的类的成员变量是常量,不可被改变。 …

MySQL三大日志-Redo Log

Redo Log简介 事务中修改的任何数据&#xff0c;将最新的数据备份存储的位置&#xff08;Redo Log&#xff09;&#xff0c;被称为重做日志。 Redo Log 的生成和释放 随着事务操作的执行&#xff0c;就会生成Redo Log&#xff0c;在事务提交时会将产生Redo Log写入Log Buff…

【libuv】Fargo信令2:【深入】client为什么收不到服务端响应的ack消息

客户端处理server的ack回复,判断链接连接建立 【Fargo】28:字节序列【libuv】Fargo信令1:client发connect消息给到server客户端启动后理解监听read消息 但是,这个代码似乎没有触发ack消息的接收: // 客户端初始化 void start_client(uv_loop_t

html中实用标签dl dt dd(有些小众的标签 但是很好用)

背景描述 html <dl> <dt> <dd>是一组合标签&#xff0c;他们与ol li、ul li标签很相似 但是他却是没有默认前缀并且有缩进的标签 使用方式与table表格的标签一致 使用方式 dt和dd是放于dl标签内&#xff0c;dt与dd处于dl下相同级。就是dt不能放入dd内&am…

Mysql索引类型总结

按照数据结构维度划分&#xff1a; BTree 索引&#xff1a;MySQL 里默认和最常用的索引类型。只有叶子节点存储 value&#xff0c;非叶子节点只有指针和 key。存储引擎 MyISAM 和 InnoDB 实现 BTree 索引都是使用 BTree&#xff0c;但二者实现方式不一样&#xff08;前面已经介…

kubeadm_k8s_v1.31高可用部署教程

kubeadm_k8s_v1.31高可用部署教程 实验环境部署拓扑图**部署署架构****Load Balance****Control plane node****Worker node****资源分配&#xff08;8台虚拟机&#xff09;**集群列表 前置准备关闭swap开启ipv4转发更多设置 1、Verify the MAC address and product_uuid are u…

M3D: 基于多模态大模型的新型3D医学影像分析框架,将3D医学图像分析从“看图片“提升到“理解空间“的层次,支持检索、报告生成、问答、定位和分割等8类任务

M3D: 基于多模态大模型的新型3D医学影像分析框架&#xff0c;将3D医学图像分析从“看图片“提升到“理解空间“的层次&#xff0c;支持检索、报告生成、问答、定位和分割等8类任务 论文大纲理解1. 确认目标2. 分析过程&#xff08;目标-手段分析&#xff09;核心问题拆解 3. 实…

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

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

深入浅出:内网黄金票据与白银票据

在域环境中&#xff0c;Kerberos认证是确保安全通信的基石&#xff0c;而黄金票据和白银票据则是攻击者常用的两种经典手段。为了帮助大家更形象地理解它们的工作原理及防御措施&#xff0c;我们不妨将其与在私人电影院购票的情景做类比。具体内容参考如下图示即可&#xff1a;…

Eclipse2024无法创建Dynamic Web project解决方法

Dynamic Web Project 是由 Eclipse Web Developer Tools 提供的&#xff0c;确保你已经安装了该插件。 在 Eclipse 中&#xff0c;点击菜单栏的 Help > Eclipse Marketplace&#xff0c;搜索 Eclipse Web Developer Tools&#xff0c;然后安装或更新它。 等待安装完成重启一…

Unity复刻胡闹厨房复盘 模块一 新输入系统订阅链与重绑定

本文仅作学习交流&#xff0c;不做任何商业用途 郑重感谢siki老师的汉化教程与代码猴的免费教程以及搬运烤肉的小伙伴 版本&#xff1a;Unity6 模板&#xff1a;3D 核心 渲染管线&#xff1a;URP ------------------------------…

Edge Scdn防御网站怎么样?

酷盾安全Edge Scdn&#xff0c;即边缘式高防御内容分发网络&#xff0c;主要是通过分布在不同地理位置的多个节点&#xff0c;使用户能够更快地访问网站内容。同时&#xff0c;Edge Scdn通过先进的技术手段&#xff0c;提高了网上内容传输的安全性&#xff0c;防止各种网络攻击…

开源数字人系统源码短视频文案提取文案改写去水印小程序

应用场景 短视频去水印&#xff1a; 个人用户&#xff1a;在社交媒体上分享短视频时&#xff0c;去除原视频中的水印&#xff0c;以保护个人隐私或避免侵权问题。企业用户&#xff1a;在广告、宣传和营销活动中&#xff0c;使用无水印的短视频以提高品牌知名度和吸引力。 文案提…

Everything实现,快速搜索文件

最近编写NTFS文件实时搜索工具, 类似 Everything 这样, 翻阅了很多博客, 结果大致如下: 1.分析比较肤浅, 采用USN日志枚举来获取文件记录 速度一言难尽, 因为日志枚举的是全盘所有文件的所有日志, 记录比文件记录还多, 速度当然很慢, 还有的甚至于是 使用 DeviceIoControl 函数…