【PCL】—— 点云滤波

news2024/11/26 20:27:39

文章目录

  • 直通滤波
  • 降采样
  • 使用统计滤波(statisticalOutlierRemoval)移除离群点
  • 使用条件滤波(ConditionalRemoval)或 半径滤波(RadiusOutlinerRemoval)移除离群点

在获取点云数据时,由于设备精度,操作者经验环境因素带来的影响,以及电磁波的衍射特性,被测物体表面性质变化和数据拼接配准操作过程的影响,点云数据中将不可避免的出现一些噪声。

几种需要进行点云滤波处理情况如下:

  • 点云数据密度不规则需要平滑;
  • 因为遮挡等问题造成离群点需要去除;
  • 大量数据需要下采样;
  • 噪声数据需要去除。

PCL常规滤波手段均进行了很好的封装,对点云的滤波通过调用各个滤波器对象来完成。主要的滤波器有直通滤波器体素格滤波器统计滤波器半径滤波器等。

常用方法如下:

  • 使用直通滤波器对点云进行滤波处理
  • 使用体素滤波对点云进行下采样
  • 使用统计滤波器移除离群点
  • 使用条件滤波或半径滤波移除离群点

直通滤波

直通滤波器就是根据点云的属性(属性比如x,y,z,颜色值等),在点的属性上设置范围,对点进行滤波,保留范围内的或保留范围外的。

官网教程——https://pcl.readthedocs.io/projects/tutorials/en/latest/passthrough.html#passthrough
测试案例1(保留z轴范围内0-1m内的点云)

#include <iostream>
#include <pcl/point_types.h>
#include <pcl/filters/passthrough.h>
#include <pcl/visualization/cloud_viewer.h>

typedef pcl::PointXYZ PointT;

int
main(int argc, char **argv) {
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>);

    //写入点云
    cloud->width = 5;
    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 * rand() / (RAND_MAX + 1.0f);
        cloud->points[i].y = 1024 * rand() / (RAND_MAX + 1.0f);
        cloud->points[i].z = 1024 * rand() / (RAND_MAX + 1.0f);
    }

    std::cerr << "Cloud before filtering: " << std::endl;
    for (size_t i = 0; i < cloud->points.size(); ++i)
        std::cerr << "    " << cloud->points[i].x << " "
                  << cloud->points[i].y << " "
                  << cloud->points[i].z << std::endl;

    // Create the filtering object
    pcl::PassThrough<pcl::PointXYZ> pass;
    pass.setInputCloud(cloud);          // 1. 设置输入源
    pass.setFilterFieldName("z");       // 2. 设置过滤域名
    pass.setFilterLimits(0.0, 1.0);     // 3. 设置过滤范围
//    pass.setFilterLimitsNegative(true); // 设置获取Limits之外的内容
    pass.filter(*cloud_filtered);       // 4. 执行过滤,并将结果输出到cloud_filtered

    std::cerr << "Cloud after filtering: " << std::endl;
    for (size_t i = 0; i < cloud_filtered->points.size(); ++i)
        std::cerr << "    " << cloud_filtered->points[i].x << " "
                  << cloud_filtered->points[i].y << " "
                  << cloud_filtered->points[i].z << std::endl;

    pcl::visualization::CloudViewer viewer("Cloud Viewer");

    //这里会一直阻塞直到点云被渲染
    viewer.showCloud(cloud);
    while (!viewer.wasStopped()) {
    }
    return (0);
}

执行程序之后,会有如下结果

Cloud before filtering:
    0.352222 -0.151883 -0.106395
    -0.397406 -0.473106 0.292602
    -0.731898 0.667105 0.441304
    -0.734766 0.854581 -0.0361733
    -0.4607 -0.277468 -0.916762
Cloud after filtering:
    -0.397406 -0.473106 0.292602
    -0.731898 0.667105 0.441304

过滤过程的图形显示如下所示,其中坐标系中红色为(x)、绿色为(y)、蓝色为(z)。图中的五个点中绿色的点为被过滤后的点,红色的点为被过滤掉的点。
在这里插入图片描述

