上手一个RGBD深度相机:从原理到实践--ROS noetic+Astra S(上):解读深度测距原理和内外参推导

news2024/9/20 0:19:02

前言

  • 最近在做项目的时候,项目组丢给了我一个深度相机,今天我们来尝试上手一个实体深度相机。请添加图片描述

  • 本教程设计基础相机的原理,使用,标定,和读取。(注:本教程默认大家有ROS1基础,故不对程序进行详细解释)

  • 本教程使用的环境

    • ubuntu 20.04 LTS ROS1 noetic
    • Astra S

产品基础参数

  • 根据摄像机背后所贴的标签,顺藤摸瓜的爬到Orbbec公司的官网,以下是Astra系列3D摄像头的介绍,大致是一系列的介绍(这里我拿到手的是Astra S(short-range)小范围的深度相机)请添加图片描述

  • 往下翻可以看到相机的具体参数请添加图片描述

  • 分为两个部分:摄像头规格(Camera Specifications)和物理参数(Physical Parameters)。以下是具体内容:

    • 摄像头规格(Camera Specifications)
      1. 深度技术:该摄像头采用结构光(Structured Light)技术来获取深度信息。
      2. 波长:摄像头使用850nm的波长进行深度感应。
      3. 深度范围:摄像头能够感应到的深度范围是0.6米到8米,对于S型号,这个范围是0.4米到2米。(short-range)
      4. 深度分辨率/帧率:摄像头能够提供的最高深度分辨率为640x480,帧率为30fps。
      5. 深度视场角:摄像头的深度视场角为水平58.4度,垂直45.5度。
      6. RGB分辨率/帧率:Pro Plus版摄像头的RGB分辨率为1920x1080,帧率为30fps,而其他版本的分辨率为640x480,帧率为30fps。
      7. RGB视场角:Pro Plus版摄像头的RGB视场角为水平66.1度,垂直40.2度,其他版本为水平63.1度,垂直49.4度。
      8. 处理芯片:摄像头使用的是Orbec ASIC处理芯片。
      9. IMU:该摄像头没有配备IMU(惯性测量单元)。
    • 物理参数(Physical Parameters)
      1. 数据连接:摄像头通过USB 2.0 Type-A接口进行数据连接。
      2. 电源输入:摄像头的电源输入也是通过USB 2.0 Type-A接口。
      3. 触发器:该摄像头没有配备触发器功能。
      4. 功耗:摄像头的平均功耗小于2.4瓦。
      5. 工作环境:摄像头适用于10°C到40°C的室内环境,湿度范围为10%到85%。
      6. SDK支持:摄像头支持Orbbec OpenNI SDK。
      7. 数据输出:摄像头能够输出点云、深度图、红外或RGB数据。
      8. 尺寸(宽_高_深):摄像头的尺寸为165毫米 x 48毫米 x 40毫米。
      9. 重量:摄像头的重量为310克。
      10. 安装方式:摄像头的底部有M6螺丝孔,用于安装。

原理

  • 上述产品参数中,有一条比较有意思,深度技术:该摄像头采用结构光(Structured Light)技术来获取深度信息。那啥是结构光呢,这个相机如何利用结构光来获取深度呢,这小节我们来看看。
RGBD:RGB+D
  • 我们先来理解RGBD深度相机,RGBD相机,也称为彩色深度相机或三维相机,是一种结合了传统RGB成像和深度信息捕捉功能的设备。它能够同时输出两个数据流:一个是普通的彩色图像(RGB图像),另一个是深度图(Depth Map),其中包含了场景中每个点的深度信息。
  • RGBD相机的核心组件通常包括:
    1. 彩色摄像头:用于捕捉场景的RGB图像,提供颜色的信息。
    2. 深度传感器:用于捕捉场景的深度信息。这可以通过多种技术实现,如结构光、飞行时间(ToF)、立体视觉或激光雷达等。
    3. 如下图我收到的这个RGBD相机为例子请添加图片描述
  • 深度相机通常使用以下几种技术来测量深度:
    1. 结构光技术:通过向场景投射特定的光图案(如条纹或点阵),然后分析这些图案在场景表面的变形来计算深度。后面我们重点分析。
    2. 飞行时间(Time-of-Flight, ToF)技术:通过测量光从相机发出,照射到场景中的物体并反射回相机的飞行时间来计算深度。(说人话就是计算光飞了多久,换算成距离深度)请添加图片描述
    3. 立体视觉(Stereo Vision):使用两个或多个摄像头从不同的角度拍摄同一场景,通过比较不同视角下的图像来确定深度。(包括对两张图像的角点提取,特征点匹配)请添加图片描述
    4. 激光雷达(Lidar):使用激光束来测量从发射到反射回来的时间,或者通过分析激光束的相位变化来计算深度。(这个不用多说了吧)
