PCL学习五:Range Images-距离图像

news2024/11/18 12:28:16

参考引用

  • Point Cloud Library
  • 黑马机器人 | PCL-3D点云
  • PCL深度图像

1. 引言

1.1 深度图像的获取与研究方向

  • 获取方法

    • 激光雷达深度成像法,计算机立体视觉成像,坐标测量机法,莫尔条纹法,结构光法
  • 研究方向

    • 深度图像的分割技术
    • 深度图像的边缘检测技术
    • 基于不同视点的多幅深度图像的配准技术
    • 基于深度数据的三维重建技术
    • 基于三维深度图像的三维目标识别技术
    • 深度图像的多分辨率建模和几何压缩技术

1.2 深度图像定义

  • 深度图像(Depth Images)也被称为距离影像(Range Image),是指:将从图像采集器到场景中各点的距离值作为像素值的图像,它直接反应了景物可见表面的几何形状(来自传感器一个特定角度拍摄的一个三维场景获取的有规则的有焦距等基本信息的深度图)

  • 从数学模型上看,深度图像可以看做是标量函数 j : I 2 → R j:I^2\to R j:I2R 在几何 K K K 上的离散采样,得到 r i = j ( u i ) r_i=j(u_i) ri=j(ui),其中 u i ∈ I 2 u_i\in I^2 uiI2 为二维网格(矩阵)的索引, r i ∈ R , i = 1 , … , k r_i\in R,i=1,\ldots,k riR,i=1,,k以下为从不同视角获得的深度图像过程示意
    在这里插入图片描述

  • 点云:当一束激光照射到物体表面时,所反射的激光会携带方位、距离和强度等信息。若将激光束按照某种轨迹进行扫描,便会边扫描边记录到反射的激光点信息,由于扫描极为精细,则能够得到大量的激光点,因而就可形成激光点云。点云格式有 .las、.pcd、.txt

    在 PCL 中深度图像与点云最主要的区别在于:近邻的检索方式不同,并且可以互相转换,深度图像经过点云变换可以计算为点云数据,有规则及有必要信息的点云数据可以反算为深度图像数据

2. 从点云创建深度图

2.1 pcl::RangeImage

  • RangeImage 类继承于 PointCloud,主要功能是:实现一个特定视点得到一个三维场景的深度图像,其继承关系如下
    在这里插入图片描述

2.2 核心函数及参数说明

  • 函数
    createFromPointCloud(pointCloud, angularResolution, maxAngleWidth, maxAngleHeight,
                         sensorPose, coordinate_frame, noiseLevel, minRange, borderSize)
    
  • 参数
    • pointCloud:被检测点云
    • angularResolution = 1:邻近的像素点所对应的每个光束之间相差 1°
    • maxAngleWidth = 360:进行模拟的距离传感器对周围的环境拥有一个完整的 360° 视角,无论任何数据集都推荐使用此设置,因为最终获取的深度图像将被裁剪到有空间物体存在的区域范围
    • maxAngleHeight = 180:当传感器后面没有可以观测的点时,设置一个水平视角为 180° 的激光扫描仪即可,因为只需要观察距离传感器前面就可以了
    • sensorPose:定义了模拟深度图像获取传感器的 6 自由度位置,其原始值为横滚角 roll、俯仰角 pitch、偏航角 yaw 都为 0,设置的模拟传感器的位姿是一个仿射变换矩阵,默认为 4*4 的单位矩阵变换
    • coordinate_frame:设置为 CAMERA_FRAME 说明系统的 X 轴是向右的、Y 轴是向下的、Z 轴是向前的,另外参数值是 LASER_FRAME,其 X 轴向前、Y 轴向左、Z 轴向上
    • noiseLevel = 0:是指使用一个归一化的 Z 缓存区来创建深度图像,如果想让邻近点集都落在同一个像素单元,可以设置一个较高的值,例如 noiseLevel = 0.05 可以理解为深度距离值是通过查询点半径为 5cm 的圆内包含的点用来平均计算而得到的
    • minRange = 0:设置最小的获取距离,如果设置 > 0 则所有模拟器所在位置半径 minRange 内的邻近点都将被忽略,即为盲区
    • borderSize = 1:设置获取深度图像边缘的宽度,默认为 0。如果设置 > 0 ,在裁剪图像时,将在图像周围留下当前视点不可见点的边界

