点云——噪声(代码)

本人硕士期间研究的方向就是三维目标点云跟踪,对点云和跟踪有着较为深入的理解,但一直忙于实习未进行梳理,今天趁着在家休息对点云的噪声进行梳理,因为预处理对于点云项目是至关重要的,所有代码都是近期重新复现过。

这篇之前写的,主要是对P2B点云跟踪进行复现以及学习记录,里面也包含了一些对点云的理解

P2B论文复现——点云学习记录_etw_pytorch_utils.git-CSDN博客

对PTT代码是更为熟悉的,几篇论文都是基于这个进行修改,等我今年毕业后会更新一次

目录

1、点云噪声是什么

2、点云噪声滤波技术

3、点云数据

4、统计滤波器

5、体素网格滤波

6、半径离群值移除

7、边缘保留滤波

8、将无组织的点云映射到二维图像

9、将无组织的点云转换为有组织的点云 

1、点云噪声是什么

点云噪声是指在使用三维扫描设备(如激光扫描仪、立体视觉相机等)获取点云数据时,由于各种原因引入的误差或偏差。这些噪声可能来源于设备的精度限制、扫描环境的影响(如光照条件、反射表面)、或者是数据处理过程中的算法误差。点云噪声会影响数据的质量,进而影响后续的处理和分析,如三维重建、模型识别等。

噪声的表现形式多种多样,包括:

  • 随机噪声:这是最常见的噪声类型,表现为点的位置存在随机偏差。
  • 系统噪声:由扫描设备的固有特性引起,如畸变、校准错误等,导致点云数据整体偏移或变形。
  • 环境噪声:由扫描环境引起,如由于表面反射特性不同,导致某些区域点云密度不均或缺失。

为了提供直观的理解,可以想象一个简单的场景:使用激光扫描仪扫描一个球体。理想情况下,扫描得到的点应该均匀分布在球体表面。然而,在实际情况中,扫描得到的点云数据可能会因为噪声的存在而出现以下问题:

  • 球体表面的点不是完全均匀分布,而是有些区域点更密集,有些区域点更稀疏。
  • 球体的形状看起来可能不是完全光滑的圆形,而是有些凹凸不平的地方。
  • 在球体的边缘或特定区域可能会有一些离群点,这些点明显偏离了球体的真实表面。

2、点云噪声滤波技术

解决点云噪声的方法通常涉及多种滤波技术,旨在去除或减少噪声,同时尽量保留有用的数据信息。以下是一些常用的点云滤波技术:

  1. 统计滤波器(Statistical Outlier Removal, SOR):此方法基于统计分析,移除那些与其邻近点距离大幅偏离平均值的点。它假设点云的噪声是高斯分布的,通过计算每个点到其邻居的距离的平均值和标准差,然后根据这些统计数据移除离群点。

  2. 体素网格滤波(Voxel Grid Filter):该技术通过创建一个三维体素网格覆盖在整个点云上,然后在每个体素内部将所有点简化为一个代表点(例如,通过取平均位置),以减少点云中的点数。这种方法对于降低数据量和滤除噪声很有效。

  3. 半径离群值移除(Radius Outlier Removal):在这种方法中,对于每一个点,如果在给定的半径内找到的邻近点数少于某个阈值,这个点就被认为是离群值并被移除。这种方法对于去除孤立的噪声点很有效。

  4. 边缘保留滤波:这种方法尤其适用于在尽量保留数据特征边缘的同时去除噪声。例如,双边滤波器和引导滤波器能够在平滑数据的同时,保留边缘信息。

  5. 深度学习方法:最近,深度学习技术也被应用于点云噪声的去除。通过训练神经网络模型来识别和滤除噪声点,这种方法可以非常有效,尤其是在处理复杂数据和场景时。

选择合适的滤波技术时,需要考虑数据的特点、处理目标以及对结果质量的要求。在实际应用中,可能需要尝试多种方法或将几种方法组合使用,以达到最佳的去噪效果。

