SMOKE Single-Stage Monocular 3D Object Detection via Keypoint Estimation 论文学习

news2024/11/23 19:09:32

论文地址:SMOKE: Single-Stage Monocular 3D Object Detection via Keypoint Estimation
Github 地址:https://github.com/open-mmlab/mmdetection3d/tree/main/configs/smoke

1. 解决了什么问题?

预测物体的 3D 朝向角和平移距离对于自动驾驶感知非常重要。现有的单目视觉方法主要包含两个部分:

  • 生成 2D 区域候选框的网络;
  • 基于生成的感兴趣区域,预测 3D 目标姿态的 R-CNN 结构。

本文认为 2D 检测网络是冗余的,并会给 3D 检测引入噪声。
目前,使用 LiDAR 点云的 3D 目标检测方法是比较成功的,但 LiDAR 传感器成本高昂,使用寿命有限,因此经济性不强。而相机具有重量轻、成本低、易安装、寿命长的优势。与 LiDAR 传感器不同,单个相机自身是无法获得足够的空间信息的,因为 RGB 图像无法提供目标的位置信息或真实世界的维度轮廓。
以前的单目 3D 检测算法非常依赖 R-CNN 或者 RPN 结构。基于学到的大量的 2D 候选框,这些方法使用一个额外的分支,要么直接学习 3D 信息,要么生成伪点云,再输入进点云检测网络做检测。这个过程很复杂,2D 检测结果会给 3D 参数预测带来挥之不去的噪声,增大了网络学习 3D 几何信息的难度。

2. 提出了什么方法?

在这里插入图片描述

SMOKE 是一个端到端的单阶段 3D 目标检测算法,用一个关键点来指代每个目标。如上图所示,对于每个关键点,SMOKE 算法回归多个 3D 参数,从而准确地预测 3D 框。SMOKE 网络简单,包括两个预测分支,分别进行分类和回归任务。它将预测的关键点和变量投影到图像上,得到 3D 框的八个角点,用统一的损失函数来回归。
此外,提出了一个多步骤解耦方法来构建 3D 边框的回归,极大地提升了训练的收敛速度和检测的准确率。由于所有的几何信息都被分在一个参数组里面,网络很难准确地以统一的方式学习每个变量。本文方法在 3D 框编码阶段和回归损失中,将每个参数的贡献分离开来,极大提升了网络的表现。

2.1 Detection Problem

3D 目标检测任务可以表述为:给定单张 RGB 图像 I ∈ R W × H × 3 I\in \mathbb{R}^{W\times H\times 3} IRW×H×3 W W W是图像的宽度, H H H是图像的高度),找到每个目标的类别标签 C C C和 3D 框 B B B B B B由七自由度的变量 ( h , w , l , x , y , z , θ ) (h,w,l,x,y,z,\theta) (h,w,l,x,y,z,θ)表示。 ( h , w , l ) (h,w,l) (h,w,l)表示每个目标的高度、宽度和长度,以米为单位。 ( x , y , z ) (x,y,z) (x,y,z)是目标中心点在相机坐标系的坐标,以米为单位。 θ \theta θ是对应 3D 框的偏航角。在 KITTI 中,roll 和 pitch 都设为了 0 0 0

2.2 SMOKE Approach

以前的方法都是利用 2D 候选框来预测 3D 框,而本文方法则使用单个阶段就能预测出 3D 信息。该方法可以分为三个部分:主干网络、3D 检测网络、损失函数。
在这里插入图片描述

2.2.1 主干网络

如上图所示,SMOKE 使用 DLA-34 作为主干网络来提取特征,DLA-34 能聚合不同层级的信息。所有的层级聚合连接都被替换为了可变形卷积(DCN)。对原图做了 4 4 4倍降采样,得到输出特征图。此外,将所有的 BatchNorm 替换为了 GroupNorm,GN 对 batch size 没那么敏感,对训练噪声更加鲁棒。该 trick 也用在了预测分支里面。它不仅提升了检测准确率,也能降低训练时间。

2.2.2 3D 检测网络

如上图所示,在主干网络输出的特征图上有两个分支,协同进行关键点分类(粉色)和 3D 框回归(绿色)。