结构光Structured Light
  • 这里我们详细看一下这个摄像头用到的技术,我们来看维基百科对他的定义请添加图片描述
  • 翻译:结构光是一种深度感测技术,它将已知图案(通常是网格或水平条)投影到场景上。当这些图案撞击表面时,它们发生变形的方式使得视觉系统能够计算场景中物体的深度和表面信息,这被用于结构光3D扫描仪中。来张图你就懂了请添加图片描述
  • 结构光类型分为线结构光面结构光:
    1. 线结构光通过向物体表面投射一条或多条线形光束,然后捕捉这些光线在物体表面的变形。(通过机械结构改变扫描角度,可以理解成行扫描)
    2. 面结构光通过向物体表面投射一个或多个面状光图案(如网格或点阵),然后捕捉这些图案在物体表面的变形。
  • 面结构光又分为正弦曲线光栅条纹组(Sinusoidal Grating Stripes)和格雷码形式(Gray Code Pattern):
    • 正弦曲线光栅条纹是一种周期性变化的条纹图案,其亮度和位置随着正弦函数变化。通过捕捉这些条纹在物体表面的变形,可以计算出物体的三维形状。(高中死去的知识)请添加图片描述

    • 也就是上面那个图,通过根据相位差和周期可以计算出深度信息请添加图片描述

    • 请添加图片描述

    • 格雷码是一种特殊的二进制编码方式,其中连续的码字之间只有一个比特的差异。在三维扫描中,格雷码光图案通常由多个不同的图案组成,每个图案代表格雷码的一个码字。通过比较不同图案的变形,可以计算出物体的三维形状。


ros_astra_camera的使用

其他SDK(不使用)
  • 在官网所提供的购买链接右下方,我们可以看到官方提供的SDK请添加图片描述
    请添加图片描述

  • 值得一提的是本人试过其他官方提供的几个ROS的SDK,OrbbecSDK_ROS2和OrbbecSDK_ROS1,但是都出现了多多少少的问题:

    • OrbbecSDK_ROS2并不支持Astra S这个相机请添加图片描述

    • OrbbecSDK_ROS1我试图配置了但是无法激活相机(这个存疑)

ros_astra_camera
  • ros_astra_camera 是一个为 Orbbec 3D 相机创建的 OpenNI2 ROS 包装器。这个软件包允许在 ROS Kinetic、Melodic 和 Noetic 发行版中使用 Orbbec 3D 相机。通过这个包装器,用户可以在 ROS 环境中方便地使用 Orbbec 相机的三维扫描功能,获取深度信息和彩色图像。链接:ros_astra_camera请添加图片描述
配置以及依赖安装
  • 根据这个功能包的README.md,我们来配置使用
  1. 安装必要依赖
sudo apt install libgflags-dev  ros-$ROS_DISTRO-image-geometry ros-$ROS_DISTRO-camera-info-manager\
ros-$ROS_DISTRO-image-transport ros-$ROS_DISTRO-image-publisher  libusb-1.0-0-dev libeigen3-dev
ros-$ROS_DISTRO-backward-ros libdw-dev
  1. 安装libuvc:libuvc 是一个开源的 USB 视频类 (UVC) 设备的跨平台库,它提供了一个用户空间接口来访问 UVC 设备。UVC 是 USB 设备类定义的一部分,它允许计算机通过 USB 接口与视频捕捉设备(如网络摄像头、USB 摄像头等)进行通信。