2.3 代码实现(C++)

#include <pcl/range_image/range_image.h>
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/visualization/range_image_visualizer.h>

int main(int argc, char **argv) {
    pcl::PointCloud<pcl::PointXYZ>::Ptr pointCloudPtr(new pcl::PointCloud<pcl::PointXYZ>);
    
    // 智能指针 pointCloudPtr 指向堆内存中的一个点云对象,而传递对象时通常有两种方式:通过值进行传递或通过引用进行传递
        // 1. 值传递方式,要将整个对象从一个地方复制到另一个地方,会产生大量开销,尤其当对象较大时程序运行缓慢
        // 2. 引用的方式,只是将指针所指向的对象暴露出来,不会进行拷贝操作,可提高程序效率
    pcl::PointCloud<pcl::PointXYZ> &pointCloud = *pointCloudPtr; // 使用引用的形式赋值是为了避免拷贝操作,可提高效率

    // 创建一个矩形形状的点云
        // 1.遍历一个立方体的所有点,并将每个点添加到点云对象中。这个立方体的长、宽、高为 1,中心点坐标为(1, 0, 0)
        // 2.最终生成了一个包含 100000 个点的点云对象,其中每个点在以(1, 0, 0)为中心
          // 的 1x1x1 的立方体内,并且在 y-z 平面内均匀分布
    for (float y = -0.5f; y <= 0.5f; y += 0.01f) {
        for (float z = -0.5f; z <= 0.5f; z += 0.01f) {
            pcl::PointXYZ point;
            point.x = 2.0f - y;
            point.y = y;
            point.z = z;
            pointCloud.points.push_back(point); // 循环添加点数据到点云对象
        }
    }
    pointCloud.width = (uint32_t) pointCloud.points.size();
    pointCloud.height = 1;

    // pcl::io::loadPCDFile("./data/table_scene_lms400.pcd", pointCloud);

    // 根据前面得到的点云图,通过 1deg 的分辨率生成深度图

    // 模拟深度传感器的角度分辨率,即深度图像中一个像素对应的角度大小(都转为弧度)
    float angularResolution = (float)(1.0f * (M_PI / 180.0f)); // 弧度 1°
    // 模拟深度传感器的水平最大采样角度(都转为弧度)
    float maxAngleWidth = (float) (360.0f * (M_PI / 180.0f)); // 弧度 360°
    // 模拟传感器的垂直方向最大采样角度(都转为弧度)
    float maxAngleHeight = (float) (180.0f * (M_PI / 180.0f)); // 弧度 180°
    Eigen::Affine3f sensorPose = (Eigen::Affine3f) Eigen::Translation3f(0.0f, 0.0f, 0.0f);  // 传感器采集位置
    pcl::RangeImage::CoordinateFrame coordinate_frame = pcl::RangeImage::CAMERA_FRAME;      // 相机坐标系
    float noiseLevel = 0.00;    // 获取深度图像深度时,近邻点对查询点距离值的影响水平
    float minRange = 0.0f;    // 设置最小的获取距离,小于最小获取距离的位置为传感器的盲区
    int borderSize = 1;    // 获得深度图像的边缘的宽度
    
    // 使用智能指针 boost::shared_ptr 创建一个名为 range_image_ptr 的指向 pcl::RangeImage 对象的指针
    // 同时动态分配内存,该对象可被多个指针共享,直到没有指针引用它时才会自动释放
    boost::shared_ptr<pcl::RangeImage> range_image_ptr(new pcl::RangeImage);
    pcl::RangeImage &rangeImage = *range_image_ptr;

    rangeImage.createFromPointCloud(pointCloud, angularResolution, maxAngleWidth, maxAngleHeight,
                                    sensorPose, coordinate_frame, noiseLevel, minRange, borderSize);
    std::cout << rangeImage << "\n";

    // 3D 可视化操作
    pcl::visualization::PCLVisualizer viewer ("3D Viewer");
    viewer.setBackgroundColor (1, 1, 1);
    // 添加深度图点云
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointWithRange> range_image_color_handler (range_image_ptr, 0, 0, 0);
    viewer.addPointCloud (range_image_ptr, range_image_color_handler, "range image");
    viewer.setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 4, "range image");

    // 添加原始点云
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> org_image_color_handler (pointCloudPtr, 255, 100, 0);
    viewer.addPointCloud (pointCloudPtr, org_image_color_handler, "orginal image");
    viewer.setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "orginal image");

    viewer.initCameraParameters();
    viewer.addCoordinateSystem(1.0);

    // 在可视化窗口中实时显示点云数据,并能够对其进行交互操作。当用户关闭窗口时,循环结束,程序自动退出
    while (!viewer.wasStopped ()) {
        viewer.spinOnce(); // 检查并处理可视化窗口的所有事件(如:鼠标点击、键盘输入等),然后更新可视化窗口的渲染结果
        pcl_sleep(0.01); // 让程序暂停 0.01 秒,这是为了控制循环的速度,防止过快更新可视化窗口导致程序卡死
    }

    return (0);
}
  • 配置文件 CMakeLists.txt

    cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
    
    project(range_image_creation)
    
    find_package(PCL 1.2 REQUIRED)
    
    include_directories(${PCL_INCLUDE_DIRS})
    link_directories(${PCL_LIBRARY_DIRS})
    add_definitions(${PCL_DEFINITIONS})
    
    add_executable (range_image_creation range_image_creation.cpp)
    target_link_libraries (range_image_creation ${PCL_LIBRARIES})
    
  • 编译并执行

    $ mkdir build
    $ cd build
    $ cmake ..
    $ make
    
    $ ./range_image_creation
    
    // 输出结果
    header: 
    seq: 0 stamp: 0 frame_id: 
    points[]: 1360
    width: 40
    height: 34
    sensor_origin_: 0 0 0
    sensor_orientation_: 0 0 0 1
    is_dense: 0
    angular resolution: 1deg/pixel in x and 1deg/pixel in y.
    