测试案例2

#include <iostream>
#include <pcl/point_types.h>
#include <pcl/io/io.h>
#include <pcl/io/pcd_io.h>
#include <pcl/filters/passthrough.h>
#include <pcl/visualization/cloud_viewer.h>

int
main(int argc, char **argv) {
    pcl::PointCloud<pcl::PointXYZI>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZI>);
    pcl::PointCloud<pcl::PointXYZI>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZI>);

    // 加载pcd文件到cloud
    if (pcl::io::loadPCDFile("../data/result.pcd", *cloud) == -1)
    {
        std::cout << "Could not load pcd file!" << std::endl;
        return -1;
    }

    // Create the filtering object
    pcl::PassThrough<pcl::PointXYZI> pass;
    pass.setInputCloud(cloud);          // 1. 设置输入源
    pass.setFilterFieldName("z");       // 2. 设置过滤域名
    pass.setFilterLimits(-1.0, 1.0);     // 3. 设置过滤范围
    // pass.setFilterLimitsNegative(true); // 设置获取Limits之外的内容
    pass.filter(*cloud_filtered);       // 4. 执行过滤,并将结果输出到cloud_filtered

    pcl::visualization::PCLVisualizer viewer_filter("Cloud-Filtered Viewer");
    //背景颜色设置
    viewer_filter.setBackgroundColor(0, 0, 0);
    //按照z字段进行渲染
    pcl::visualization::PointCloudColorHandlerGenericField<pcl::PointXYZI> fildColor_filter(cloud_filtered, "intensity");
    //显示点云,其中fildColor为颜色显示
    viewer_filter.addPointCloud<pcl::PointXYZI>(cloud_filtered, fildColor_filter, "sample");
    //设置点云大小
    viewer_filter.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "sample");
    // // 循环判断是否退出
    // while (!viewer_filter.wasStopped()) {
    //     viewer_filter.spinOnce();
    // }

    pcl::visualization::PCLVisualizer viewer("Cloud Viewer");
    //背景颜色设置
    viewer.setBackgroundColor(0, 0, 0);
    //按照z字段进行渲染
    pcl::visualization::PointCloudColorHandlerGenericField<pcl::PointXYZI> fildColor(cloud, "intensity");
    //显示点云,其中fildColor为颜色显示
    viewer.addPointCloud<pcl::PointXYZI>(cloud, fildColor, "sample");
    //设置点云大小
    viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "sample");
    
    // 循环判断是否退出
    while (!viewer.wasStopped() && !viewer_filter.wasStopped()) {
        viewer_filter.spinOnce();
        viewer.spinOnce();
    }
    return 0;
}

测试效果

在这里插入图片描述

降采样

体素法滤波,即减少点的数量,减少点云数据,并同时保持点云的形状特征,在提高配准、曲面重建、形状识别等算法速度中非常实用。

PCL实现的VoxelGrid类通过输入的点云数据创建一个三维体素栅格(可把体素栅格想象为微小的空间三维立方体的集合),然后在每个体素(即三维立方体)内,用体素中所有点的重心来近似显示体素中其他点,这样该体素内所有点就用一个重心点最终表示,对于所有体素处理后得到过滤后的点云。

在这里插入图片描述

官方教程—— https://pcl-tutorials.readthedocs.io/en/latest/voxel_grid.html#voxelgrid

#include <iostream>
#include <pcl/io/io.h>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/visualization/cloud_viewer.h>