git clone https://github.com/libuvc/libuvc.git
cd libuvc
mkdir build && cd build
cmake .. && make -j4
sudo make install
sudo ldconfig
  1. 新建一个工作空间并进入
mkdir -p ~/ros_ws/src
cd ~/ros_ws/src
  1. 拉取仓库(没安装git的朋友sudo apt install git就行了)
git clone https://github.com/orbbec/ros_astra_camera.git
  1. 安装udev规则:udev 是一个设备管理器,用于在 Linux 系统中管理设备文件。udev 规则(udev rules)是用于定义如何创建和管理设备节点的配置文件。这些规则通常位于 /etc/udev/rules.d/ 目录下,并以 .rules 为文件扩展名。
cd ~/ros_ws
source ./devel/setup.bash
roscd astra_camera
./scripts/create_udev_rules
sudo udevadm control --reload && sudo  udevadm trigger
启动
  • 在正式启动前,我们检查相机已经连接
source ./devel/setup.bash 
roslaunch astra_camera list_devices.launch  

请添加图片描述

  • 进入工作空间,打开一个终端,启动相机
source ./devel/setup.bash 
roslaunch astra_camera astra.launch
  • 看到终端输出: Start device done就说明摄像头启动成功(这一步如果有报错的朋友根据报错去launch中修正相机参数,我这里使用的Astra S可以直接启动)请添加图片描述

  • 我们另外开启一个终端,开启rviz(没安装的朋友记得sudo apt install ros-noetic-rviz)

source ./devel/setup.bash 
rviz
  • 点击Add添加组件,选择By topic ,我们就能看到基本信息了请添加图片描述

  • 这里我们选择image组件,分别添加/camera/color/image_raw和/camera/depth/image_raw请添加图片描述

  • 你就可以看到相机的画面和深度信息了请添加图片描述

  • 同理我们选择点云信息 请添加图片描述

  • 这里我们选择固定坐标系为camera_link,就可以看到深度信息的点云信息了请添加图片描述


astra.launch 分析

  • 我们来看看launch文件