3、点云数据

一般是pcd和ply,这两个都可以互相转换

ply转pcd

#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/io/ply_io.h>

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

    if (pcl::io::loadPLYFile<pcl::PointXYZRGB>(R"(D:\CPlusProject\PCL\pclTest\Data\Sparse.ply)", *cloud) == -1) //加载文件
    {
        PCL_ERROR("Couldn't read file Sparse.ply \n");
        system("PAUSE");
        return (-1);
    }
    //显示点云数量
    std::cout << "Loaded "
        << cloud->width * cloud->height
        << " data points from Sparse.ply with the following fields: "
        << std::endl;

    //保存文件,包括颜色信息
    std::string filename("Sparse.pcd");
    pcl::PCDWriter writer;
    writer.write<pcl::PointXYZRGB>(R"(D:\CPlusProject\PCL\pclTest\Data\Sparse.pcd)", *cloud, true); // 第三个参数为true时表示保存为二进制格式,可以包含颜色信息

    system("PAUSE");
    return 0;
}

4、统计滤波器

#include <iostream>
#include <pcl/point_types.h>
#include <pcl/filters/statistical_outlier_removal.h>
#include <pcl/io/pcd_io.h>

int main()
{
    // 创建点云指针
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>);

    // 读取点云文件
    if (pcl::io::loadPCDFile<pcl::PointXYZ>(R"(D:\CPlusProject\PCL\pclTest\Data\Sparse.pcd)", *cloud) == -1)
    {
        PCL_ERROR("Couldn't read file Sparse.pcd \n");
        return (-1);
    }
    std::cout << "Loaded "
        << cloud->width * cloud->height
        << " data points from Sparse.pcd with the following fields: "
        << std::endl;

    // 创建滤波器对象
    pcl::StatisticalOutlierRemoval<pcl::PointXYZ> sor;
    sor.setInputCloud(cloud);
    sor.setMeanK(50); // 设置在进行统计分析时考虑的临近点个数
    sor.setStddevMulThresh(1.0); // 设置标准差倍数阈值
    sor.filter(*cloud_filtered);

    

    // 保存过滤后的点云
    pcl::io::savePCDFile(R"(D:\CPlusProject\PCL\pclTest\Data\Sparse_Filter.pcd)", *cloud_filtered);

    std::cout << "Cloud after filtering: " << std::endl;
    std::cout << "Saved "
        << cloud_filtered->width * cloud_filtered->height
        << " data points to filtered_output.pcd."
        << std::endl;

    return 0;
}

 报错如下。解决方案:通过项目属性->C/C++->代码生成->启用增强指令集->选择AVX

原图 

 设置下点的大小

滤波后 ,看左下角,一些单个的离群点已经消除,算法滤波能力取决于参数

5、体素网格滤波

对于降低数据量和滤除噪声很有效

因此上一个点云数据有点太小了,建议换大点的,我换了一个点云是不带RGB颜色的,也就是把PointXYZRGB换成PointXYZ




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

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>);

    // 读取PCD文件
    if (pcl::io::loadPCDFile<pcl::PointXYZ>(R"(D:\CPlusProject\PCL\pclTest\Data\chef.pcd)", *cloud) == -1) //* 打开点云文件
    {
        PCL_ERROR("Couldn't read file input_color.pcd \n");
        return (-1);
    }
    std::cout << "Loaded "
        << cloud->width * cloud->height
        << " data points from input_color.pcd with the following fields: "
        << std::endl;

    // 创建体素网格滤波器对象
    pcl::VoxelGrid<pcl::PointXYZ> sor;
    sor.setInputCloud(cloud);
    sor.setLeafSize(0.01f, 0.01f, 0.01f); // 设置体素网格的大小
    sor.filter(*cloud_filtered);

    std::cout << "PointCloud after filtering: " << cloud_filtered->width * cloud_filtered->height
        << " data points." << std::endl;

    // 保存过滤后的点云
    pcl::io::savePCDFile(R"(D:\CPlusProject\PCL\pclTest\Data\chef_VoxelGrid.pcd)", *cloud_filtered);

    return (0);
}