在这里插入图片描述

3. 从深度图提取边界

3.1 引言

  • 对三种不同类型的点感兴趣

    • obstacle border:对象边界(属于对象的最外面的可见点)
    • shadow border:阴影边界(在背景中与遮挡物相邻的点)
    • veil points:面纱点集(对象边界与阴影边界之间的内插点)
  • 以下是一个典型的激光雷达获得的 3D 数据对应的点云图
    在这里插入图片描述

3.2 代码实现(C++)

注意事项

  • 要提取边界信息,重点区分未观察到的图像点和应该观察到但超出传感器范围的点。后者通常用来标记边界,而未观察到的点通常不标记边界。因此,最好可以提供这些测量信息。如果无法提供超出这些应该观察到的传感器范围的点,则可以使用 setUnseenToMaxRange 函数,将那些点设置为最大深度(本例添加 -m 参数)
  • range_image_border_extraction.cpp
#include <iostream>

#include <boost/thread/thread.hpp>
#include <pcl/range_image/range_image.h>
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/range_image_visualizer.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/features/range_image_border_extractor.h>
#include <pcl/console/parse.h>
#include <pcl/common/file_io.h>  // for getFilenameWithoutExtension

typedef pcl::PointXYZ PointType;

float angular_resolution = 0.5f;
pcl::RangeImage::CoordinateFrame coordinate_frame = pcl::RangeImage::LASER_FRAME;
// 若为 true,则:将 应该观察到 但超出传感器范围 的点设置为最大深度
bool setUnseenToMaxRange = false; 