int main (int argc, char** argv)
{
  pcl::PCLPointCloud2::Ptr cloud (new pcl::PCLPointCloud2 ());
  pcl::PCLPointCloud2::Ptr cloud_filtered (new pcl::PCLPointCloud2 ());

  // Fill in the cloud data
  pcl::PCDReader reader; // 也可以用创建reader的方式来读PCD文件
  // Replace the path below with the path where you saved your file
  reader.read ("../data/result.pcd", *cloud); // Remember to download the file first!

  std::cerr << "PointCloud before filtering: " << cloud->width * cloud->height 
       << " data points (" << pcl::getFieldsList (*cloud) << ")." << std::endl;

  // Create the filtering object
  pcl::VoxelGrid<pcl::PCLPointCloud2> sor;
  sor.setInputCloud (cloud);
  sor.setLeafSize (0.5f, 0.5f, 0.5f);
  sor.filter (*cloud_filtered);

  std::cerr << "PointCloud after filtering: " << cloud_filtered->width * cloud_filtered->height 
       << " data points (" << pcl::getFieldsList (*cloud_filtered) << ")." << std::endl;

  pcl::PCDWriter writer;
  writer.write ("../data/result_downsampled.pcd", *cloud_filtered, 
         Eigen::Vector4f::Zero (), Eigen::Quaternionf::Identity (), false);

  return (0);
}
PointCloud before filtering: 98322 data points (x y z intensity).
PointCloud after filtering: 11733 data points (x y z intensity).

pcl_viewer查看效果,点云数目明显减少。

在这里插入图片描述

使用统计滤波(statisticalOutlierRemoval)移除离群点

激光扫描通常会产生密度不均匀的点云数据集,另外测量中的误差也会产生稀疏的离群点,局部点云特征运算(如采样点处法向量或曲率变化率)复杂,容易导致点云配准等后期处理失败。

常用解决思路:每个点的邻域进行一个统计分析,并修剪掉一些不符合一定标准的点。假设得到的结果是一个高斯分布,其形状是由均值和标准差决定,则平均距离在标准范围之外的点,可以被定义为离群点并可从数据中去除。

在这里插入图片描述
统计滤波移除离群点的步骤如下:

  1. 查找每一个点的所有邻域点
  2. 计算每个点到其邻域点的距离 d i j d_{ij} dij,其中 i = [ 1 , 2 , . . . , m ] i=[1,2,...,m] i=[1,2,...,m]表示共有 m m m个点, j = [ 1 , 2 , . . . , k ] j=[1,2,...,k] j=[1,2,...,k]表示共有 k k k个邻域点
  3. 根据高斯分布 d   N ( μ , σ ) d~N(\mu,\sigma) d N(μ,σ)模型化距离参数,计算所有点与邻域点的 μ \mu μ(距离的均值), σ \sigma σ(距离的标准差),如下: μ = 1 n k ∑ i = 1 m ∑ j = 1 k d i j \mu {\rm{ = }}\frac{{\rm{1}}}{{nk}}\sum\limits_{i = 1}^m {\sum\limits_{j = 1}^k {{d_{ij}}} } μ=nk1i=1mj=1kdij σ = 1 n k ∑ i = 1 m ∑ j = 1 k ( d i j − μ ) 2 \sigma {\rm{ = }}\sqrt {\frac{{\rm{1}}}{{nk}}\sum\limits_{i = 1}^m {\sum\limits_{j = 1}^k {{{({d_{ij}} - \mu )}^2}} } } σ=nk1i=1mj=1k(dijμ)2 在此步骤时,同时也把每个点与其邻域点的距离均值求出 ∑ j = 1 k d i j {\sum\limits_{j = 1}^k {{{{d_{ij}} }}} } j=1kdij
    遍历所有点,若其距离的均值大于高斯分布的指定置信度,则移除,例如: ∑ j = 1 k d i j > μ + 3 σ o r ∑ j = 1 k d i j < μ − 3 σ \sum\limits_{j = 1}^k {{d_{ij}}} > \mu + 3\sigma or\sum\limits_{j = 1}^k {{d_{ij}}} < \mu - 3\sigma j=1kdij>μ+3σorj=1kdij<μ3σ
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/filters/statistical_outlier_removal.h>