原图 

滤波后,很明显的数据量减少

6、半径离群值移除

 这种方法对于去除孤立的噪声点很有效

#include <iostream>
#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
#include <pcl/io/pcd_io.h>
#include <pcl/filters/radius_outlier_removal.h>

int main(int argc, char** argv)
{
    // 创建点云指针
    pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGB>);
    pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZRGB>);

    // 读取点云文件
    if (pcl::io::loadPCDFile<pcl::PointXYZRGB>(R"(D:\CPlusProject\PCL\pclTest\Data\Sparse.pcd)", *cloud) == -1)
    {
        PCL_ERROR("Couldn't read file input_color.pcd \n");
        return (-1);
    }
    std::cout << "Loaded "
        << cloud->width * cloud->height
        << " data points from input_color.pcd with the following fields: "
        << std::endl;

    // 创建半径离群值移除滤波器
    pcl::RadiusOutlierRemoval<pcl::PointXYZRGB> outrem;
    outrem.setInputCloud(cloud);
    outrem.setRadiusSearch(0.2); // 设置搜索半径
    outrem.setMinNeighborsInRadius(5); // 设置半径内最小邻居数目

    // 应用滤波器
    outrem.filter(*cloud_filtered);

    std::cout << "PointCloud after filtering: " << cloud_filtered->width * cloud_filtered->height
        << " data points." << std::endl;

    // 保存过滤后的点云
    pcl::io::savePCDFile(R"(D:\CPlusProject\PCL\pclTest\Data\Sparse_RadiusOutlierRemoval.pcd)", *cloud_filtered);

    return (0);
}

原图

滤波后,还是比较明显的,离群点不见了

7、边缘保留滤波

旨在平滑数据的同时保留边缘特征,如物体边界。我们可以利用类似于图像处理中边缘保留技术的方法,例如双边滤波(Bilateral filter),来实现类似的效果。双边滤波是一种常见的边缘保留滤波方法,可以在平滑点云数据的同时保留其边缘信息。

#include <iostream>
#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
#include <pcl/io/pcd_io.h>
#include <pcl/filters/fast_bilateral.h> // 注意:PCL版本可能影响这个头文件的可用性

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>());

    if (pcl::io::loadPCDFile<pcl::PointXYZ>(R"(D:\CPlusProject\PCL\pclTest\Data\chef.pcd)", *cloud) == -1) //* 打开点云文件
    {
        PCL_ERROR("Couldn't read file input.pcd \n");
        return (-1);
    }

    // 创建双边滤波对象
    pcl::FastBilateralFilter<pcl::PointXYZ> fbFilter;
    fbFilter.setInputCloud(cloud);
    fbFilter.setSigmaS(1.5); // 空间范围的标准差
    fbFilter.setSigmaR(0.05f); // 颜色或强度范围的标准差

    // 应用滤波器
    fbFilter.applyFilter(*cloud_filtered);

    // 保存过滤后的点云
    pcl::io::savePCDFile(R"(D:\CPlusProject\PCL\pclTest\Data\chef_organized_FastBilateralFilter.pcd)", *cloud_filtered);

    return 0;
}



报错

[pcl::FastBilateralFilter] Input cloud needs to be organized.

[pcl::PCDWriter::writeASCII] Input point cloud has no data!

输入的点云需要是有组织的(organized)。有组织的点云类似于图像数据,其中每个点都有明确的像素位置(即它们是按矩阵形式排列的),这通常是从深度相机(如Kinect或Realsense)直接获取的数据。如果你的点云是无组织的(unorganized),即简单的点云列表,那么FastBilateralFilter无法直接应用。

 如何将无组织的点云转换为有组织的点云?

将无组织的点云映射到二维图像->二维图像映射成三维点云