// 命令帮助提示
void printUsage (const char* progName) {
    std::cout << "\n\nUsage: "<< progName <<" [options] <scene.pcd>\n\n"
              << "Options:\n"
              << "-------------------------------------------\n"
              << "-r <float>   angular resolution in degrees (default "<< angular_resolution << ")\n"    // 指定角度分辨率的浮点数值,默认值为 angular_resolution
              << "-c <int>     coordinate frame (default "<< (int)coordinate_frame << ")\n"    // 指定坐标系的整数值,默认值为 coordinate_frame
              << "-m           Treat all unseen points to max range\n"    // 将所有未被观察到的点视为最大距离处理
              << "-h           this help\n"    // 输出帮助信息
              << "\n\n";
}

int main (int argc, char** argv) {
    // 解析命令行参数(执行时在 ./range_image_border_extraction.cpp 后添加)
    if (pcl::console::find_argument (argc, argv, "-h") >= 0) {
        printUsage (argv[0]);
        return 0;
    }
    if (pcl::console::find_argument (argc, argv, "-m") >= 0) {
        setUnseenToMaxRange = true;
        cout << "Setting unseen values in range image to maximum range readings.\n";
    }
    int tmp_coordinate_frame;
    if (pcl::console::parse (argc, argv, "-c", tmp_coordinate_frame) >= 0) {
        coordinate_frame = pcl::RangeImage::CoordinateFrame (tmp_coordinate_frame);
        cout << "Using coordinate frame "<< (int)coordinate_frame <<".\n";
    }
    if (pcl::console::parse (argc, argv, "-r", angular_resolution) >= 0)
        cout << "Setting angular resolution to " << angular_resolution << "deg.\n";
    // 将一个以度为单位表示的 角度分辨率值 转换为弧度制的值
    angular_resolution = pcl::deg2rad (angular_resolution);

    // 读取点云 PCD 文件;如果没有输入 PCD 文件就生成一个点云
    pcl::PointCloud<PointType>::Ptr point_cloud_ptr(new pcl::PointCloud<PointType>);
    pcl::PointCloud<PointType> &point_cloud = *point_cloud_ptr;
    pcl::PointCloud<pcl::PointWithViewpoint> far_ranges; // 定义点云中每个点的位置和视角信息
    Eigen::Affine3f scene_sensor_pose(Eigen::Affine3f::Identity ()); // 申明传感器的位置是一个 4*4 的仿射变换
    // 解析命令行参数,并返回所有 .pcd 扩展名的文件的索引列表
    std::vector<int> pcd_filename_indices = pcl::console::parse_file_extension_argument(argc, argv, "pcd");
    if (!pcd_filename_indices.empty()) {
        std::string filename = argv[pcd_filename_indices[0]]; // 保存从命令行参数获取到的第一个 PCD 文件名
        if (pcl::io::loadPCDFile(filename, point_cloud) == -1) {
            cout << "Was not able to open file \"" << filename << "\".\n";
            printUsage(argv[0]);
            return 0;
        }
        // 给传感器的位姿赋值,就是获取点云的传感器的 平移与旋转的向量
            // scene_sensor_pose:相机在场景中的位姿(位置和朝向)
            // Eigen::Affine3f:可以表示平移、旋转等多种变换,并且支持矩阵乘法来组合多个变换
        scene_sensor_pose = Eigen::Affine3f (Eigen::Translation3f (point_cloud.sensor_origin_[0],
                                                                   point_cloud.sensor_origin_[1],
                                                                   point_cloud.sensor_origin_[2])) *
                                             Eigen::Affine3f (point_cloud.sensor_orientation_);
        // 去除文件扩展名,并添加 "_far_ranges.pcd" 来创建输出文件名
        std::string far_ranges_filename = pcl::getFilenameWithoutExtension(filename) + "_far_ranges.pcd";
        if (pcl::io::loadPCDFile(far_ranges_filename.c_str(), far_ranges) == -1)
            std::cout << "Far ranges file \"" << far_ranges_filename << "\" does not exists.\n";
    } else {    // 如果没有读取点云,则要自己生成点云
        cout << "\nNo *.pcd file given => Generating example point cloud.\n\n";
        for (float x = -0.5f; x <= 0.5f; x += 0.01f) {
            for (float y = -0.5f; y <= 0.5f; y += 0.01f) {
                PointType point;
                point.x = x;
                point.y = y;
                point.z = 2.0f - y;
                point_cloud.points.push_back(point);
            }
        }
        point_cloud.width = (int) point_cloud.points.size();
        point_cloud.height = 1;
    }

    // 从创建的原始点云中获取深度图
    float noise_level = 0.0;
    float min_range = 0.0f;
    int border_size = 1;
    // 使用智能指针 boost::shared_ptr 管理内存,确保在不需要该对象时自动释放其占用的空间
    boost::shared_ptr<pcl::RangeImage> range_image_ptr(new pcl::RangeImage);
    pcl::RangeImage &range_image = *range_image_ptr;
    range_image.createFromPointCloud (point_cloud, angular_resolution, pcl::deg2rad(360.0f), pcl::deg2rad(180.0f),
                                      scene_sensor_pose, coordinate_frame, noise_level, min_range, border_size);
    range_image.integrateFarRanges(far_ranges); // 将远处的距离数据合并到深度图像中对应的位置上,以提高远处物体的检测效果
    // 将所有未被观测到的点的值设置为距离图像中已知距离的最大值
        // 避免在后续的处理或分析过程中出现未知的距离值所带来的问题
    if (setUnseenToMaxRange)
        range_image.setUnseenToMaxRange();

    // 设置点云可视化
    pcl::visualization::PCLVisualizer viewer("3D Viewer");
    viewer.setBackgroundColor(1, 1, 1);
    viewer.addCoordinateSystem(1.0f, "global");
    // 创建一个自定义的点云颜色处理器,用于将点云数据中的每个点赋予相同的黑色颜色
    pcl::visualization::PointCloudColorHandlerCustom<PointType> point_cloud_color_handler(point_cloud_ptr, 0, 0, 0);
    // 将点云数据加入到场景中,并使用上述颜色处理器使其呈现黑色
    viewer.addPointCloud(point_cloud_ptr, point_cloud_color_handler, "original point cloud");
    //PointCloudColorHandlerCustom<pcl::PointWithRange> range_image_color_handler(range_image_ptr, 150, 150, 150);
    //viewer.addPointCloud(range_image_ptr, range_image_color_handler, "range image");
    //viewer.setPointCloudRenderingProperties(PCL_VISUALIZER_POINT_SIZE, 2, "range image");

    // 提取深度图边界
    pcl::RangeImageBorderExtractor border_extractor(&range_image); // 从深度图像或距离图像中提取边界信息
    pcl::PointCloud<pcl::BorderDescription> border_descriptions; // 用于存储每个点是否是 边界点及其边界类型 的信息
    border_extractor.compute(border_descriptions);

    // 在 3D viewer 中显示点云
    // pcl::PointWithRange 存储了每个点的三维坐标 xyz 和距离信息 range
    pcl::PointCloud<pcl::PointWithRange>::Ptr border_points_ptr(new pcl::PointCloud<pcl::PointWithRange>),
                                              veil_points_ptr(new pcl::PointCloud<pcl::PointWithRange>),
                                              shadow_points_ptr(new pcl::PointCloud<pcl::PointWithRange>);
    pcl::PointCloud<pcl::PointWithRange> &border_points = *border_points_ptr,
                                         &veil_points = * veil_points_ptr,
                                         &shadow_points = *shadow_points_ptr;

    // 从给定的 border_descriptions 中提取特定属性的点,并将这些点分别存储到三个不同的 PointCloud 中
    // 使用双重循环遍历整个 range_image,在每个像素位置 (x, y) 处检查该位置的点是否具有特定的边界属性
    for (int y = 0; y < (int)range_image.height; ++y) {
        for (int x = 0; x < (int)range_image.width; ++x) {
            /*
            首先,通过 border_descriptions.points[y * range_image.width + x] 访问像素点(x, y)对应的边界特征
            然后,使用 pcl::BORDER_TRAIT__OBSTACLE_BORDER 常量进行比较,判断该像素点是否具有障碍物边界特征
            如果是,则通过 range_image.points[y * range_image.width + x] 获取该像素点对应的三维点,并添加到 border_points 容器中
                1. border_descriptions:表示边界描述的容器,其中包含了每个像素点的边界特征
                2. range_image:表示一个基于深度图的三维点云数据结构,其中每个像素点对应于一个三维空间中的点
                3. x 和 y:表示像素点的坐标
                4. pcl::BORDER_TRAIT__OBSTACLE_BORDER:表示障碍物边界特征的枚举常量
            */
            if (border_descriptions.points[y * range_image.width + x].traits[pcl::BORDER_TRAIT__OBSTACLE_BORDER])
                border_points.points.push_back(range_image.points[y * range_image.width + x]);
            if (border_descriptions.points[y * range_image.width + x].traits[pcl::BORDER_TRAIT__VEIL_POINT])
                veil_points.points.push_back(range_image.points[y * range_image.width + x]);
            if (border_descriptions.points[y * range_image.width + x].traits[pcl::BORDER_TRAIT__SHADOW_BORDER])
                shadow_points.points.push_back(range_image.points[y * range_image.width + x]);
        }
    }

    // 分别设置三种类型点云可视化
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointWithRange> border_points_color_handler (border_points_ptr, 0, 255, 0);
    viewer.addPointCloud<pcl::PointWithRange> (border_points_ptr, border_points_color_handler, "border points");
    viewer.setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 7, "border points");

    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointWithRange> veil_points_color_handler (veil_points_ptr, 255, 0, 0);
    viewer.addPointCloud<pcl::PointWithRange> (veil_points_ptr, veil_points_color_handler, "veil points");
    viewer.setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 7, "veil points");

    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointWithRange> shadow_points_color_handler (shadow_points_ptr, 0, 255, 255);
    viewer.addPointCloud<pcl::PointWithRange> (shadow_points_ptr, shadow_points_color_handler, "shadow points");
    viewer.setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 7, "shadow points");

    // 在深度图中显示点云
    pcl::visualization::RangeImageVisualizer *range_image_borders_widget = NULL;
                                            // 要显示的距离图像,显示范围的最小值,显示范围的最大值(返回 float 类型的正无穷大)
                                            // 是否应该在边框上显示描述信息,可选的边框描述信息,显示窗口的名称
    range_image_borders_widget = pcl::visualization::RangeImageVisualizer::getRangeImageBordersWidget
                                                 (range_image, -std::numeric_limits<float>::infinity(), 
                                                  std::numeric_limits<float>::infinity(), false,
                                                  border_descriptions, "Range image with borders");

    while (!viewer.wasStopped ()) {
        range_image_borders_widget->spinOnce();
        viewer.spinOnce ();
        pcl_sleep(0.01);
    }
}
  • 配置文件 CMakeLists.txt

    cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
    
    project(range_image_border_extraction)
    
    find_package(PCL 1.3 REQUIRED)
    
    include_directories(${PCL_INCLUDE_DIRS})
    link_directories(${PCL_LIBRARY_DIRS})
    add_definitions(${PCL_DEFINITIONS})
    
    add_executable (range_image_border_extraction range_image_border_extraction.cpp)
    target_link_libraries (range_image_border_extraction ${PCL_LIBRARIES})
    
  • 编译并执行

    $ mkdir build
    $ cd build
    $ cmake ..
    $ make
    
    $ ./range_image_border_extraction -m table_scene_lms400.pcd # 使用 -m 设置传感器看不见的位置
    

