CloudCompare二次开发之如何通过PCL进行点云采样?

news2024/10/6 10:43:21

文章目录

  • 0.引言
  • 1.CloudCompare界面设计采样(sample)按钮
  • 2.RandomSample随机下采样
  • 3.VoxelGrid体素下采样
  • 4.UniformSampling均匀采样
  • 5. MovingLeastSquares增采样
  • 6.SamplingSurfaceNormal非均匀体素采样

0.引言

  因笔者课题涉及点云处理,需要通过PCL进行点云数据一系列处理分析,查阅现有网络资料,对常用PCL点云采样进行代码实现,本文记录采样实现过程。

1.CloudCompare界面设计采样(sample)按钮

  (1)设计.ui文件
  ①设计按钮
  在这里插入图片描述

  ②编译.ui
  在这里插入图片描述

  (2)修改mainwindow.h文件
  在这里插入图片描述

//点云采样
void doActionPCLRandomSample(); // 随机下采样  
void doActionPCLVoxelGrid(); // 体素下采样  
void doActionPCLUniformSampling(); // 均匀采样  
void doActionPCLMovingLeastSquares(); // 增采样  
void doActionPCLSamplingSurfaceNormal(); // 非均匀体素采样

  (3)修改mainwindow.cpp文件
  ①添加头文件
  在这里插入图片描述

#include <pcl/filters/random_sample.h>// 随机下采样
#include <pcl/filters/voxel_grid.h>// 体素下采样  
#include <pcl/keypoints/uniform_sampling.h>// 均匀采样  
#include <pcl/surface/mls.h>// 增采样  
#include <pcl/filters/sampling_surface_normal.h>//非均匀体素采样

  ②添加实现代码
  在这里插入图片描述

//随机下采样
void MainWindow::doActionPCLRandomSample()  
{  
}  
//体素下采样  
void MainWindow::doActionPCLVoxelGrid()  
{  
}  
// 均匀采样  
void MainWindow::doActionPCLUniformSampling()  
{  
}  
//增采样  
void MainWindow::doActionPCLMovingLeastSquares()  
{  
}  
//非均匀体素采样  
void MainWindow::doActionPCLSamplingSurfaceNormal()  
{  
}

  ③添加信号槽函数
  在这里插入图片描述

connect(m_UI->actionRandomSample, &amp;QAction::triggered, this, &amp;MainWindow::doActionPCLRandomSample);//随机下采样
connect(m_UI->actionVoxelGrid_2, &amp;QAction::triggered, this, &amp;MainWindow::doActionPCLVoxelGrid);//体素下采样  
connect(m_UI->actionUniformSampling_2, &amp;QAction::triggered, this, &amp;MainWindow::doActionPCLUniformSampling);//均匀采样  
connect(m_UI->actionMovingLeastSquares, &amp;QAction::triggered, this, &amp;MainWindow::doActionPCLMovingLeastSquares);//增采样  
connect(m_UI->actionSamplingSurfaceNormal, &amp;QAction::triggered, this, &amp;MainWindow::doActionPCLSamplingSurfaceNormal);//非均匀体素采样

  (4)生成
  在这里插入图片描述

2.RandomSample随机下采样

  (1)实现代码