int main (int argc, char** argv)
{
    pcl::PointCloud<pcl::PointXYZI>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZI>);
    pcl::PointCloud<pcl::PointXYZI>::Ptr cloud_filtered (new pcl::PointCloud<pcl::PointXYZI>);

    // 从文件读取点云
    // Fill in the cloud data
    pcl::PCDReader reader;
    // Replace the path below with the path where you saved your file
    reader.read<pcl::PointXYZI> ("../data/result.pcd", *cloud);

    std::cerr << "Cloud before filtering: " << std::endl;
    std::cerr << *cloud << std::endl;

    // 创建过滤器,每个点分析计算时考虑的最近邻居个数为50个;
    // 设置标准差阈值为1,这意味着所有距离查询点的平均距离的标准偏差均大于1个标准偏差的所有点都将被标记为离群值并删除。
    // 计算输出并将其存储在cloud_filtered中

    // Create the filtering object
    pcl::StatisticalOutlierRemoval<pcl::PointXYZI> sor;
    sor.setInputCloud (cloud);
    // 设置平均距离估计的最近邻居的数量K
    sor.setMeanK (50);
    // 设置标准差阈值系数
    sor.setStddevMulThresh (1.0);
    // 执行过滤
    sor.filter (*cloud_filtered);

    std::cerr << "Cloud after filtering: " << std::endl;
    std::cerr << *cloud_filtered << std::endl;
    // 将留下来的点保存到后缀为_inliers.pcd的文件
    pcl::PCDWriter writer;
    writer.write<pcl::PointXYZI> ("../data/result_inliers.pcd", *cloud_filtered, false);

    // 使用个相同的过滤器,但是对输出结果取反,则得到那些被过滤掉的点,保存到_outliers.pcd文件
    sor.setNegative (true);
    sor.filter (*cloud_filtered);
    writer.write<pcl::PointXYZI> ("../data/result_outliers.pcd", *cloud_filtered, false);

    return 0;
}

执行程序,输出以下结果

Cloud before filtering: 
header: seq: 0 stamp: 0 frame_id: 

points[]: 98322
width: 98322
height: 1
is_dense: 1
sensor origin (xyz): [0, 0, 0] / orientation (xyzw): [0, 0, 0, 1]

Cloud after filtering: 
header: seq: 0 stamp: 0 frame_id: 

points[]: 90637
width: 90637
height: 1
is_dense: 1
sensor origin (xyz): [0, 0, 0] / orientation (xyzw): [0, 0, 0, 1]

用pcl_viwer查看
在这里插入图片描述

使用条件滤波(ConditionalRemoval)或 半径滤波(RadiusOutlinerRemoval)移除离群点

条件滤波器:通过设定滤波条件进行滤波,有点分段函数的味道,当点云在一定范围则留下,不在则舍弃。

半径滤波器:以某点为中心画一个圆计算落在该圆中点的数量,当数量大于给定值时,则保留该点,数量小于给定值则剔除该点。此算法运行速度快,依序迭代留下的点一定是最密集的,但是圆的半径和圆内点的数目都需要人工指定。

下图有助于可视化RadiusOutlierRemoval过滤器对象的作用。用户指定邻居的个数,要每个点必须在指定半径内具有指定个邻居才能保留在PointCloud中。例如,如果指定了1个邻居,则只会从PointCloud中删除黄点。如果指定了2个邻居,则黄色和绿色的点都将从PointCloud中删除。

在这里插入图片描述

#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/filters/radius_outlier_removal.h>
#include <pcl/filters/conditional_removal.h>
#include <pcl/visualization/pcl_visualizer.h>

void showPointClouds(const pcl::PointCloud<pcl::PointXYZI>::Ptr &cloud){
    pcl::visualization::PCLVisualizer viewer("Cloud Viewer");
    //背景颜色设置
    viewer.setBackgroundColor(0, 0, 0);
    //按照z字段进行渲染
    pcl::visualization::PointCloudColorHandlerGenericField<pcl::PointXYZI> fildColor(cloud, "intensity");
    //显示点云,其中fildColor为颜色显示
    viewer.addPointCloud<pcl::PointXYZI>(cloud, fildColor, "sample");
    //设置点云大小
    viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "sample");

    while (!viewer.wasStopped())
    {
        viewer.spinOnce();
    }
    
}