在这里插入图片描述

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

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

相关文章

使用 SaleSmartly 实时聊天提高转化率

在竞争激烈的电子商务环境中&#xff0c;很难给客户留下持久的印象&#xff0c;与他们建立关系更加困难。但是&#xff0c;提供个性化的体验和产品是超越竞争对手的最佳方式之一。这就是为什么许多跨境电子商务企业将与客户的个性化沟通作为他们的首要任务。 SaleSmartly&#…

JVM原理与实战(一)

jvm的基本结构 1.类加载系统 负责从文件系统或者网络中加载Class信息 2.方法区 &#xff08;1&#xff09;加载的类信息存放于一块称为方法去的内存空间 &#xff08;2&#xff09;除了类的信息外&#xff0c;方法区中可能还存放着运行时常量池信息&#xff0c;包括字符串字面…

PyQt5桌面应用开发(8):从QInputDialog转进到函数参数传递

本文目录 PyQt5桌面应用系列How old are you, Dialog?QInputDialog minimalistwhy not lambdaand how partial worksSummary PyQt5桌面应用系列 PyQt5桌面应用开发&#xff08;1&#xff09;&#xff1a;需求分析 PyQt5桌面应用开发&#xff08;2&#xff09;&#xff1a;事件…

HTML购物车示例(勾选、删除、添加和结算功能)