//随机下采样
void MainWindow::doActionPCLRandomSample()  
{  
    if (getSelectedEntities().size() != 1)  
    {  
        ccLog::Print(QStringLiteral("只能选择一个点云实体"));  
    return;  
    }  
    ccHObject* entity = getSelectedEntities()[0];  
    ccPointCloud* ccCloud = ccHObjectCaster::ToPointCloud(entity);  
    // ---------------------------读取数据到PCL----------------------------------  
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);  
    cloud->resize(ccCloud->size());  
    for (int i = 0; i < cloud->size(); ++i)  
    {  
        const CCVector3* point = ccCloud->getPoint(i);  
        cloud->points[i].x = point->x;  
        cloud->points[i].y = point->y;  
        cloud->points[i].z = point->z;  
    }  
    // -----------------------------对话框---------------------------------------  
    float radius = QInputDialog::getDouble(this, QStringLiteral("参数设置"), QStringLiteral("采样比例: "), 50, 0, 100, 4);  
    // ----------------------------随机下采样--------------------------------------  
    pcl::PointCloud<pcl::PointXYZ>::Ptr filtered(new pcl::PointCloud<pcl::PointXYZ>);  
    pcl::RandomSample<pcl::PointXYZ> us;  
    us.setInputCloud(cloud);  
    us.setSample(cloud->size()*radius/100.0);  
    us.filter(*filtered);  
    // ------------------------PCL->CloudCompare--------------------------------  
    if (!filtered->empty())  
    {  
        ccPointCloud* newPointCloud = new ccPointCloud(QString("RandomSample"));  
        for (int i = 0; i < filtered->size(); ++i)  
        {  
            double x = filtered->points[i].x;  
            double y = filtered->points[i].y;  
            double z = filtered->points[i].z;  
            newPointCloud->addPoint(CCVector3(x, y, z));  
        }  
        newPointCloud->setRGBColor(ccColor::Rgba(255, 255, 255, 255));  
        newPointCloud->showColors(true);  
        if (ccCloud->getParent())  
        {  
            ccCloud->getParent()->addChild(newPointCloud);  
        }  
        ccCloud->setEnabled(false);  
        addToDB(newPointCloud);  
        refreshAll();  
        updateUI();  
    }  
    else  
    {  
        ccCloud->setEnabled(true);  
        // Display a warning message in the console  
        dispToConsole("Warning: example shouldn't be used as is", ccMainAppInterface::WRN_CONSOLE_MESSAGE);  
    }  
}

  (2)采样结果
  ①采样前
  在这里插入图片描述

  ②采样后
  在这里插入图片描述

3.VoxelGrid体素下采样

  (1)实现代码

// 体素滤波器
void MainWindow::doActionPCLVoxelGrid()  
{  
    if (getSelectedEntities().size() != 1)  
    {  
        ccLog::Print(QStringLiteral("只能选择一个点云实体"));  
    return;  
    }  
    ccHObject* entity = getSelectedEntities()[0];  
    ccPointCloud* ccCloud = ccHObjectCaster::ToPointCloud(entity);  
    // ---------------------------读取数据到PCL----------------------------------  
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);  
    cloud->resize(ccCloud->size());  
    for (int i = 0; i < cloud->size(); ++i)  
    {  
        const CCVector3* point = ccCloud->getPoint(i);  
        cloud->points[i].x = point->x;  
        cloud->points[i].y = point->y;  
        cloud->points[i].z = point->z;  
    }  
    // -----------------------------对话框---------------------------------------  
    float radius = QInputDialog::getDouble(this, QStringLiteral("参数设置"), QStringLiteral("体素大小: "), 0.1, 0, 100, 4);  
    // ----------------------------体素下采样-------------------------------------  
    pcl::PointCloud<pcl::PointXYZ>::Ptr filtered(new pcl::PointCloud<pcl::PointXYZ>);  
    pcl::VoxelGrid<pcl::PointXYZ> us;  
    us.setInputCloud(cloud);  
    us.setLeafSize(radius, radius, radius);  
    us.filter(*filtered);  
    // ------------------------PCL->CloudCompare--------------------------------  
    if (!filtered->empty())  
    {  
        ccPointCloud* newPointCloud = new ccPointCloud(QString("VoxelGrid"));  
        for (int i = 0; i < filtered->size(); ++i)  
        {  
            double x = filtered->points[i].x;  
            double y = filtered->points[i].y;  
            double z = filtered->points[i].z;  
            newPointCloud->addPoint(CCVector3(x, y, z));  
        }  
        newPointCloud->setRGBColor(ccColor::Rgba(255, 255, 255, 255));  
        newPointCloud->showColors(true);  
        if (ccCloud->getParent())  
        {  
            ccCloud->getParent()->addChild(newPointCloud);  
        }  
        ccCloud->setEnabled(false);  
        addToDB(newPointCloud);  
        refreshAll();  
        updateUI();  
    }  
    else  
    {  
        ccCloud->setEnabled(true);  
        // Display a warning message in the console  
        dispToConsole("Warning: example shouldn't be used as is", ccMainAppInterface::WRN_CONSOLE_MESSAGE);  
    }  
}

  (2)采样结果
  ①采样前
  在这里插入图片描述

  ②采样后
  在这里插入图片描述

4.UniformSampling均匀采样

  (1)实现代码