int main(int argc, char **argv) {
    if (argc != 2)
    {
        //选择-r为半径滤波;选择-c为条件滤波
        std::cerr << "please specify command line arg '-r' or '-c'" << std::endl;
        exit(0);
    }
    pcl::PointCloud<pcl::PointXYZI>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZI>);
    pcl::PointCloud<pcl::PointXYZI>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZI>);

    // 从文件读取点云
    // Fill in the cloud data
    pcl::PCDReader reader;
    // Replace the path below with the path where you saved your file
    reader.read<pcl::PointXYZI> ("../data/result.pcd", *cloud);

    if (strcmp(argv[1], "-r") == 0) 
    {
        //半径滤波
        pcl::RadiusOutlierRemoval<pcl::PointXYZI> outrem;
        // build the filter
        outrem.setInputCloud(cloud);
        outrem.setRadiusSearch(0.4); //设置半径滤波时圆的半径
        outrem.setMinNeighborsInRadius(2); //设置圆内的点数
        // apply filter
        outrem.filter(*cloud_filtered);

        //保存相应pcd文件,以方便后续查看
        pcl::PCDWriter writer;
        writer.write<pcl::PointXYZI>("../data/result_remove_outliers_r.pcd", *cloud_filtered, false);
    } 
    else if (strcmp(argv[1], "-c") == 0) 
    {
        //条件滤波
        // build the condition
        // 过滤条件:z轴方向上,大于0.0,小于8.0
        pcl::ConditionAnd<pcl::PointXYZI>::Ptr range_cond(new pcl::ConditionAnd<pcl::PointXYZI>());
        range_cond->addComparison(pcl::FieldComparison<pcl::PointXYZI>::ConstPtr(
                new pcl::FieldComparison<pcl::PointXYZI>("z", pcl::ComparisonOps::GT, 0.0)));
        range_cond->addComparison(pcl::FieldComparison<pcl::PointXYZI>::ConstPtr(
                new pcl::FieldComparison<pcl::PointXYZI>("z", pcl::ComparisonOps::LT, 0.8)));

        // build the filter
        pcl::ConditionalRemoval<pcl::PointXYZI> condrem;
        condrem.setCondition(range_cond);
        condrem.setInputCloud(cloud);
        condrem.setKeepOrganized(false);
        // apply filter
        condrem.filter(*cloud_filtered);

        //保存相应pcd文件,以方便后续查看
        pcl::PCDWriter writer;
        writer.write<pcl::PointXYZI>("../data/result_remove_outliers_c.pcd", *cloud_filtered, false);
    } 
    else 
    {
        std::cerr << "please specify command line arg '-r' or '-c'" << std::endl;
        exit(0);
    }


    std::cerr << "Cloud before filtering: " << std::endl;
    std::cerr << *cloud << std::endl;

    // display pointcloud after filtering
    std::cerr << "Cloud after filtering: " << std::endl;
    std::cerr << *cloud_filtered << std::endl;

    showPointClouds(cloud_filtered);
    return (0);
}

半径滤波

Cloud before filtering: 
header: seq: 0 stamp: 0 frame_id: 

points[]: 98322
width: 98322
height: 1
is_dense: 1
sensor origin (xyz): [0, 0, 0] / orientation (xyzw): [0, 0, 0, 1]

Cloud after filtering: 
header: seq: 0 stamp: 0 frame_id: 

points[]: 95967
width: 95967
height: 1
is_dense: 1
sensor origin (xyz): [0, 0, 0] / orientation (xyzw): [0, 0, 0, 1]

在这里插入图片描述

条件滤波

Cloud before filtering: 
header: seq: 0 stamp: 0 frame_id: 

points[]: 98322
width: 98322
height: 1
is_dense: 1
sensor origin (xyz): [0, 0, 0] / orientation (xyzw): [0, 0, 0, 1]

Cloud after filtering: 
header: seq: 0 stamp: 0 frame_id: 

points[]: 9904
width: 9904
height: 1
is_dense: 1
sensor origin (xyz): [0, 0, 0] / orientation (xyzw): [0, 0, 0, 1]

在这里插入图片描述

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

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

相关文章

Vue(组件化编程:非单文件组件、单文件组件)