以下是一个简单的HTML购物车示例&#xff0c;包含勾选、删除、添加和结算功能。结算功能使用PHP实现&#xff0c;可以获取选中商品的ID。 以下是一个简单的HTML购物车示例&#xff0c;包含勾选、删除、添加和结算功能。结算功能使用PHP实现&#xff0c;可以获取选中商品的ID以下…

Linux下安装Redis

下载 方式一&#xff1a;官网下载稳定版本&#xff0c;然后FTP上传至服务器 https://download.redis.io/releases/ 方式二&#xff1a;服务器内使用wget下载&#xff08;想下其它版本可参考上图&#xff0c;更改命令后缀版本即可&#xff09; wget http://download.redis.i…

2.基础篇

目录 一、描述软件测试的生命周期&#xff08;软件测试的流程&#xff09; 二、如何描述一个bug 三、bug的级别&#xff08;粗略划分&#xff09; 四、bug的生命周期 五、因为一个bug和开发人员产生争执怎么办 六、如何设置弱网&#xff1f; 一、描述软件测试的生命周期&a…

Flex弹性布局

文章目录 1. 开启Flex布局2. 应用于flex container的css属性flex-directionjustify-contentalign-itemsflex-wrapflex-flowalign-content 3. 应用于flex items的css属性orderflex-growflex-shrinkflex-basis&#xff08;了解&#xff09;align-selfflex 1. 开启Flex布局 flex c…