// 均匀采样
void MainWindow::doActionPCLUniformSampling()  
{  
    if (getSelectedEntities().size() != 1)  
    {  
        ccLog::Print(QStringLiteral("只能选择一个点云实体"));  
    return;  
    }  
    ccHObject* entity = getSelectedEntities()[0];  
    ccPointCloud* ccCloud = ccHObjectCaster::ToPointCloud(entity);  
    // ---------------------------读取数据到PCL----------------------------------  
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);  
    cloud->resize(ccCloud->size());  
    for (int i = 0; i < cloud->size(); ++i)  
    {  
        const CCVector3* point = ccCloud->getPoint(i);  
        cloud->points[i].x = point->x;  
        cloud->points[i].y = point->y;  
        cloud->points[i].z = point->z;  
    }  
    // -----------------------------对话框---------------------------------------  
    float radius = QInputDialog::getDouble(this, QStringLiteral("参数设置"), QStringLiteral("搜索半径: "), 0.1, 0, 100, 4);  
    // ----------------------------均匀采样--------------------------------------  
    pcl::PointCloud<pcl::PointXYZ>::Ptr filtered(new pcl::PointCloud<pcl::PointXYZ>);  
    pcl::UniformSampling<pcl::PointXYZ> us;  
    us.setInputCloud(cloud);  
    us.setRadiusSearch(radius);  
    us.filter(*filtered);  
    // ------------------------PCL->CloudCompare--------------------------------  
    if (!filtered->empty())  
    {  
        ccPointCloud* newPointCloud = new ccPointCloud(QString("UniformSampling"));  
        for (int i = 0; i < filtered->size(); ++i)  
        {  
            double x = filtered->points[i].x;  
            double y = filtered->points[i].y;  
            double z = filtered->points[i].z;  
            newPointCloud->addPoint(CCVector3(x, y, z));  
        }  
        newPointCloud->setRGBColor(ccColor::Rgba(255, 255, 255, 255));  
        newPointCloud->showColors(true);  
        if (ccCloud->getParent())  
        {  
            ccCloud->getParent()->addChild(newPointCloud);  
        }  
        ccCloud->setEnabled(false);  
        addToDB(newPointCloud);  
        refreshAll();  
        updateUI();  
    }  
    else  
    {  
        ccCloud->setEnabled(true);  
        // Display a warning message in the console  
        dispToConsole("Warning: example shouldn't be used as is", ccMainAppInterface::WRN_CONSOLE_MESSAGE);  
    }  
}

  (2)采样结果
  ①采样前
  在这里插入图片描述

  ②采样后
  在这里插入图片描述

5. MovingLeastSquares增采样

  (1)实现代码

//增采样
void MainWindow::doActionPCLMovingLeastSquares()  
{  
    if (getSelectedEntities().size() != 1)  
    {  
        ccLog::Print(QStringLiteral("只能选择一个点云实体"));  
    return;  
    }  
    ccHObject* entity = getSelectedEntities()[0];  
    ccPointCloud* ccCloud = ccHObjectCaster::ToPointCloud(entity);  
    // ---------------------------读取数据到PCL----------------------------------  
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);  
    cloud->resize(ccCloud->size());  
    for (int i = 0; i < cloud->size(); ++i)  
    {  
        const CCVector3* point = ccCloud->getPoint(i);  
        cloud->points[i].x = point->x;  
        cloud->points[i].y = point->y;  
        cloud->points[i].z = point->z;  
    }  
    // -----------------------------对话框---------------------------------------  
    float radius = QInputDialog::getDouble(this, QStringLiteral("参数设置"), QStringLiteral("搜索邻域的半径: "), 0.03, 0, 100, 4);  
    // ----------------------------增采样--------------------------------------  
    pcl::PointCloud<pcl::PointXYZ>::Ptr filtered(new pcl::PointCloud<pcl::PointXYZ>);  
    pcl::MovingLeastSquares<pcl::PointXYZ, pcl::PointXYZ>  us;  
    us.setInputCloud(cloud);  
    pcl::search::KdTree<pcl::PointXYZ>::Ptr kdtree;  //定义搜索方法  
    us.setSearchMethod(kdtree);   //设置搜索方法  
    us.setSearchRadius(radius);   //设置搜索邻域的半径  
    us.setUpsamplingMethod(pcl::MovingLeastSquares<pcl::PointXYZ, pcl::PointXYZ>::SAMPLE_LOCAL_PLANE);   //对点云进行上采样  
    us.setUpsamplingRadius(0.03);   //设置采样半径大小,3cm  
    us.setUpsamplingStepSize(0.02);  //设置采样步长大小,2cm  
    us.process(*filtered);  
    // ------------------------PCL->CloudCompare--------------------------------  
    if (!filtered->empty())  
    {  
        ccPointCloud* newPointCloud = new ccPointCloud(QString("MovingLeastSquares"));  
        for (int i = 0; i < filtered->size(); ++i)  
        {  
            double x = filtered->points[i].x;  
            double y = filtered->points[i].y;  
            double z = filtered->points[i].z;  
            newPointCloud->addPoint(CCVector3(x, y, z));  
        }  
        newPointCloud->setRGBColor(ccColor::Rgba(255, 255, 255, 255));  
        newPointCloud->showColors(true);  
        if (ccCloud->getParent())  
        {  
            ccCloud->getParent()->addChild(newPointCloud);  
        }  
        ccCloud->setEnabled(false);  
        addToDB(newPointCloud);  
        refreshAll();  
        updateUI();  
    }  
    else  
    {  
        ccCloud->setEnabled(true);  
        // Display a warning message in the console  
        dispToConsole("Warning: example shouldn't be used as is", ccMainAppInterface::WRN_CONSOLE_MESSAGE);  
    }  
}

  (2)采样结果
  ①采样前
  在这里插入图片描述

  ②采样后
  在这里插入图片描述