<launch>
    <!-- unique camera name-->
    <arg name="camera_name" default="camera"/>
    <!-- Hardware depth registration -->
    <arg name="depth_align" default="false"/>
    <arg name="depth_scale" default="1"/>
    <arg name="serial_number" default=""/>
    <arg name="device_num" default="1"/>
    <arg name="vendor_id" default="0x2bc5"/>
    <arg name="product_id" default=""/>
    <arg name="enable_point_cloud" default="true"/>
    <arg name="enable_point_cloud_xyzrgb" default="false"/>
    <arg name="connection_delay" default="100"/> 
    <arg name="color_width" default="640"/>
    <arg name="color_height" default="480"/>
    <arg name="color_fps" default="30"/>
    <arg name="enable_color" default="true"/>
    <arg name="flip_color" default="false"/>
    <arg name="color_format" default="RGB"/>
    <arg name="depth_width" default="640"/>
    <arg name="depth_height" default="480"/>
    <arg name="depth_fps" default="30"/>
    <arg name="enable_depth" default="true"/>
    <arg name="flip_depth" default="false"/>
    <arg name="depth_format" default="Y11"/>
    <arg name="ir_width" default="640"/>
    <arg name="ir_height" default="480"/>
    <arg name="ir_fps" default="30"/>
    <arg name="enable_ir" default="true"/>
    <arg name="ir_format" default="Y10"/>
    <arg name="flip_ir" default="false"/>
    <arg name="publish_tf" default="true"/>
    <arg name="tf_publish_rate" default="10.0"/>
    <arg name="ir_info_uri" default=""/>
    <arg name="color_info_uri" default=""/>
    <arg name="color_depth_synchronization" default="false"/>
    <arg name="oni_log_level" default="verbose"/>
    <arg name="oni_log_to_console" default="false"/>
    <arg name="oni_log_to_file" default="false"/>
    <arg name="enable_d2c_viewer" default="false"/>
    <arg name="enable_publish_extrinsic" default="false"/>
    <!-- software filter 0-off ,1-on (default,support windows/linux/arm/
    ,not support android),2 - Optimized software filtering algorithm,support windows/linux/arm/android-->
    <arg name="soft_filter" default="2"/>
    <!-- software filter param MaxDiff (default 16)-support when SoftFilter =2 -->
    <arg name="soft_filter_max_diff" default="16"/>
    <!-- software filter param maxSpeckleSize -support when SoftFilter =2-->
    <arg name="soft_filter_max_speckle_size" default="480"/>
    <group ns="$(arg camera_name)">
        <node name="camera" pkg="astra_camera" type="astra_camera_node" output="screen">
            <param name="camera_name" value="$(arg camera_name)"/>
            <param name="depth_align" value="$(arg depth_align)"/>
            <param name="depth_scale" value="$(arg depth_scale)"/>
            <param name="serial_number" type="string" value="$(arg serial_number)"/>
            <param name="device_num" value="$(arg device_num)"/>
            <param name="vendor_id" value="$(arg vendor_id)"/>
            <param name="product_id" value="$(arg product_id)"/>
            <param name="enable_point_cloud" value="$(arg enable_point_cloud)"/>
            <param name="enable_point_cloud_xyzrgb" value="$(arg enable_point_cloud_xyzrgb)"/>
            <param name="connection_delay" value="$(arg connection_delay)"/>
            <param name="color_width" value="$(arg color_width)"/>
            <param name="color_height" value="$(arg color_height)"/>
            <param name="color_fps" value="$(arg color_fps)"/>
            <param name="enable_color" value="$(arg enable_color)"/>
            <param name="color_format" value="$(arg color_format)"/>
            <param name="flip_color" value="$(arg flip_color)"/>
            <param name="depth_width" value="$(arg depth_width)"/>
            <param name="depth_height" value="$(arg depth_height)"/>
            <param name="depth_fps" value="$(arg depth_fps)"/>
            <param name="flip_depth" value="$(arg flip_depth)"/>
            <param name="enable_depth" value="$(arg enable_depth)"/>
            <param name="depth_format" value="$(arg depth_format)"/>
            <param name="ir_width" value="$(arg ir_width)"/>
            <param name="ir_height" value="$(arg ir_height)"/>
            <param name="ir_fps" value="$(arg ir_fps)"/>
            <param name="enable_ir" value="$(arg enable_ir)"/>
            <param name="flip_ir" value="$(arg flip_ir)"/>
            <param name="ir_format" value="$(arg ir_format)"/>
            <param name="publish_tf" value="$(arg publish_tf)"/>
            <param name="tf_publish_rate" value="$(arg tf_publish_rate)"/>
            <param name="ir_info_uri" value="$(arg ir_info_uri)"/>
            <param name="color_info_uri" value="$(arg color_info_uri)"/>
            <param name="color_depth_synchronization" value="$(arg color_depth_synchronization)"/>
            <param name="oni_log_level" value="$(arg oni_log_level)"/>
            <param name="oni_log_to_console" value="$(arg oni_log_to_console)"/>
            <param name="oni_log_to_file" value="$(arg oni_log_to_file)"/>
            <param name="enable_d2c_viewer" value="$(arg enable_d2c_viewer)"/>
            <param name="enable_publish_extrinsic" value="$(arg enable_publish_extrinsic)"/>
            <param name="soft_filter" value="$(arg soft_filter)"/>
            <param name="soft_filter_max_diff" value="$(arg soft_filter_max_diff)"/>
            <param name="soft_filter_max_speckle_size" value="$(arg soft_filter_max_speckle_size)"/>
            <remap from="/$(arg camera_name)/depth/color/points" to="/$(arg camera_name)/depth_registered/points"/>
        </node>
    </group>