看完第8节和第9节应该可以得到如下图片,双边滤波的参数对z轴影响很大,注意参数调节

8、将无组织的点云映射到二维图像

要实现将无组织的点云映射到一个特定平面并为其分配一个固定分辨率的过程,我们需要考虑几个关键步骤:定义映射平面、选择分辨率、计算2D像素位置。这个示例不会涉及复杂的相机内参转换。深度信息直接用z来进行表示。



#include <iostream>
#include <vector>
#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
#include <pcl/io/pcd_io.h>
#include <pcl/common/common.h> // 包含 getMinMax3D

#include <opencv2/opencv.hpp> // 包含OpenCV库头文件
#include <opencv2/highgui/highgui.hpp>
#include <algorithm> // std::minmax_element

int main() {
    // 假设已经加载了点云数据到cloud变量
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);

    // 加载点云文件
    if (pcl::io::loadPCDFile<pcl::PointXYZ>(R"(D:\CPlusProject\PCL\pclTest\Data\chef.pcd)", *cloud) != 0) {
        return -1;
    }

    int imageWidth = 640;
    int imageHeight = 480;
    // 初始化深度图,使用-1表示该像素位置没有对应的点云数据
    std::vector<std::vector<float>> depthMap(imageHeight, std::vector<float>(imageWidth, -1));

    // 确定点云的边界
    pcl::PointXYZ minPt, maxPt;
    pcl::getMinMax3D(*cloud, minPt, maxPt);

    // 遍历点云中的每个点
    for (const auto& point : cloud->points) {
        // 将点云的坐标转换为2D图像的像素坐标
        // 这里使用简单的线性映射,假设点云完全覆盖图像平面
        int u = static_cast<int>((point.x - minPt.x) / (maxPt.x - minPt.x) * (imageWidth - 1));
        int v = static_cast<int>((point.y - minPt.y) / (maxPt.y - minPt.y) * (imageHeight - 1));

        // 选择z值作为深度信息
        float depth = point.z;

        // 更新深度图
        if (u >= 0 && u < imageWidth && v >= 0 && v < imageHeight) {
            // 这里简单地将点云的z值直接赋给像素,实际应用中可能需要其他处理方式
            depthMap[v][u] = depth;
        }
    }


    // 将depthMap转换为cv::Mat
    int rows = depthMap.size();
    int cols = depthMap[0].size();
    cv::Mat depthImage(rows, cols, CV_32FC1); // 浮点单通道图像

    for (int i = 0; i < rows; ++i) {
        for (int j = 0; j < cols; ++j) {
            depthImage.at<float>(i, j) = depthMap[i][j];
        }
    }

    // 可视化处理
    // 为了更好地在图像中显示深度信息,我们可以对深度值进行归一化
    double minVal, maxVal;
    cv::minMaxIdx(depthImage, &minVal, &maxVal); // 查找深度图中的最小和最大值
    cv::Mat normalizedDepthImage;
    cv::convertScaleAbs(depthImage, normalizedDepthImage, 255 / (maxVal - minVal), -minVal * 255 / (maxVal - minVal));

    // 显示深度图
    cv::namedWindow("Depth Image", cv::WINDOW_AUTOSIZE);
    cv::imshow("Depth Image", normalizedDepthImage);
    cv::waitKey(0); // 等待按键

    // 保存深度图为图片
    cv::imwrite(R"(D:\CPlusProject\PCL\pclTest\Data\chef_depth_image.png)", normalizedDepthImage);
    
    return 0;
}

这段代码首先将深度图转换为OpenCV的cv::Mat格式,然后使用cv::minMaxIdx查找深度图中的最小和最大深度值,以便对深度值进行归一化处理,使其范围在0到255之间。这样处理后的深度图更适合在屏幕上显示和保存为图片。

运行代码即可看到三维点云已经映射到二维图像上了

9、将无组织的点云转换为有组织的点云 