6.SamplingSurfaceNormal非均匀体素采样

  (1)实现代码

//非均匀体素采样
void MainWindow::doActionPCLSamplingSurfaceNormal()  
{  
    if (getSelectedEntities().size() != 1)  
    {  
        ccLog::Print(QStringLiteral("只能选择一个点云实体"));  
    return;  
    }  
    ccHObject* entity = getSelectedEntities()[0];  
    ccPointCloud* ccCloud = ccHObjectCaster::ToPointCloud(entity);  
    // ---------------------------读取数据到PCL----------------------------------  
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);  
    cloud->resize(ccCloud->size());  
    pcl::PointCloud<pcl::PointNormal>::Ptr incloud(new pcl::PointCloud <pcl::PointNormal>());  
    for (int i = 0; i < cloud->size(); ++i)  
    {  
        const CCVector3* point = ccCloud->getPoint(i);  
        cloud->points[i].x = point->x;  
        cloud->points[i].y = point->y;  
        cloud->points[i].z = point->z;  
    pcl::PointNormal pt;  
    pt.x = point->x;  
    pt.y = point->y;  
    pt.z = point->z;  
    incloud->points.push_back(pt);  
    }  
    // -----------------------------对话框---------------------------------------  
    float radius = QInputDialog::getDouble(this, QStringLiteral("参数设置"), QStringLiteral("采样比例: "),0.3, 0, 100, 4);  
    incloud->width = 1;  
    incloud->height = uint32_t(incloud->points.size());  
    // ----------------------------随机下采样--------------------------------------  
    pcl::PointCloud<pcl::PointNormal>::Ptr filtered(new pcl::PointCloud<pcl::PointNormal>);  
    pcl::SamplingSurfaceNormal<pcl::PointNormal> us;  
    us.setInputCloud(incloud);  
    us.setRatio(radius);  
    us.filter(*filtered);  
    // ------------------------PCL->CloudCompare--------------------------------  
    if (!filtered->empty())  
    {  
        ccPointCloud* newPointCloud = new ccPointCloud(QString("SamplingSurfaceNormal"));  
        for (int i = 0; i < filtered->size(); ++i)  
        {  
            double x = filtered->points[i].x;  
            double y = filtered->points[i].y;  
            double z = filtered->points[i].z;  
            newPointCloud->addPoint(CCVector3(x, y, z));  
        }  
        newPointCloud->setRGBColor(ccColor::Rgba(255, 255, 255, 255));  
        newPointCloud->showColors(true);  
        if (ccCloud->getParent())  
        {  
            ccCloud->getParent()->addChild(newPointCloud);  
        }  
        ccCloud->setEnabled(false);  
        addToDB(newPointCloud);  
        refreshAll();  
        updateUI();  
    }  
    else  
    {  
        ccCloud->setEnabled(true);  
        // Display a warning message in the console  
        dispToConsole("Warning: example shouldn't be used as is", ccMainAppInterface::WRN_CONSOLE_MESSAGE);  
    }  
}

  (2)采样结果
  ①采样前
  在这里插入图片描述

  ②采样后
  在这里插入图片描述