关键点分支

每个目标用一个关键点表示。关键点定义为图像平面上目标 3D 中心的投影点,而不是 2D 框的中心点。下图展示了 2D 框中心点(红色)和 3D 框投影点(橙色)的差异。通过相机参数,我们可以对投影的关键点恢复出每个目标的 3D 位置。用 [ x , y , z ] T [x,y,z]^T [x,y,z]T表示相机坐标系每个目标的 3D 中心点。可以通过相机内参矩阵 K K K计算出图像平面上的投影点 [ x c , y c ] T [x_c,y_c]^T [xc,yc]T
[ z ⋅ x c z ⋅ y c z ] = K 3 × 3 [ x y z ] \left[ \begin{array}{ccc} z\cdot x_c \\ z\cdot y_c \\ z \end{array} \right]=K_{3\times 3} \left[ \begin{array}{ccc} x \\ y \\ z \end{array} \right] zxczycz =K3×3 xyz
对于每个 ground-truth 关键点,借鉴 CenterNet 高斯核的方式,计算它在特征图上相应的下采样点。将 ground-truth 3D 框投影到图像上,计算标准差。用 8 8 8个 2D 点来表示图像上的 3D 框 [ x b , 1 ∼ 8 , y b , 1 ∼ 8 ] T [x_{b,1\sim 8}, y_{b,1\sim 8}]^T [xb,18,yb,18]T,其最小包围框是 { x b m i n , y b m i n , x b m a x , y b m a x } \left\{x_b^{min}, y_b^{min}, x_b^{max}, y_b^{max}\right\} {xbmin,ybmin,xbmax,ybmax},然后计算其标准差。
在这里插入图片描述

回归分支

对于热力图上的每个关键点,回归分支预测构建 3D 框的变量。3D 信息编码为 8 8 8元组形式, τ = [ δ z , δ x c , δ y c , δ h , δ w , δ l , sin ⁡ α , cos ⁡ α ] T \tau=[\delta_z, \delta_{x_c},\delta_{y_c},\delta_h,\delta_w,\delta_l,\sin{\alpha},\cos{\alpha}]^T τ=[δz,δxc,δyc,δh,δw,δl,sinα,cosα]T δ z \delta_z δz表示深度偏移值, δ x c , δ y c \delta_{x_c},\delta_{y_c} δxc,δyc表示由离散化的偏移值, δ h , δ w , δ l \delta_h,\delta_w,\delta_l δh,δw,δl表示边框的残差维度, sin ⁡ ( α ) , cos ⁡ ( α ) \sin(\alpha),\cos(\alpha) sin(α),cos(α)是旋转角度 α \alpha α的向量表示。以残差表征的形式编码所有的变量,降低学习时间,简化训练任务。回归的特征图大小是 S r ∈ R H R × W R × 8 S_r\in \mathbb{R}^{\frac{H}{R}\times \frac{W}{R}\times 8} SrRRH×RW×8。作者使用操作 F \mathcal{F} F,将投影 3D 点转化为一个 3D 框 B = F ( τ ) ∈ R 3 × 8 B=\mathcal{F}(\tau)\in \mathbb{R}^{3\times 8} B=F(τ)R3×8。对于每个目标,用预定义的尺度 σ z \sigma_z σz和平移参数 μ z \mu_z μz恢复出深度 z z z:
z = μ z + δ z σ z z=\mu_z + \delta_z \sigma_z z=μz+δzσz
给定目标的深度 z z z,我们可以用目标在图像平面的投影中心点 [ x c , y c ] T [x_c,y_c]^T [xc,yc]T和下采样偏移值 [ δ x c , δ y c ] T [\delta_{x_c},\delta_{y_c}]^T [δxc,δyc]T恢复出它在相机坐标系的位置,
[ x y z ] = K 3 × 3 − 1 [ z ⋅ ( x c + δ x c ) z ⋅ ( y c + δ y c ) z ] \left[ \begin{array}{ccc} x \\ y \\ z \end{array} \right]=K_{3\times 3}^{-1} \left[ \begin{array}{ccc} z\cdot (x_c + \delta_{x_c})\\ z\cdot (y_c + \delta_{y_c})\\ z \end{array} \right] xyz =K3×31 z(xc+δxc)z(yc+δyc)z
为了获取目标的尺度 [ h , w , l ] T [h,w,l]^T [h,w,l]T,我们先对整个数据集计算出各类别的平均尺度 [ h ‾ , w ‾ , l ‾ ] T [\overline{h},\overline{w}, \overline{l}]^T [h,w,l]T。使用残差尺度的偏移值 [ δ h , δ w , δ l ] T [\delta_h, \delta_w, \delta_l]^T [δh,δw,δl]T可以恢复每个目标的尺度信息:
[ h w l ] = [ h ‾ ⋅ e δ h w ‾ ⋅ e δ w l ‾ ⋅ e δ l ] \left[ \begin{array}{ccc} h\\ w\\ l \end{array} \right]= \left[ \begin{array}{ccc} \overline{h}\cdot e^{\delta_h}\\ \overline{w}\cdot e^{\delta_w}\\ \overline{l}\cdot e^{\delta_l} \end{array} \right] hwl = heδhweδwleδl
本文方法选择回归目标的观测角(物体前进方向与观测视线的夹角) α x \alpha_x αx,而非偏航角 θ \theta θ。关于目标的朝向,我们进一步调整观测角 α x \alpha_x αx得到 α z \alpha_z αz,做法就是 α z = α x − π 2 \alpha_z=\alpha_x - \frac{\pi}{2} αz=αx2π。下图展示了 α x , α z \alpha_x,\alpha_z αx,αz的区别。每个 α \alpha α用向量 [ sin ⁡ ( α ) , cos ⁡ ( α ) ] T [\sin(\alpha),\cos(\alpha)]^T [sin(α),cos(α)]T编码。偏航角 θ \theta θ(即 r y r_y ry)可以通过 α z \alpha_z αz和目标位置得到:
θ = α z + arctan ⁡ ( x z ) \theta=\alpha_z + \arctan(\frac{x}{z}) θ=αz+arctan(zx)
在这里插入图片描述