校招推荐学习java开发还是大数据开发

这两个方向其实都是不错的方向&#xff0c;java虽然卷&#xff0c;但是技能在手也不怕。大数据的发展前景也是不容小觑的。关键就在于你未来想发展的方向以及个人的兴趣 首先可以肯定的是&#xff0c;市场上终归是需要Java人才的&#xff0c;但是总会有人来问&#xff0c;Java…

对偶问题和KKT条件

KKT条件 对于不等式约束优化问题 min ⁡ f ( x ) s . t . g ( x ) ≤ 0 \min\quad f(x)\\ {\rm s.t.}\quad g(x)\leq 0 minf(x)s.t.g(x)≤0 拉格朗日函数为 L ( x , λ ) f ( x ) λ g ( x ) L(x,\lambda)f(x)\lambda g(x) L(x,λ)f(x)λg(x) 。 KKT条件包括 拉格朗日函…

分享5款轻量级的Win10神器,错过你会后悔的

今天我要为大家推荐五款小众而且小体积的WIN10小工具&#xff0c;它们可以让你的电脑使用更加方便和高效&#xff0c;而且不占用太多的空间和资源&#xff0c;非常适合轻量级的办公和娱乐。 1.窗口管理工具——TileIconifier TileIconifier可以将窗口最小化到托盘区域,从而更…

在Android应用中集成使用traceroute工具