一、组件化编程 1. 对比传统编写与组件化编程&#xff08;下面两个解释图对比可以直观了解&#xff09; 传统组件编写&#xff1a;不同的HTML引入不同的样式和行为文件 组件方式编写&#xff1a;组件单独&#xff0c;复用率高&#xff08;前提组件拆分十分细致&#xff09; 理…

【Fluent】Error: Model information is incompatible with incoming mesh.

一、问题背景 在原有workbench数据文件上&#xff0c;修改几何数据&#xff0c;然后重新划分网格&#xff0c;在更新网格后&#xff0c;workbench就弹出错误Error&#xff01; Model information is incompatible with incoming mesh. 因为当时并不影响我打开fluent求解器&am…

C语言数组介绍和用法

文章目录 前言一、数组的定义二、数组的大小三、数组的访问方法四、使用for循环遍历数组五、数组地址的访问方法六、二维数组七、二维数组的遍历总结 前言 本篇文章将带大家学习C语言中的数组&#xff0c;数组在C语言中是一个比较重要的点&#xff0c;大家需要好好理解并多加使…

Linux Shell 介绍及常用命令汇总

文章目录 Part.I shell 简介Chap.I 概念汇编Chap.II 命令概览 Part.II shell 常用命令大全Chap.I 关于文件和目录Chap.II 关于磁盘和内存Chap.III 关于进程调度 Reference Part.I shell 简介 Chap.I 概念汇编 下面是一些概念 shell 与 bash 的区别与联系&#xff1a;bash 是 b…

2023五一杯B题:快递需求分析问题

题目 网络购物作为一种重要的消费方式&#xff0c;带动着快递服务需求飞速增长&#xff0c;为我国经济发展做出了重要贡献。准确地预测快递运输需求数量对于快递公司布局仓库站点、节约存储成本、规划运输线路等具有重要的意义。附件1、附件2、附件3为国内某快递公司记录的部分…

从力的角度再次比较9-2分布和8-3分布

( A, B )---1*30*2---( 1, 0 )( 0, 1 ) 让网络的输入只有1个节点&#xff0c;AB各由11张二值化的图片组成&#xff0c;让A中有3个0&#xff0c;8个1.B中全是0&#xff0c;排列组合A的所有可能&#xff0c;统计迭代次数的顺序。在前面实验中得到了8-3分布的数据 A-B 迭代次数 …

孔乙己文学,满街长衫,为谁而穿?解构孔乙己文学

鲁迅先生创作《孔乙己》的背景是20世纪初期的中国社会。那时&#xff0c;中国正处于民国的初期&#xff0c;社会动荡不安&#xff0c;人民生活贫困。在这个背景下&#xff0c;鲁迅开始写作并发表了一系列揭露社会黑暗面的作品。《孔乙己》是其中之一&#xff0c;它讲述了一个被…

利用snpEff对基因型VCF文件进行变异注释的详细方法

利用snpEff对VCF文件进行变异注释 群体遗传研究中&#xff0c;在获得SNP位点后,我们需要对SNP位点进行注释&#xff0c;对这些SNP位点进行更深的了解。 snpEff是一个用于对基因组单核苷酸多态性(SNP)进行注释的软件&#xff0c;snpEff软件可以用于对VCF文件进行变异注释&#x…

VC++ | VS2017编译报错-20230428

VC | VS2017编译报错-20230428 文章目录 VC | VS2017编译报错-202304281.报错1-1.解决办法 2.报错2-1.解决办法2-1-1.做如下设置2-1-2.代码调整 1.报错 1>------ 已启动生成: 项目: NvtUSBTool, 配置: Debug Win32 ------ 1>NvtUSBTool.cpp 1>$(PRJ_ROOT_DIR)nvtusbt…

Linux文件系统权限

目录标题 文件权限文件和目录的一般权限文件的权限针对三类对象进行定义文件和目录中&#xff0c;r、w、x的作用 设置文件和目录的一般权限修改文件或目录的权限—chmod(change mode)命令权限值的表示方法—使用3位八进制数表示权限值的表示方法—使用字符串表示修改文件或目录…

视频转gif如何做?三步教你视频转gif制作