前提是做了前一步,三维映射到二维得到深度图 

这边的相机模型参数是简单的一种模拟



#include <iostream>
#include <vector>
#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
#include <pcl/io/pcd_io.h>
#include <pcl/common/common.h> // 包含 getMinMax3D


int main() {
    // 假设已经加载了点云数据到cloud变量
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);

    // 加载点云文件
    if (pcl::io::loadPCDFile<pcl::PointXYZ>(R"(D:\CPlusProject\PCL\pclTest\Data\chef.pcd)", *cloud) != 0) {
        return -1;
    }

    int imageWidth = 640;
    int imageHeight = 480;
    // 初始化深度图,使用-1表示该像素位置没有对应的点云数据
    std::vector<std::vector<float>> depthMap(imageHeight, std::vector<float>(imageWidth, -1));

    // 确定点云的边界
    pcl::PointXYZ minPt, maxPt;
    pcl::getMinMax3D(*cloud, minPt, maxPt);

    // 遍历点云中的每个点
    for (const auto& point : cloud->points) {
        // 将点云的坐标转换为2D图像的像素坐标
        // 这里使用简单的线性映射,假设点云完全覆盖图像平面
        int u = static_cast<int>((point.x - minPt.x) / (maxPt.x - minPt.x) * (imageWidth - 1));
        int v = static_cast<int>((point.y - minPt.y) / (maxPt.y - minPt.y) * (imageHeight - 1));

        // 选择z值作为深度信息
        float depth = point.z;

        // 更新深度图
        if (u >= 0 && u < imageWidth && v >= 0 && v < imageHeight) {
            // 这里简单地将点云的z值直接赋给像素,实际应用中可能需要其他处理方式
            depthMap[v][u] = depth;
        }
    }


    // 有了深度图 depthMap 和对应的尺寸 imageWidth, imageHeight
    pcl::PointCloud<pcl::PointXYZ>::Ptr organizedCloud(new pcl::PointCloud<pcl::PointXYZ>);

    organizedCloud->width = imageWidth;
    organizedCloud->height = imageHeight;
    organizedCloud->is_dense = false; // 有组织的点云可能包含无效点
    organizedCloud->points.resize(organizedCloud->width * organizedCloud->height);

    // 假设的相机参数
    float focalLength = 1500.0; // 焦距,以某种单位表示
    float centerX = imageWidth / 2.0;
    float centerY = imageHeight / 2.0;
    float scalingFactor = 1; // 将深度值转换为相同单位的比例因子

    for (int i = 0; i < imageHeight; ++i) {
        for (int j = 0; j < imageWidth; ++j) {
            pcl::PointXYZ point;
            if (depthMap[i][j] != -1) {
                float z = depthMap[i][j] * scalingFactor; // 转换深度值
                float x = (j - centerX) * z / focalLength;
                float y = (i - centerY) * z / focalLength;
                point.x = x;
                point.y = y;
                point.z = z;
            }
            else {
                point.x = point.y = point.z = std::numeric_limits<float>::quiet_NaN();
            }
            organizedCloud->points[i * imageWidth + j] = point;
        }
    }



    //保存为有组织的三维点云
    if (pcl::io::savePCDFile(R"(D:\CPlusProject\PCL\pclTest\Data\chef_organized.pcd)", *organizedCloud) == -1) {
        PCL_ERROR("Couldn't save the organized point cloud file.\n");
        return -1;
    }
    
    return 0;
}

 好的,大家可与拿这个有组织的点云数据跑双边滤波了,已经测过,不会报错了。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【并发编程】锁-源码分析

1、ReentrantLock 1.1 加锁流程源码 1.1.1 加锁流程概述 1.1.2 lock源码分析 1.1.2.1 公平和非公平锁方式 // 非公平锁 final void lock() {// 上来就先基于CAS的方式,尝试将state从0改为1if (compareAndSetState(0, 1))// 获取锁资源成功,会将当前线程设置到exclusiveOwn…