</launch>

  • 这里分析具体参数
  • connection_delay: 重新打开设备的延迟时间,以毫秒为单位。
  • enable_point_cloud: 是否启用点云。
  • enable_point_cloud_xyzrgb: 是否启用RGB点云。
  • enable_d2c_viewer: 发布D2C叠加图像(仅用于测试)
  • device_num: 设备数量。使用多个相机时,需要指定设备数量。
  • enable_reconfigure: 是否启用ROS动态配置更改,设置为false表示Astra.cfg配置将不起作用。这仅建议用于测试目的。使用时请关闭。
  • color_widthcolor_heightcolor_fps: 彩色流分辨率和帧率。
  • ir_widthir_heightir_fps:IR流分辨率和帧率。(IR 是 “Infrared” 的缩写,中文意思是红外线。)
  • depth_widthdepth_heightdepth_fps: 深度流分辨率和帧率。
  • enable_color: 是否启用RGB相机。当RGB相机使用UVC协议时,此参数无效。
  • enable_depth: 是否启用深度相机。
  • enable_ir: 是否启用IR相机。
  • depth_align: 启用硬件深度到颜色的对齐,启用RGB点云时需要。
  • depth_scale: 深度图像缩放比例。例如,将其设置为2意味着将大小为320x240的深度图像对齐到大小为640x480的RGB图像。
  • color_roi_xcolor_roi_ycolor_roi_widthcolor_roi_height: 是否裁剪RGB图像。默认为-1,仅在RGB分辨率大于深度分辨率且需要对齐时使用。例如,如果需要将大小为640x400的深度图像与大小为640x480的RGB图像对齐,则需要将color_roi_x设置为0,color_roi_y设置为0,color_roi_width设置为640,color_roi_height设置为400。这将裁剪RGB图像的顶部400像素,与相应的深度ROI对齐。
  • color_depth_synchronization,启用RGB与深度的同步
  • use_uvc_camera: 如果RGB相机使用UVC协议,则将此参数设置为true。UVC是当前包括Dabai,Dabai_dcw等的协议。
  • uvc_product_id:UVC相机的PID。
  • uvc_camera_format:UVC相机的图像格式。
  • uvc_retry_count : 有时UVC协议相机在热插拔时无法成功重新连接,需要多次重试。
  • enable_publish_extrinsic 启用发布相机外参。
  • oni_log_level: OpenNI的日志级别:详细,信息,警告,错误或无。
  • oni_log_to_console, 是否将OpenNI日志输出到控制台。
  • oni_log_to_file: 是否将OpenNI日志输出到文件。默认情况下,它将保存在当前运行程序的路径下的Log文件夹中。 针对特殊客户需求:
  • keep_alive, 是否向固件发送心跳包。默认不启用。
  • keep_alive_interval, 发送心跳包的时间间隔,以秒为单位。

内外参

内参矩阵原理推导
  • 这里我们来推导是相机内参矩阵,来个问题,什么是相机呢。相机是一种现实3维世界在相机2维屏幕上的一个映射,具体关系可以这样表示请添加图片描述

  • 我们假设2D摄像机的点为[X,Y,Z],其中Z表示这个像素点(X,Y)对应的深度信息,由此我们推断出相机矩阵是一个3✖4的矩阵请添加图片描述

  • 摄像机的焦距 𝑓 是指从摄像机镜头的光学中心到成像平面的距离,这个成像平面通常位于摄像机的图像传感器上。

  • 对于相机上的点,我们可以通过三角关系得出下述关系

  • 请添加图片描述

  • 反解上述矩阵,我们有得到P的表达式,如下

  • 请添加图片描述

  • 考虑到现实中成像的图像和真实摄像机的终点存在偏移(焦距是摄像头中点计算的)

  • 请添加图片描述

  • 我们假设相对偏移量为(px,py),那么我们来修正P矩阵

  • 请添加图片描述

  • 这里我们先假设相机坐标系和世界坐标系不存在偏移,二者是重合的,我们把P继续进行拆分请添加图片描述

  • 其中[I∣0]是一个特定的4×4齐次变换矩阵。这个矩阵由两部分组成:
    请添加图片描述

    • 左上角的3×3部分是单位矩阵 I,表示没有旋转。
    • 右上角的3×1部分是零向量 0,表示没有沿x、y、z轴的平移。
  • 在齐次坐标下,这个矩阵代表了一个没有旋转和没有平移的变换。它通常用于表示从世界坐标系到摄像机坐标系的变换,其中摄像机和世界坐标系是重合的。

  • 在这种情况下,摄像机内参矩阵 K 直接映射世界坐标系中的点到图像平面上,而不需要考虑任何旋转或平移。

  • 这时候我们就推导出了相机的内参矩阵

  • 请添加图片描述