如何将视频做成gif表情包呢&#xff1f;想要把视频中的精彩画面截取出来做成gif动画表情&#xff0c;却又不想下载软件的时候&#xff0c;该怎么办呢&#xff1f;有没有简单实用的工具呢&#xff1f; 一、什么工具能够截取视频做gif呢&#xff1f; GIF中文网作为一款专业的在…

react之按钮鉴权

使用HOC来完成 HOC&#xff1a;高阶组件&#xff0c;是React中复用组件逻辑的一种高级技巧。HOC自身不是React API的一部分&#xff0c;他是一种基于React的组合特性而形成的设计模式。 作用&#xff1a;用于复用组件的业务逻辑 VUE mixinReact Hoc 用户数据渲染带操作按钮渲…

C#手术麻醉临床信息系统源码,实现体征数据自动采集绘制

手麻系统源码&#xff0c;自动生成电子单据 基于C# 前端框架&#xff1a;Winform后端框架&#xff1a;WCF 数据库&#xff1a;sqlserver 开发的手术麻醉临床信息系统源码&#xff0c;应用于医院手术室、麻醉科室的计算机软件系统。该系统针对整个围术期&#xff0c;对病人进…

本地安装kibana kibana设置中文汉化

一、Kibana简介 Kibana是一个开源的基于浏览器的分析和可视化平台&#xff0c;可以用于搜索&#xff0c;查看&#xff0c;删除Elasticsearch索引并与存储在Elasticsearch索引中的数据进行交互。可以执行高级数据分析&#xff0c;并且以各种图标、表格和地图的形式可视化数据。…

【hello Linux】进程信号

目录 1. 进程信号的引出及整体概况 2. 信号的产生 1. 键盘产生 2. 进程异常 3. 系统调用 4. 软件条件 3. 信号的保存 1. 信号相关的常见概念 2. sigset_t 3. 信号集操作函数 4. sigprocmask&#xff1a;对block位图的操作 5. sigpending&#xff1a;对pending位图的操作 6. 捕捉…

三分钟看懂Python分支循环规范:if elif for while

人生苦短&#xff0c;我用python 分支与循环 条件是分支与循环中最为核心的点&#xff0c; 解决的问题场景是不同的问题有不同的处理逻辑。 当满足单个或者多个条件或者不满足条件进入分支和循环&#xff0c; 这里也就说明这个对相同问题处理执行逻辑依据具体参数动态变化&…

智慧医疗服务平台有哪些优势?

对于引用了智慧医疗服务平台的机构来说&#xff0c;其优势体现在哪些方面呢&#xff1f; 一、提高医疗资源利用效率。 在传统的医疗模式中&#xff0c;医生需要耗费大量的时间和精力去处理病人的病历、诊断、治疗等问题。而在智慧医疗服务平台的支持下&#xff0…

稳定排序和不稳定排序

稳定排序和不稳定排序 稳定排序 插入排序、冒泡排序、归并排序、基数排序 其时间复杂度 直接插入排序 最好情况:初始有序,为O(n); 最坏情况:初始逆序,为O(n) 平均时间复杂度T(n) O(n) 折半插入排序 时间复杂度为O(n) 冒泡排序 最好时&#xff0c;基本有序&#xff0c;…

Python 科研绘图可视化(后处理)Matplotlib - 2D彩图

Introduction 科研可视化是将数据和信息转化为可视化形式的过程&#xff0c;旨在通过图形化展示数据和信息&#xff0c;使得科研工作者能够更好地理解和分析数据&#xff0c;并从中发现新的知识和洞见。科研可视化可以应用于各种领域&#xff0c;如生物学、物理学、计算机科学…

制造策略 ETO、MTO、ATO、MTS

ETO 按交货周期跨度从长到短来讲&#xff0c;首先就是 ETO&#xff0c;Engineer To Order – 面向订单设计、定制生产或特殊生产。 就是客户给的订单&#xff0c;你要生产的话&#xff0c;你之前的原产品改动很大&#xff0c;或者基本上用不上&#xff0c;要完全按照客户的要求…