前端JavaScript篇之call() 和 apply() 的区别?

目录 call() 和 apply() 的区别&#xff1f; call() 和 apply() 的区别&#xff1f; 在JavaScript中&#xff0c;call()和apply()都是用来改变函数中this指向的方法&#xff0c;它们的作用是一样的&#xff0c;只是传参的方式不同。 call()方法和apply()方法的第一个参数都是…

【Web】小白友好的Java内存马基础学习笔记

目录 简介 文件马与内存马的比较 文件马原理 内存马原理 内存马使用场景 内存马分类 内存马注入方式 这篇文章主要是概念性的&#xff0c;具体技术细节不做探究&#xff0c;重点在祛魅。 简介 内存马&#xff08;Memory Shellcode&#xff09;是一种恶意攻击技术&…

【GAMES101】Lecture 20 颜色

目录 光 颜色 加色系统 CIE RGB颜色匹配实验 颜色空间 CIE XYZ颜色空间 HSV颜色空间(Hue-Saturation-Value) CIELAB空间 减色系统&#xff1a;CMYK 光 光是由不同波长的光波组成的&#xff0c;其中可见光的波长范围在400nm到700nm 用谱功率密度&#xff08;Spectral…

相机图像质量研究(11)常见问题总结:光学结构对成像的影响--像差

系列文章目录 相机图像质量研究(1)Camera成像流程介绍 相机图像质量研究(2)ISP专用平台调优介绍 相机图像质量研究(3)图像质量测试介绍 相机图像质量研究(4)常见问题总结&#xff1a;光学结构对成像的影响--焦距 相机图像质量研究(5)常见问题总结&#xff1a;光学结构对成…

算法学习——LeetCode力扣字符串篇

算法学习——LeetCode力扣字符串篇 344. 反转字符串 344. 反转字符串 - 力扣&#xff08;LeetCode&#xff09; 描述 编写一个函数&#xff0c;其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。 不要给另外的数组分配额外的空间&#xff0c;你必须原地…

每日五道java面试题之java基础篇(四)

第一题. 访问修饰符 public、private、protected、以及不写&#xff08;默认&#xff09;时的区别&#xff1f; Java 中&#xff0c;可以使⽤访问控制符来保护对类、变量、⽅法和构造⽅法的访问。Java ⽀持 4 种不同的访问权限。 default (即默认&#xff0c;什么也不写&…

腾讯云4核8g10M轻量服务器能承受多少人在线访问?

腾讯云轻量4核8G12M轻量应用服务器支持多少人同时在线&#xff1f;通用型-4核8G-180G-2000G&#xff0c;2000GB月流量&#xff0c;系统盘为180GB SSD盘&#xff0c;12M公网带宽&#xff0c;下载速度峰值为1536KB/s&#xff0c;即1.5M/秒&#xff0c;假设网站内页平均大小为60KB…

七、滚动条操作——调整图像对比度

对比度调整&#xff1a;是在原来图像基础上进行相应的公式调整&#xff0c;是类似乘法操作&#xff0c;本身像数值越大&#xff0c;对比度增加之后其与低像素点值差距越大&#xff0c;导致对比增强 项目最终效果&#xff1a;通过滚动条trackbar来实现调整图片亮度的功能 我这里…

单片机与外设的交互

单片机与外设的交互是嵌入式系统中非常重要的一个基础知识点。单片机是一个集成在同一芯片上的中央处理器、存储器和输入/输出接口,它可以根据用户编写的程序与各种外部设备即外设进行交互。单片机与外设之间的交互主要通过单片机上的输入/输出口(I/O口)来实现。 I/O口的工作原…

(坑点!!!)给定n条过原点的直线和m条抛物线(y=ax^2+bx+c,a>0),对于每一条抛物线,是否存在一条直线与它没有交点,若有,输出直线斜率