进一步考虑
  • 现在我们考虑到摄像机,图像,世界坐标系存在偏差(开始头疼辣)请添加图片描述
  • 这里我们来换算摄像机光心C点(即摄像机的光学中心)在世界坐标系中的位置。我们需要分别计算旋转和平移来得出变换式子
  1. 我们先来计算偏移量,可以看出现实中的一点相对于光心的偏移量是Xc,而相当于世界坐标系的偏移量是Xw,我们可以得到偏移量是Xw-C请添加图片描述

  2. 我们来看旋转,我们定义R来表示旋转请添加图片描述

  3. 如此一来我们得到二者的相对关系
    请添加图片描述
    4.这时候我们可以通过这个关系式子,将世界坐标系中的一个点通过旋转和平移操作转换到相机坐标系中。
    请添加图片描述

  • 至此我们得到最终答案
    请添加图片描述
  • 其中 𝑃 是一个 3x4 的投影矩阵。
  • 𝐾 代表相机的内参(intrinsic parameters),通常是一个 3x3 矩阵。
  • 𝑅 代表旋转矩阵(rotation matrix),也是一个 3x3 的矩阵。
  • [𝐼] 表示单位矩阵(identity matrix)。
  • 𝐶 是相机中心向量,表示为列向量。
内参矩阵通解
  • 合并上述推导,我们得到一般式子请添加图片描述
外参
  • 外参(Extrinsic Parameters)在计算机视觉和机器人学中指的是描述摄像机相对于世界坐标系的位置和方向的参数。这些参数通常包括一个旋转矩阵(Rotation Matrix)和一个平移向量(Translation Vector)。外参定义了摄像机坐标系与世界坐标系之间的坐标变换关系。
  • 这下懂了吧(就是上头的R和t),好!懂的明明白白

标定

  • 相机标定(Camera Calibration)是计算机视觉中的一个基本步骤,其目的是确定相机的内参(internal parameters)和可能的外参(external parameters)。内参包括焦距(focal length)、主点(principal point)、畸变系数(distortion coefficients)等,而外参则包括相机的位置和方向。
  • 在ros_astra_camera中,我们可以添加标定的结果到启动文件
<launch>
    <!--...-->
    <arg name="ir_info_uri" default="file:///you_ir_camera_calib_path/depth_camera.yaml"/>
    <arg name="color_info_uri" default="file:///you_depth_camera_calib_path/rgb_camera.yaml"/>
    <!--...-->
</launch>
  • 标定的文件大致长这样
image_width: 640
image_height: 480
# The camera name is fixed. The color camera is rgb_camera, the depth/IR camera name is ir_camera
camera_name: rgb_camera
camera_matrix:
  rows: 3
  cols: 3
  data: [517.301, 0, 326.785, 0, 519.291, 244.563, 0, 0, 1]
distortion_model: plumb_bob
distortion_coefficients:
  rows: 1
  cols: 5
  data: [-0.41527, 0.31874, -0.00197, 0.00071, 0]
rectification_matrix:
  rows: 3
  cols: 3
  data: [0.999973, 0.00612598, -0.00406652, -0.00610201, 0.999964, 0.00588094, 0.0041024, -0.00585596, 0.999974 ]
projection_matrix:
  rows: 3
  cols: 4
  data: [517.301, 0, 326.785, -25.3167, 0, 519.291, 244.563, 0.282065, 0, 0, 1, 0.0777703]