参考资料:
[1] 来吧!我在未来等你!. CloudCompare二次开发之如何配置PCL点云库?; 2023-05-15 [accessed 2023-05-16].
[2] 自动驾驶之心. 聊一聊点云PCL中常用的高级采样方法; 2023-01-17 [accessed 2023-05-16].
[3] 悠缘之空. PCL函数库摘要——采样一致性; 2021-11-07 [accessed 2023-05-16].
[4] 陈三章. PCL学习笔记——点云曲面重建(一); 2019-04-03 [accessed 2023-05-16].

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

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

相关文章

MySQL之数据目录

前言 本文章收录在MySQL性能优化原理实战专栏&#xff0c;点击此处查看更多优质内容。 本文摘录自 ▪ 小孩子4919《MySQL是怎样运行的&#xff1a;从根儿上理解MySQL》 我们知道像InnoDB、MyISAM这样的存储引擎都是把表存储在磁盘上的&#xff0c;而操作系统用来管理磁盘的那…

C. Classy Numbers(dfs构造 + 组合数学)

Problem - C - Codeforces 让我们称某个正整数为“优美的”&#xff0c;如果它的十进制表示中不超过3个数字不为零。例如&#xff0c;数字4、200000、10203是优美的&#xff0c;而数字4231、102306、7277420000则不是。 给定一个区间[L;R]&#xff0c;请计算在此区间内有多少个…

Linux awk流编辑器

awk流编辑器 工作原理 逐行读取文本&#xff0c;默认以空格或tab键为分隔符进行分隔&#xff0c;将分隔所得的各个字段保存到内建变量中&#xff0c;并按模式或者条件执行编辑命令。 sed命令常用于一整行的处理&#xff0c;而awk比较倾向于将一行分成多个“字段”然后再进行处理…

pix2pix

Image-to-Image Translation Using Conditional Adversarial Networks 1&#xff1a; pix2pix也是CGAN的一种&#xff0c;pix2pix可以学习输入到输出的映射&#xff0c;同时也学习了损害函数去训练这个映射。这是一个大一统的方法去实现从标签合成图像&#xff0c;从边界图重建…

【FMC139】多通道采集--基于 VITA57.1 标准的4 路500MSPS/1GSPS 14 位AD 采集子卡模块(AD9680/HMC7044)

板卡概述 FMC139 是一款基于VITA57.1 标准规范的JESD204B 接口FMC 子卡模块&#xff0c;该模块可以实现4 路14-bit、500MSPS/1GSPSADC采集功能。该板卡ADC 器件采用ADI 公司的AD9680 芯片,全功率-3dB 模拟输入带宽可达2GHz。该ADC 与FPGA 的主机接口通过8通道的高速串行GTX 收…

AutoSAR PNC和ComM

文章目录 PNC和ComMPNC管理NM PDU结构及PNC信息位置如何理解节点关联PNCPNC状态管理 ComM 通道状态管理 PNC和ComM PNC 和 ComM层的Channel不是一个概念&#xff0c;ComM的Channel对应具体的物理总线数。 在ComM模块中&#xff0c;一个Channel可以对应一个PNC&#xff0c;也可…

AIGC产业研究报告2023——语言生成篇

易观&#xff1a;今年以来&#xff0c;随着人工智能技术不断实现突破迭代&#xff0c;生成式AI的话题多次成为热门&#xff0c;而人工智能内容生成&#xff08;AIGC&#xff09;的产业发展、市场反应与相应监管要求也受到了广泛关注。为了更好地探寻其在各行业落地应用的可行性…

java字类与继承

文章目录 一、Java子类与父类二、Java子类的继承性三、Java子类与对象四、Java成员变量的隐藏和方法重写五、Java super关键字六、Java final关键字七、Java对象的上转型对象八、Java继承与多态九、Java abstract类和abstract方法总结 一、Java子类与父类 继承就是一种由已有的…

电脑无法安装软件?不用慌,这样做可以快速解决!