背景知识 traceroute是一个常用于Linux系统的网络工具&#xff0c;它可显示数据包在IP网络中所经过路由的IP地址&#xff0c;理想状态下可探测本机和目标地址之间的所有路由节点。 其他操作系统中也有类似的替代品&#xff0c;实现都大同小异。一般用法如下&#xff1a; 终端…

【TCP为什么需要粘包和拆包】

如今&#xff0c;大半个互联网都建立在 TCP 协议之上&#xff0c;我们使用的 HTTP 协议、消息队列、存储、缓存&#xff0c;都需要用到 TCP 协议——这是因为 TCP 协议提供了可靠性。简单来说&#xff0c;可靠性就是让数据无损送达。但若是考虑到成本&#xff0c;就会变得非常复…

一文带你理解SpringBean

Bean定义 ​ Bean作为Spring框架面试中不可或缺的概念&#xff0c;其本质上是指代任何被Spring加载生成出来的对象。&#xff08;本质上区别于Java Bean&#xff0c;Java Bean是对于Java类的一种规范定义。&#xff09;Spring Bean代表着Spring中最小的执行单位&#xff0c;其…

如何用ApiFox自动生成接口文档?没有比这更详细的教程了

目录 前言 第一步&#xff1a;安装 Apifox IDEA 插件&#xff08;Apifox Helper&#xff09; 第二步&#xff1a;配置 Apifox 访问令牌 和项目 ID 第三步&#xff1a;自动生成文档&#xff01; 第四步&#xff1a;去 Apifox 项目中查看自动生成的文档 Apifox 更多好用的功能…

Addictive Multiplicative in NN

特征交叉是特征工程中的重要环节&#xff0c;在以表格型&#xff08;或结构化&#xff09;数据为输入的建模中起到了很关键的作用。 特征交互的作用&#xff0c;一是尽可能挖掘对目标有效的模式、特征&#xff0c;二是具有较好的可解释性&#xff0c;三是能够将对数据的洞见引…

一文教会你如何重装Windows10系统【过程+图解+说明】

前言 申请了一台台式机电脑&#xff0c;操作系统是windows11的&#xff0c;要windows10的系统。电脑不能连网&#xff0c;身为程序员&#xff0c;我竟然想着别人远程帮我安装&#xff0c;可恶呐。之前也没重装过系统。第一次重装遇到了一些坑。我甚至在拼夕夕上花了几块钱买个镜…

python-使用Qchart总结5-使用信号槽绘制动态曲线图

python-使用Qchart总结3-绘制曲线图在这篇文章基础上&#xff0c;来改造一下&#xff0c;绘制一下动态曲线图吧 一、明确需求 ①点击按钮&#xff0c;开始动态加载曲线&#xff0c;细节:一个一个点加载出来 二、实现 ①在UI上添加按钮&#xff0c;打开原先的untitled.ui文件…

【Linux】浅谈eloop机制

目录 1.eloop 机制 2.eloop结构体 2.1.eloop_data结构体 2.2 Socket事件结构体 2.3 Timeout事件结构体 2.4 Signal事件结构体 3.eloop_init 4.eloop_run 4.1 signal事件 4.2 socket事件 4.3 timeout事件 1.eloop 机制 主线程中启动事件监听机制&#xff0c;对不同的…

【Python入门】字符串的扩展

前言 &#x1f4d5;作者简介&#xff1a;热爱跑步的恒川&#xff0c;致力于C/C、Java、Python等多编程语言&#xff0c;热爱跑步&#xff0c;喜爱音乐的一位博主。 &#x1f4d7;本文收录于Python零基础入门系列&#xff0c;本专栏主要内容为Python基础语法、判断、循环语句、函…

Nginx介绍及安装

简介 Nginx 是一个高性能的 HTTP 和反向代理服务器。它最初由 Nigel Cook 开发&#xff0c;旨在解决 Apache 服务器在高并发环境下性能瓶颈的问题。Nginx 具有占用资源少、处理能力强等优点&#xff0c;在互联网应用中广泛应用于静态资源服务、反向代理、负载均衡、HTTP缓存、…