小结

  • 本节完完整整的推导了内外参的由来,下一节标定就简单了
  • 如有错误,欢迎指出!!!

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

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

相关文章

Camelyon16数据集切块批量预处理

参考自&#xff1a; Camelyon16数据集切块预处理 区别是这里做了批量处理 数据集目录格式&#xff1a; ** main.py** # !/usr/bin/python3 # -*- coding: utf-8 -*- # Time : 2024/9/4 20:21 # Author : 猫娜Lisa # File : camelyon16_get_patch.py # Software: PyC…

Linux从0到1——基础IO(下)【磁盘/文件系统/软硬链接/动静态库】

Linux从0到1——基础IO&#xff08;下&#xff09; 0. 前言1. 磁盘1.1 物理存储结构1.2 磁盘的逻辑存储结构 2. 文件系统2.1 文件系统的管理思想2.2 详解块组2.3 文件名和inode2.4 挂载 3. 软硬链接3.1 引入3.2 软链接3.3 硬链接 4. 动静态库4.1 静态库4.2 动态库 0. 前言 前面…

强化学习之PPO算法

PPO算法 什么是PPO算法PPO算法的原理PPO-Clip的目标函数 什么是PPO算法 PPO算法&#xff0c;全称为Proximal Policy Optimization&#xff08;近端策略优化&#xff09;&#xff0c;是一种强化学习算法。它由OpenAI在2017年提出&#xff0c;旨在解决策略梯度方法中的一些问题&…

带你0到1之QT编程:六、打地基QList的高效用法

此为QT编程的第六谈&#xff01;关注我&#xff0c;带你快速学习QT编程的学习路线&#xff01; 每一篇的技术点都是很很重要&#xff01;很重要&#xff01;很重要&#xff01;但不冗余&#xff01; 我们通常采取总-分-总和生活化的讲解方式来阐述一个知识点&#xff01; 码…

【系统架构设计师-2012年】综合知识-答案及详解

更多内容请见&#xff1a; 备考系统架构设计师-核心总结索引 文章目录 【第1~2题】【第3~4题】【第5题】【第6题】【第7题】【第8题】【第9题】【第10~11题】【第12~13题】【第14~19题】【第20~21题】【第22~24题】【第25~26题】【第27~31题】【第32~33题】【第34~36题】【第37…

南京大学机试试题合集

&#x1f370;&#x1f370;&#x1f370;hello宝子们&#xff0c;今天我们来练习南京大学的机试题目&#xff0c;这些题目的缺点就是太老了&#xff0c;都是18或19年的题&#xff0c;大家就练练手。加油&#xff01;fighting&#xff01;( •̀ ω •́ )✧ &#x1f369;1161…

geodatatool(地图资源工具)3.8

geodatatool&#xff08;地图资源工具&#xff09;3.8&#xff08;新&#xff09;修复更新&#xff0c;修复更新包括&#xff1a; 1.优化在线地图多线程下载及用户体验。 注意&#xff1a;在线地图下载与背景地图显示用的是同样的源&#xff0c;所以在线地图是否能下载&#x…

通过Jflash合并程序以 BOOT + APP 合并为例

打开【jflash】新建一个JFash工程 建好后界面如下 打开【File】下面的【Open data file…】 找到Boot程序所在位置 打开后界面如下&#xff0c;可以看到hex中的数据 点击【File】下面的【Merge data file…】 打开应用程序 查看APP地址区域是否有数据&#xff0c…

备战秋招60天算法挑战,Day32

题目链接&#xff1a; https://leetcode.cn/problems/house-robber-ii/ 视频题解&#xff1a; https://www.bilibili.com/video/BV1WRYKeKEQE/ LeetCode 213. 打家劫舍 II 题目描述 你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋&#xff0c;每间房内都藏有一定的现金。…

京东的AIGC革新之旅:通过JoyCoder实现研发提效 | 新程序员

【导读】从需求分析、设计编码到测试运维&#xff0c;AI已经逐步渗透到软件开发的各个环节&#xff0c;如何切实针对研发场景进行提效&#xff0c;是业内每个企业都在思考的问题。本文作者详细分析了AI在研发中的实际应用&#xff0c;并分享了JoyCoder与京东内部工具结合的实际…