题目 思路: 1、区间端点可能是小数的时候,不能直接利用加减1将 < 转化为 <=,例如,x < 1.5 不等价于 x <= 2.5 2、该题中k在(b - sqrt(4 * a * c), b + sqrt(4 * a * c) 中,注意是开区间,那么可以将左端点向上取整,右端点向下取整,即sqrt(4 * a * c)向下取…

超维机器人年终总结大事记回顾

2023年&#xff0c;对于超维机器人来说&#xff0c;是充满挑战和机遇的一年。在这一年里&#xff0c;我们攻坚克难&#xff0c;持续创新&#xff0c;深度聚焦智能巡检机器人的发展&#xff0c;加强合作伙伴关系&#xff0c;不断优化产品和服务&#xff0c;不断提升客户体验&…

[NSSCTF]-Web:[SWPUCTF 2021 新生赛]easy_sql解析

查看网页 有提示&#xff0c;参数是wllm&#xff0c;并且要我们输入点东西 所以&#xff0c;我们尝试以get方式传入 有回显&#xff0c;但似乎没啥用 从上图看应该是字符型漏洞&#xff0c;单引号字符注入 先查看字段数 /?wllm2order by 3-- 没回显 报错了&#xff0c;说明…

初识String类和String类的拓展

前言&#xff1a;以下是Java中String类的知识点与一些常见问题和注意事项&#xff0c;如有讲解不妥&#xff0c;请见谅&#xff01; 目录 1.String类的创建及常见API &#xff08;1&#xff09;String类的四种创建方式&#xff1a; 补充&#xff1a;字符串转化成字符数组 / …

MTK 多帧算法集成实现流程

和你一起终身学习&#xff0c;这里是程序员Android 经典好文推荐&#xff0c;通过阅读本文&#xff0c;您将收获以下知识点: 一、选择feature和配置feature table二、 挂载算法三、自定义metadata四、APP调用算法五、结语 一、选择feature和配置feature table 1.1 选择feature …

C++入门篇(4)—— 类与对象(1)

目录 1.类的引入 2.类的定义 3.类的访问限定符 4.类的作用域 5. 类对象的存储方式 6. this指针 6.1 this指针的引入 6.2 this指针的特性 6.3有意思的面试题 1.类的引入 C语言struct 结构体中只能定义变量&#xff0c;而C中可以定义函数。 struct Date {void Init(int…

Go语言每日一练——链表篇(八)

传送门 牛客面试笔试必刷101题 ----------------两个链表的第一个公共结点 题目以及解析 题目 解题代码及解析 解析 这一道题使用的还是双指针算法&#xff0c;我们先求出两个链表的长度差n&#xff0c;然后定义快慢指针&#xff0c;让快指针先走n步&#xff0c;最后快慢指…

IntelliScraper 更新 --可自定义最大输出和相似度 支持Html的内容相似度匹配

场景 之前我们在使用IntelliScraper 初代版本的时候&#xff0c;不少人和我反馈一个问题&#xff0c;那就是最大输出结果只有50个&#xff0c;而且还带有html内容&#xff0c;不支持自动化&#xff0c;我声明一下&#xff0c;自动化目前不会支持&#xff0c;以后也不会支持&am…

02 数据库管理 数据表管理

文章目录 数据库管理数据表管理基础数据类型表的基本操作 数据库管理 查看已有库 show databases; 创建库 create database 库名 [character set utf8]; e.g. 创建stu数据库&#xff0c;编码为utf8 create database stu character set utf8; create database stu charsetutf8;…

第二十七回 武松威镇安平寨 施恩义夺快活林-人人爱用的Python编程语言

张青提议武松不要去牢城营受苦&#xff0c;可以把公差杀掉然后去二龙山入伙鲁智深。武松却坚持他的道义原则&#xff0c;不愿意伤害一路上照顾他的两位公人。张青尊重他的决定&#xff0c;救醒了两位公人。 张青、孙二娘和武松以及两位公人一起喝酒吃饭&#xff0c;张青还向武…