注意:在代码中使用 torch.atan \text{torch.atan} torch.atan得到 α x ′ = arctan ⁡ ( sin ⁡ α cos ⁡ α ) ∈ [ − π 2 , π 2 ] \alpha_x'=\arctan(\frac{\sin{\alpha}}{\cos{\alpha}})\in [-\frac{\pi}{2}, \frac{\pi}{2}] αx=arctan(cosαsinα)[2π,2π],而原本的角度 α x ∈ [ 0 , 2 π ] \alpha_x\in [0, 2\pi] αx[0,2π],因此需要对 α x ′ \alpha_x' αx做进一步变换。

  • 如果 cos ⁡ α ≥ 0 \cos{\alpha}\geq 0 cosα0,说明 α ∈ [ 0 , π 2 ] \alpha\in [0, \frac{\pi}{2}] α[0,2π] α ∈ [ 3 π 2 , 2 π ] \alpha\in [\frac{3\pi}{2}, 2\pi] α[23π,2π](后者需要 + 2 π +2\pi +2π,但由于周期性不加也可以),则 α x = α x ′ \alpha_x=\alpha_x' αx=αx,于是 α z = α x ′ − π 2 \alpha_z = \alpha_x' - \frac{\pi}{2} αz=αx2π
  • 如果 cos ⁡ α < 0 \cos{\alpha}<0 cosα<0,说明 α ∈ [ π 2 , 3 π 2 ] \alpha\in [\frac{\pi}{2}, \frac{3\pi}{2}] α[2π,23π] α x = α x ′ + π \alpha_x=\alpha_x' + \pi αx=αx+π,那么 α z = α x ′ + π − π 2 = α x ′ + π 2 \alpha_z=\alpha_x' + \pi - \frac{\pi}{2}=\alpha_x' + \frac{\pi}{2} αz=αx+π2π=αx+2π
    α z = { α x ′ − π 2 , if cos ⁡ α ≥ 0 α x ′ + π 2 , if cos ⁡ α < 0 \alpha_z=\left\{ \begin{aligned} \alpha_x'-\frac{\pi}{2},&& \text{if} &\cos{\alpha}\geq 0 \\ \alpha_x'+\frac{\pi}{2},&& \text{if} & \cos{\alpha}<0 \end{aligned} \right. αz= αx2π,αx+2π,ififcosα0cosα<0
    然后就可得: θ = α z + arctan ⁡ ( x z ) \theta=\alpha_z + \arctan(\frac{x}{z}) θ=αz+arctan(zx)
    上述偏航角解码过程可参考下面的代码:
def decode_orientation(self, vector_ori, locations, flip_mask=None):
    locations = locations.view(-1, 3)
    rays = torch.atan(locations[:, 0] / (locations[:, 2] + 1e-7))  # 计算 arctan(x/z),用的gt
    alphas = torch.atan(vector_ori[:, 0] / (vector_ori[:, 1] + 1e-7))  # arctan(sin/cos)
    # get cosine value positive and negtive index.
    cos_pos_idx = torch.nonzero(vector_ori[:, 1] >= 0)  # 比较cos值是否大于0,判断属于哪个区间
    cos_neg_idx = torch.nonzero(vector_ori[:, 1] < 0)
    alphas[cos_pos_idx] -= PI / 2  # 通过这步转换为kitti中的alpha角度定义
    alphas[cos_neg_idx] += PI / 2# retrieve object rotation y angle.
    rotys = alphas + rays  # ry = alpha + theta

最后,通过偏航角旋转矩阵 R θ R_\theta Rθ、目标尺度 [ h , w , l ] T [h,w,l]^T [h,w,l]T和坐标 [ x , y , z ] T [x,y,z]^T [x,y,z]T,在相机坐标系中构建 3D 框的 8 8 8个角点:
B = R θ [ ± h / 2 ± w / 2 ± l / 2 ] + [ x y z ] B=R_\theta\left[ \begin{array}{ccc} \pm h/2\\ \pm w/2\\ \pm l/2 \end{array} \right]+ \left[ \begin{array}{ccc} x \\ y \\ z \end{array} \right] B=Rθ ±h/2±w/2±l/2 + xyz

2.2.3 Loss Functions

关键点分类损失

对下采样的热力图,逐点使用 Focal Loss。热力图位置 ( i , j ) (i,j) (i,j)的预测得分为 s i , j s_{i,j} si,j y i , j y_{i,j} yi,j是高斯核赋给每个点的 ground-truth 值。
y ˘ i , j \u{y}_{i,j} y˘i,j s ˘ i , j \u{s}_{i,j} s˘i,j定义如下:
y ˘ i , j = { 0 , if y i , j = 1 y i , j , otherwise , s ˘ i , j = { s i , j , if y i , j = 1 1 − s i , j , otherwise \u{y}_{i,j}=\left\{ \begin{aligned} 0,& & \text{if} & y_{i,j}=1 \\ y_{i,j},& & & \text{otherwise} \end{aligned} \right. \quad,\quad\quad\quad \u{s}_{i,j}=\left\{ \begin{aligned} s_{i,j},& & \text{if} & y_{i,j}=1 \\ 1-s_{i,j},& & &\text{otherwise} \end{aligned} \right. y˘i,j={0,yi,j,ifyi,j=1otherwise,s˘i,j={si,j,1si,j,ifyi,j=1otherwise
为了简洁,只考虑单个目标类别情况。分类损失如下:
L c l s = − 1 N ∑ i , j = 1 h , w ( 1 − y ˘ i , j ) β ( 1 − s ˘ i , j ) α log ⁡ ( s ˘ i , j ) L_{cls}=-\frac{1}{N}\sum_{i,j=1}^{h,w}(1-\u{y}_{i,j})^\beta (1-\u{s}_{i,j})^\alpha \log(\u{s}_{i,j}) Lcls=N1i,j=1h,w(1y˘i,j)β(1s˘i,j)αlog(s˘i,j)
这里 α , β \alpha,\beta α,β是调节超参数, N N N是图像上关键点个数。 ( 1 − y i , j ) (1-y_{i,j}) (1yi,j)用于惩罚 ground-truth 附近的点。

回归损失

回归 8 D 8D 8D元组 τ \tau τ来构建 3D 框。为了保留一致性,在每个特征图的位置上,往回归的尺度和朝向角参数中使用通道激活。对尺度参数使用的激活函数为 sigmoid \text{sigmoid} sigmoid函数,对朝向角使用的是 l 2 \mathcal{l}_2 l2范数,
[ δ h δ w δ l ] = σ ( [ o h o w o l ] ) − 1 2 , [ sin ⁡ α cos ⁡ α ] = [ o sin ⁡ / o sin ⁡ 2 + o cos ⁡ 2 o cos ⁡ / o sin ⁡ 2 + o cos ⁡ 2 ] \left[ \begin{array}{ccc} \delta_h\\ \delta_w\\ \delta_l \end{array} \right]=\sigma\left( \left[ \begin{array}{ccc} o_h \\ o_w \\ o_l \end{array} \right]\right) - \frac{1}{2} \quad,\quad\quad\quad \left[ \begin{array}{ccc} \sin{\alpha}\\ \cos{\alpha} \end{array} \right]= \left[ \begin{array}{ccc} o_{\sin}/\sqrt{o_{\sin}^2 + o_{\cos}^2} \\ o_{\cos}/\sqrt{o_{\sin}^2+o_{\cos}^2} \end{array} \right] δhδwδl =σ ohowol 21,[sinαcosα]=[osin/osin2+ocos2 ocos/osin2+ocos2 ]

这里 o o o代表网络的特定输出。将 3D 框回归损失定义为预测框 B ^ \hat{B} B^和 ground-truth B B B之间的 l 1 \mathcal{l}_1 l1距离:
L r e g = λ N ∥ B ^ − B ∥ 1 L_{reg}=\frac{\lambda}{N}\left\|\hat{B}-B\right\|_1 Lreg=Nλ B^B 1
其中 λ \lambda λ是缩放系数。
对于 3D 回归损失,解耦变换损失是一项有效的方法。
[ x y z ] = K 3 × 3 − 1 [ z ⋅ ( x c + δ x c ) z ⋅ ( y c + δ y c ) z ] \left[ \begin{array}{ccc} x \\ y \\ z \end{array} \right]=K_{3\times 3}^{-1} \left[ \begin{array}{ccc} z\cdot (x_c + \delta_{x_c})\\ z\cdot (y_c + \delta_{y_c})\\ z \end{array} \right] xyz =K3×31 z(xc+δxc)z(yc+δyc)z 中,使用图像平面的 3D 投影点 [ x c , y c ] T [x_c,y_c]^T [xc,yc]T、网络预测的离散偏移 [ δ ^ x c , δ ^ y c ] T [\hat{\delta}_{x_c},\hat{\delta}_{y_c}]^T [δ^xc,δ^yc]T和深度值 z ^ \hat{z} z^,可以得到相机坐标系内每个目标的坐标 [ x ^ , y ^ , z ^ ] T [\hat{x},\hat{y},\hat{z}]^T [x^,y^,z^]T
θ = α z + arctan ⁡ ( x z ) \theta=\alpha_z + \arctan(\frac{x}{z}) θ=αz+arctan(zx)中,使用 ground-truth 位置 [ x , y , z ] T [x,y,z]^T [x,y,z]T和预测的观测角 α ^ z \hat{\alpha}_z α^z,得到偏航角 θ ^ \hat{\theta} θ^。3D 框的表征可以分为三组,即朝向角、尺度和坐标。损失函数如下表示:
L = L c l s + ∑ i = 1 3 L r e g ( B ^ i ) L=L_{cls}+\sum_{i=1}^3 L_{reg}(\hat{B}_i) L=Lcls+i=13Lreg(B^i)
i i i表示 3D 回归分支定义的组的序号。多步骤解耦变换方法分别对待各组参数的贡献,能极大地提升了检测表现。

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

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

相关文章

hive之入门配置

学习hive之路就此开启啦&#xff0c;让我们共同努力 目录 Hive网站&#xff1a; Hive的安装部署&#xff1a; 启动并使用Hive&#xff1a; 安装Mysql: 安装Mysql依赖包&#xff1a; 启动Mysql: 查看密码&#xff1a; 登录root: 密码错误报错&#xff1a; 元数据库配置…

信创国产中间件概览

信创国产中间件概览 中间件国内中间件市场份额第一梯队仍然是IBM> 和Oracle&#xff0c;市场份额合计51%。第二梯队为五大国产厂商&#xff0c;包括东方通、普元信息、宝兰德、中创中间件、金蝶天燕&#xff0c;市场份额合计15%。东方通应用服务器TongWeb对标 开源&#xf…

人脸检测和行人检测3:Android实现人脸检测和行人检测检测(含源码,可实时检测)

人脸检测和行人检测3&#xff1a;Android实现人脸检测和行人检测检测(含源码&#xff0c;可实时检测) 目录 人脸检测和行人检测3&#xff1a;Android实现人脸检测和行人检测(含源码&#xff0c;可实时检测) 1. 前言 2. 人脸检测和行人检测数据集说明 3. 基于YOLOv5的人脸检…

Databend 开源周报第 91 期

Databend 是一款现代云数仓。专为弹性和高效设计&#xff0c;为您的大规模分析需求保驾护航。自由且开源。即刻体验云服务&#xff1a;https://app.databend.cn 。 Whats On In Databend 探索 Databend 本周新进展&#xff0c;遇到更贴近你心意的 Databend 。 新数据类型&…

【Robot Framework】RF关键字大全

收录工作当中最常用的Robot Framework关键字 内容较多&#xff0c;可以CtrlF快速搜索自己想要的 1. RF循环使用&#xff08;FOR循环&#xff09; {list1} create list LOG TXT INI INF C CPP JAVA JS CSS LRC H ASM S ASP FOR ${file_type} IN {list1} log 构造请求参数 ${t…

第二十二章 解释器模式

文章目录 前言一、解释器模式基本介绍解释器模式的原理类图 二、通过解释器模式来实现四则运算完整代码抽象表达式类 Expression变量表达式类 VarExpression抽象运算符号解析器 SymbolExpression加法解释器 AddExpression减法解释器 SubExpression计算器类 CalculatorClint 测试…

【C++】仅需一文速通继承

文章目录 1.继承的概念及定义继承的概念继承的定义定义格式:继承关系和访问限定符继承基类成员访问方式的变化 2.基类和派生类对象赋值转换3.继承中的作用域4.派生类的默认成员函数题目:设计出一个类A,让这个类不能被继承(继承了也没用) 5.继承与友元6.继承与静态成员7.复杂的菱…

VK Cup 2017 - Round 1 A - Bear and Friendship Condition(并查集维护大小 + dfs 遍历图统计边数)

题目大意&#xff1a; 给你一些n个点m条边&#xff0c;如果三个点&#xff08;a,b,c&#xff09;是合法的&#xff0c;当且仅当 a-b,b-c,c-a都有一条边&#xff0c;问你这个图是否合法&#xff0c;如果有一个或两个点视为合法 思路 考虑什么图才是个合法图&#xff1a;除了点…

Spring 更简单的读取和存储对象

✏️作者&#xff1a;银河罐头 &#x1f4cb;系列专栏&#xff1a;JavaEE &#x1f332;“种一棵树最好的时间是十年前&#xff0c;其次是现在” 前面介绍了通过配置文件的方式来存储 Bean 对象&#xff0c;那么有没有更简单的方式去存储 Bean 对象&#xff1f; 有以下 2 种方…

【论文】LearningDepth from Single Monocular Images

2005 NIPS 文章目录 特征提取卷积核的使用Multiscale 多尺度提取特征特征的相对深度 模型结论特征提取数据集导致的error 文章使用了Markov 随机场(Markov Random Fields, MRF) 从单图像上直接估计出图像的深度信息。 与RGBD输入数据不同的是&#xff0c;文章中采用了YCbCr数据…

知识点总结-DAY1

1. 请解释OSI模型中每一层的作用 应用层&#xff1a;为用户提供服务&#xff0c;处理应用程序之间交换的数据。 表示层&#xff1a;处理数据在网络上的表示形式&#xff0c;如加密和解密、压缩和解压缩等。 会话层&#xff1a;建立、维护和终止两个节点之间的会话&#xff0c…

安全防御 --- IPSec理论

IPSec 1、概述&#xff1a; 是IETF&#xff08;Internet Engineering Task Force&#xff09;制定的一组开放的网络安全协议&#xff0c;在IP层通过数据来源认证、数据加密、数据完整性和抗重放功能来保证通信双方Internet上传输数据的安全性。 IPSec安全服务 机密性完整性…

雨季时,骑行经过泥泞路段该怎么办?

泥泞路段骑行是一项需要技巧和勇气的挑战。在泥泞路段骑行&#xff0c;骑友又叫玩泥巴&#xff0c;不仅需要良好的车技和身体素质&#xff0c;还需要有足够的经验和判断力&#xff0c;以应对各种突发情况。下面&#xff0c;将从多个角度介绍泥泞路段骑行的挑战和技巧&#xff0…

宏观经济笔记--社会消费品零售总额

我们讨论了GDP的三个分项&#xff1a;投资、消费、净出口。投资我们前面已经介绍了&#xff0c;消费这一个分项我们还一直没有讨论。消费最重要的数据是每个月月中统计局公布的社会消费品零售总额。 一般的论调中&#xff0c;认为消费是三个GDP驱动项中最健康的一项&#xff0…

2023-5-4-Lua语言学习

&#x1f37f;*★,*:.☆(&#xffe3;▽&#xffe3;)/$:*.★* &#x1f37f; &#x1f4a5;&#x1f4a5;&#x1f4a5;欢迎来到&#x1f91e;汤姆&#x1f91e;的csdn博文&#x1f4a5;&#x1f4a5;&#x1f4a5; &#x1f49f;&#x1f49f;喜欢的朋友可以关注一下&#xf…

openQA----基于openQA新增指定版本的openSUSE的iso镜像进行测试

【原文链接】openQA----基于openQA新增指定版本的openSUSE的iso镜像进行测试 &#xff08;1&#xff09;执行如下命令下载openSUSE的测试脚本&#xff0c;它会从openSUSE的测试脚本github地址 /usr/share/openqa/script/fetchneedles&#xff08;2&#xff09;然后执行如下命…

在 SourceTree 中使用 rebase (win10)

原始状态 创建两个分支 dev1 dev2, 并且推送到远端 切换到dev1 做一些修改并提交dev1-1&#xff0c;注意不要推送到到远端 切换到master分支&#xff0c;拉取最新的代码 切换到dev1 分支&#xff0c;进行变基操作&#xff0c;右击master分支 推送dev1分支到远端 切换到master分…

如何快速获取已发表学术论文的期刊封面及目录(caj格式下载和caj转pdf)

目录 1 下载caj格式的封面和目录 2 CAJ格式的封面和目录转PDF格式 在进行职称评审或成果申报时&#xff0c;一般要求提交你发表的成果所在的期刊的当期封面和目录。本文就手把手带带你制作一个期刊目录。 重要提示&#xff1a;下载期刊封面和目录需要你有知网账号&#xff0…

iOS 17预计开放侧载,游戏安全对抗将迎来新高度

近日&#xff0c;据彭博社报道&#xff0c;iOS 17预计开放“侧载”机制。所谓的“侧载”是指&#xff1a;iPhone用户下载APP时&#xff0c;可选择不在APP store中下载&#xff0c;可在相关APP官网或者第三方应用市场进行下载。 众所周知&#xff0c;APP闭源生态是苹果公司最核…

C++ 基础二

C 核心编程 1 内存分区模型 内存分区模型 代码区&#xff1a;存放函数的二级制代码&#xff0c;由操作系统进行管理的 全局区&#xff1a;存放全局变量和静态变量以及常量 栈区&#xff1a;由编译器自动分配释放&#xff0c;存放函数的参数值&#xff0c;局部变量等 堆区&…