一款可以替代Notepad++的免费高级文本编辑器

Kate 文本编辑器是一款跨平台的免费高级文本编辑器&#xff0c;具有丰富的功能和特性。它支持标签页、代码高亮、多文件查找、垂直/水平视图、侧边栏、颜色主题等特性&#xff0c;类似于Notepad。它以其多功能性和易用性广受好评。Kate 支持多文档界面&#xff08;MDI&#xff…

加密技术.

基本保密通信模型 密码学发展 古典密码学 主要特点&#xff1a;数据的安全基于算法的保密 经典的加密⽅法包括凯撒密码&#xff08;Caesar Cipher&#xff09;&#xff08;替代密码&#xff09;、维吉尼亚密码&#xff08;Vigenre Cipher&#xff09; 主要分类 替代密码&…

OCR技术视角:智能文档管理中的票据自动化识别与处理

在数字化转型的浪潮中&#xff0c;企业对于高效、自动化的文档管理需求日益增长。票据作为企业运营中不可或缺的部分&#xff0c;其识别与管理的智能化成为了提升工作效率的关键。本文将深入探讨智能文档系统中票据识别功能的原理、技术优势以及在不同行业中的应用实践&#xf…

【报错已解决】`Solving environment: failed`

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 文章目录 引言&#xff1a;一、问题描述&#xff1a;1.1 报错示例&#xff1a;1.2 报错分析&#xff1a;1.3 解决思路&#xff…

智能指针,QT,C++语言的关键字总结

八、C中关键字总结 1> C中一共有63个关键字&#xff0c;如上图所示&#xff0c;其中标红的为c语言中的关键字&#xff0c;有32个 2> 数据类型相关的关键字 bool、true、false&#xff1a;对于bool类型数据的相关处理&#xff0c;值为true和false char、wchar_t:char是…

《Exemplar Free Class Agnostic Counting》CVPR2022

概述 摘要&#xff1a; 这篇论文提出了一种新颖的“无范例类别无关计数”&#xff08;Exemplar Free Class Agnostic Counting&#xff09;方法&#xff0c;旨在测试时对新类别的对象进行计数&#xff0c;而无需访问该类别的标记训练数据。以往的类别无关计数方法无法在完全自…

【刷题笔记】打家劫舍问题

欢迎来到 破晓的历程的 博客 ⛺️不负时光&#xff0c;不负己✈️ 题目一 题目链接&#xff1a;打家劫舍I 思路 小偷每到一初&#xff0c;都可以选择对这个位置偷还是不偷&#xff0c;所以&#xff0c;这次我们需要定义两个表 小Tips&#xff1a;针对这种情况&#xff0c;一般…

OpenGL/GLUT实践:水面模拟——从单振源到 Gerstner Wave(电子科技大学信软图形与动画Ⅱ实验)

源码见GitHub&#xff1a;A-UESTCer-s-Code 文章目录 1 实现效果1 简单水面模拟——单振源1.1 水面高度函数1.2 水面建模1.3 openGL 渲染(1) renderSense(2) 其他 1.4 实现效果 2 添加鼠标控制3 添加纹理4 多个振源组合5 Gerstner Wave 模型5.1 原理5.2 具体实现5.2.1 全局变量…

pytest 常用的辅助函数和工具函数

pytest 常用的辅助函数和工具函数示例 # File: my_module.pydef fetch_data():return process datadef process_data():data fetch_data()return data.upper() import logging import sys import pytest#01-------------------------------pytest.fixture,sample_data 在测试…

Android 下的 XML 文件(概念理解、存储位置理解)

一、XML 1、XML 概述 XML&#xff08;Extensible Markup Language&#xff0c;可扩展标记语言&#xff09;是一种用于存储和传输数据的标记语言 类似于 HTML&#xff0c;但旨在传输和存储数据&#xff0c;而不是显示数据&#xff0c;且基本语法都是标签 2、XML 的特点 &am…