案例&#xff1a;为什么我的电脑不能下载软件&#xff1f; 【在学习的过程中&#xff0c;需要下载一些软件工具。按照老师给的软件步骤&#xff0c;电脑还是无法安装软件&#xff0c;有小伙伴知道怎么回事吗&#xff1f;】 在使用电脑的过程中&#xff0c;很多小伙伴都会遇到…

【C++】unordered_map和unordered_set的模拟实现

一、改造HashTable 实现了哈希表&#xff08;开散列&#xff09;&#xff0c;再将其封装为unordered_map和unordered_set。 HashTable的改造与RBTree的改造大致相同&#xff1a; 改造节点 template<class T> struct HashNode {//std::pair<K, V> _kv;//HashNod…

【AI思维空间】ChatGPT纵横编程世界,点亮智慧火花 | 京东云技术团队

作者&#xff1a;京东零售 王英杰 概述 该文档记录云交易开发小伙伴儿们在开发过程中的实际应用案例&#xff0c;记录典型案例&#xff0c;以解决开发过程中的实际问题为主&#xff0c;涵盖设计方案、编码、测试、集成、部署等等。 目的&#xff1a;贡献最佳实践&#xff0c;…

案例6:Java社区志愿者服务系统设计与实现开题报告

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

全面升级:知否AI问答场景导航功能震撼登场

今日&#xff0c;知否AI问答平台推出全新的场景功能&#xff0c;为用户提供更全面、高效的智能问答服务&#xff0c;再也不用担心找不到适合自己的场景入口了。 此次升级涵盖了50多个场景&#xff0c;包括论文助手、公司文案、营销文案、多语言翻译、行政公文、科研课题、招投…

bat脚本、dos命令

bat脚本 bat脚本就是DOS批处理脚本&#xff0c;就是将一系列DOS命令按照一定顺序排列而形成的集合&#xff0c;运行在windows命令行环境上。这个文件的每一行都是一条DOS命令 在命令提示下键入批处理文件的名称&#xff0c;或者双击该批处理文件&#xff0c;系统就会调用Cmd.…

服务器信息收集

#Version&#xff1a;1.2 #Modify Date&#xff1a;2013-05-21 #说明&#xff1a; #该脚本可以获取计算机名,域名,IP地址,操作系统版本,CPU名称单颗CPU内核数量*CPU个数,内存大小(GB),单块磁盘大小,计算机序列号,制造商,计算机型号 #该脚本先将计算机信息输出到txt文件中&…

浅谈Gradle构建工具

一、序言 常见的项目构建工具有Ant、Maven、Gradle&#xff0c;以往项目常见采用Maven进构建&#xff0c;但随着技术的发展&#xff0c;越来越多的项目采用Gradle进行构建&#xff0c;例如 Spring-boot。Gradle站在了Ant和Maven构建工具的肩膀上&#xff0c;使用强大的表达式语…

千万不要乱操作了!医院机房这么做真高级

各类中心数据机房广泛分布于银行、库房、交通、电信、医院、教育等行业。系统故障和人为操作不当可能导致各种业务中断或数据丢失&#xff0c;进而影响企业业务的停滞和运行。 医院管理3大难题和挑战 01.缺乏预警、告警机制 医院在使用自动化监控系统之前&#xff0c;主要靠人…

springboot足球赛事安排球队管理系统

系统主要有球队赛程安排&#xff0c;包括比赛数据&#xff0c;球员信息&#xff0c;球员实时数据&#xff0c;球队纪念品售卖 Spring Boot 是 Spring 家族中的一个全新的框架&#xff0c;它用来简化Spring应用程序的创建和开发过程。也可以说 Spring Boot 能简化我们之前采用SS…

09——path的使用

一、path 是 svg 中最强大的图形 用于定义一个 路径所有命令均允许小写字母。大写 表示绝对定位&#xff0c;小写 表示 相对定位 &#xff08;相对于上一个结束的坐标&#xff09;d 属性中包含所有路径的点&#xff0c;可根据命令缩写 自由组合 命令 名称 …

Windows 11 反转鼠标和触摸板滚动方向

如果在使用 Windows 10 设备时不喜欢鼠标或触摸板的「下滚上移&#xff0c;上滚下移」方式&#xff0c;可以通过调整「Windows 设备」或更改注册表 2 种方式来反转滚动方向。 下面就为大家介绍详细步骤。 Windows 11反转触摸板滚动方向 要通过调整「Windows 设置」反转触摸板…