SIRA-PCR: Sim-to-Real Adaptation for 3D Point Cloud Registration 论文解读

目录

一、导言

二、 相关工作

 1、三维点云配准工作

2、无监督域适应

三、SIRA-PCR

1、FlyingShape数据集

2、Sim-to-real自适应方法

3、配准

4、损失函数


一、导言

        该论文来自于ICCV2023,论文提出了一种新的方法SIRA-PCR,通过利用合成数据FlyingShapes解决现有数据稀缺问题。

        数据稀缺原因:现有的基于数据驱动的深度学习方法一般依赖于两类数据,一是单一物体级别如ModelNet40,ShapeNet,二是对于室内场景水平如3DMatch。虽然单一物体级别数据集有较强的几何形状,但很难推广到真实的室内场景,室内场景的数据集来训练性能很好,但捕获真实的室内场景十分耗时且估计的相机姿态存在错误标签。所以针对场景级的合成数据集仍然数据稀缺,所以本文创建了一个合成场景数据集FlyingShapes。

(1)构建了第一个大规模的室内合成数据集FlyingShapes,使用基于物理和随机的策略将ShapeNet对象插入3D-FRONT场景中。

(2)设计了一个称为SIRA的管道,包括一个自适应重采样模块,目的是缓解合成数据和真实数据之间的域差距(分布差异),从而提高点云配准的性能。

二、 相关工作

 1、三维点云配准工作

        一种是直接配准,一种是基于对应的方法(与以前的博文类似)

2、无监督域适应

        无监督自适应是一种解决源域(合成数据)与目标域(真实数据)之间分布差异的方法,旨在利用源域的标注数据和目标域的无标注数据,学习一个可以将源域数据映射到目标域的模型,从而提高目标域任务的性能,通过这样的方式,利用合成数据集来解决真实数据集标注不足的问题。

        对于以往的点云配准任务来说,一般通过利用GAN来执行域对抗训练,使得两个域的点云特征难以被鉴别器区分。还有方法通过自监督学习里解决域对齐。

三、SIRA-PCR

        SIRA-PCR框架,首先通过SIRA结构基于FlyingShapes数据集来训练合成数据到真实数据的域自适应,之后基于3DMatch或3DLoMatch(实验工作)使用GeoTransformer来训练配准工作。

        SIRA-PCR框架的目的:就是通过先训练一遍我们改进的合成数据集FlyingShape,来学习到一些真实数据集中应该有的特征,这样优化了真实数据集中由于标注错误,数据样本少而训练不足的问题,其实从本质上就是增加更多的样本量,完全可以把做合成数据集到合成2真实的域适应的工作看成一种增加样本量的方式。

1、FlyingShapes数据集

        3D-FRONT数据集是一个由专业设计师设计的室内场景和家具布局的场景数据集,但由于结构过于简单,FlyingShape数据集从3D-FRONT场景数据集中添加一定的家具模型来模拟真实的场景。

        FlyingShapes数据集考虑了三个因素进行优化:

(1)几何增强

        由于现实场景中家具摆放不一定合理,可能存在一定的随机性。所以使用两种方式添加对象数据集(单一对象),分别是基于物理意义的(重力要求),随机放置(无视重力)。

        由于3D-FRONT数据集中存在大量的地板、墙壁、天花板等简单的平面,对结构的泛化效果有限,从而也使得网络过分关注这些简单的平面结构,所以以50%的概率去除这些平坦平面,进而提高对于对象数据集中物体的几何结构平衡。

(2)高质量的视角选择

        视角选择着重考虑,点云数据集中,每一团点云结构应该包含较为足够数量的对象(大于5个对象结构),并且视角保持人类视角,且移动保持人类转动行进的速度(设置高度为1.6m,水平视角360°,垂直方向仰角0到45°,以30°或15°来均匀采样视图)

(3)数据准备

        为模拟RGB-D摄像机的深度信息,我们通过虚拟摄像机绘制深度图并转换为点云,保留重叠范围在30%以上的点云,提高模型的泛化能力。

2、Sim-to-real自适应方法

        这一部分就是做无监督域适应工作,其实本质来说也是一个GAN网络。

生成器(ResampleGAN):

        生成器采用Encoder-Decoder结构,Encoder部分是ResampleKPConvEncoder结构(KPConv+ARM自适应重采样模块+FPN,用于提取特征),Decoder部分是MLPDecoder结构(本质是三层1维卷积通过LeakyReLU激活函数相连,用于将特征转换为三维坐标)

        Encoder部分又可以看做一个KPConv与FPN的结合,并且每一层都会添加一个ARM重采样结构。KPConv负责从顶到底提取特征,FPN部分负责多层次的特征再次提取。

        ARM重采样:Adaptive Re-sample Module,实现了基于注意力机制的点的局部重采样,利用点的特征和邻点的信息来计算一个点的加权平均坐标,保证了每一步的卷积操作输出后都有针对邻点特征的优化。

        ARM算法:输入所有点的坐标(坐标矩阵),构建每个点周围的一个局部patch,并得到该点的特征和该点邻点特征,并通过加权邻点特征和该点特征,得到新的坐标点,作为调整点位置。

        对于论文图3的解释如下:

        我们举点云中任何一个点P_i为例子,实际是直接用点云的坐标矩阵来进行下面计算。

        对于一个点P_i的特征f_i(d维列向量)与P_i周围K个点的邻点特征F_i^P(K*d维矩阵)的转置相乘,并除以\sqrt{d}进行归一化,之后通过Softmax函数得到权重系数w_i(K维列向量),w_i乘以K个邻近点坐标矩阵P_i (K*3维矩阵)得到重采样点y_i

        公式解释:(其中,W^A就是将点运算转换为矩阵运算,可忽略看)

                                                   w_i=softmax(\frac{(F_i^PW^A)(f_iW^A)^T}{\sqrt{d}})

                                            y_i=\sum_{k=1}^K w_{i,k} P_{i,k}^\mathrm{P}, \qquad \sum_{k=1}^Kw_{i,k}=1

         

生成器代码如下:

#重采样代码
class PatchResampleBlock(nn.Module):def __init__(self, feat_channels) -> None:r"""Initialize a patch resample block.Args:feat_channels: dimension of input features"""super(PatchResampleBlock, self).__init__()self.feat_channels = feat_channelsself.feat_proj = nn.Linear(self.feat_channels, self.feat_channels)def forward(self, points, feats, neighbor_indices):point_num, neighbor_limit = neighbor_indices.shape# adjust neighbor_indices (stand still when the patch has few neighbors)point_indices = torch.arange(point_num,device=neighbor_indices.device).reshape((point_num, 1)).repeat((1, neighbor_limit))  # (N ,K)neighbor_indices = torch.where(neighbor_indices < point_num,neighbor_indices, point_indices)# feature projectionfeats = self.feat_proj(feats)neighbor_feats = feats[neighbor_indices]  # (N, K, d)neighbor_points = points[neighbor_indices]  # (N, K, 3)neighbor_weights = torch.einsum("nd,nkd->nk", feats,neighbor_feats)  # (N, d) x (N, K, d) -> (N, K)neighbor_weights = nn.functional.softmax(neighbor_weights /self.feat_channels**0.5,dim=-1)  # (N, K) -> (N, K)output_points = torch.einsum("nk,nkp->np", neighbor_weights,neighbor_points)  # (N, K) x (N, K, 3) -> (N, 3)return output_points#KPconv+FPN+ARM作为Encoder
class ResampleKPConvEncoder(nn.Module):def __init__(self, input_dim, output_dim, init_dim, kernel_size,init_radius, init_sigma, group_norm):super(ResampleKPConvEncoder, self).__init__()self.encoder1_1 = ConvBlock(input_dim, init_dim, kernel_size,init_radius, init_sigma, group_norm)self.encoder1_2 = ResidualBlock(init_dim, init_dim * 2, kernel_size,init_radius, init_sigma, group_norm)self.encoder2_1 = ResidualBlock(init_dim * 2,init_dim * 2,kernel_size,init_radius,init_sigma,group_norm,strided=True)self.encoder2_2 = ResidualBlock(init_dim * 2, init_dim * 4,kernel_size, init_radius * 2,init_sigma * 2, group_norm)self.encoder2_3 = ResidualBlock(init_dim * 4, init_dim * 4,kernel_size, init_radius * 2,init_sigma * 2, group_norm)self.encoder3_1 = ResidualBlock(init_dim * 4,init_dim * 4,kernel_size,init_radius * 2,init_sigma * 2,group_norm,strided=True)self.encoder3_2 = ResidualBlock(init_dim * 4, init_dim * 8,kernel_size, init_radius * 4,init_sigma * 4, group_norm)self.encoder3_3 = ResidualBlock(init_dim * 8, init_dim * 8,kernel_size, init_radius * 4,init_sigma * 4, group_norm)self.encoder4_1 = ResidualBlock(init_dim * 8,init_dim * 8,kernel_size,init_radius * 4,init_sigma * 4,group_norm,strided=True)self.encoder4_2 = ResidualBlock(init_dim * 8, init_dim * 16,kernel_size, init_radius * 8,init_sigma * 8, group_norm)self.encoder4_3 = ResidualBlock(init_dim * 16, init_dim * 16,kernel_size, init_radius * 8,init_sigma * 8, group_norm)self.resample4 = PatchResampleBlock(feat_channels=init_dim * 16)self.decoder4 = UnaryBlock(init_dim * 16 + 3, init_dim * 16,group_norm)self.resample3 = PatchResampleBlock(feat_channels=init_dim * 8)self.decoder3 = UnaryBlock(init_dim * 24 + 3, init_dim * 8, group_norm)self.resample2 = PatchResampleBlock(feat_channels=init_dim * 4)self.decoder2 = UnaryBlock(init_dim * 12 + 3, init_dim * 4, group_norm)self.resample1 = PatchResampleBlock(feat_channels=init_dim * 2)self.decoder1 = UnaryBlock(init_dim * 6 + 3, output_dim, group_norm)self.outputlayer = LastUnaryBlock(output_dim, output_dim)def forward(self, data_dict):points_list = data_dict['points']neighbors_list = data_dict['neighbors']subsampling_list = data_dict['subsamples']upsampling_list = data_dict['upsamples']feats_s1 = torch.ones((points_list[0].shape[0], 1),dtype=torch.float32).to(points_list[0])feats_s1 = self.encoder1_1(feats_s1, points_list[0], points_list[0],neighbors_list[0])feats_s1 = self.encoder1_2(feats_s1, points_list[0], points_list[0],neighbors_list[0])feats_s2 = feats_s1feats_s2 = self.encoder2_1(feats_s2, points_list[1], points_list[0],subsampling_list[0])feats_s2 = self.encoder2_2(feats_s2, points_list[1], points_list[1],neighbors_list[1])feats_s2 = self.encoder2_3(feats_s2, points_list[1], points_list[1],neighbors_list[1])feats_s3 = feats_s2feats_s3 = self.encoder3_1(feats_s3, points_list[2], points_list[1],subsampling_list[1])feats_s3 = self.encoder3_2(feats_s3, points_list[2], points_list[2],neighbors_list[2])feats_s3 = self.encoder3_3(feats_s3, points_list[2], points_list[2],neighbors_list[2])feats_s4 = feats_s3feats_s4 = self.encoder4_1(feats_s4, points_list[3], points_list[2],subsampling_list[2])feats_s4 = self.encoder4_2(feats_s4, points_list[3], points_list[3],neighbors_list[3])feats_s4 = self.encoder4_3(feats_s4, points_list[3], points_list[3],neighbors_list[3])resampled_points4 = self.resample4(points_list[3], feats_s4,neighbors_list[3])latent_s4 = torch.cat([feats_s4, resampled_points4],dim=1)  # (N4, 64*16+3)latent_s4 = self.decoder4(latent_s4)resampled_points3 = self.resample3(points_list[2], feats_s3,neighbors_list[2])latent_s3 = nearest_upsample(latent_s4, upsampling_list[2])latent_s3 = torch.cat([latent_s3, feats_s3, resampled_points3],dim=1)  # (N3, 64*16+64*8+3)latent_s3 = self.decoder3(latent_s3)resampled_points2 = self.resample2(points_list[1], feats_s2,neighbors_list[1])latent_s2 = nearest_upsample(latent_s3, upsampling_list[1])latent_s2 = torch.cat([latent_s2, feats_s2, resampled_points2],dim=1)  # (N2, 64*8+64*4+3)latent_s2 = self.decoder2(latent_s2)  # (N1, 256)resampled_points1 = self.resample1(points_list[0], feats_s1,neighbors_list[0])latent_s1 = nearest_upsample(latent_s2, upsampling_list[0])latent_s1 = torch.cat([latent_s1, feats_s1, resampled_points1],dim=1)  # (N1, 64*4+64*2+3)latent_s1 = self.decoder1(latent_s1)  # (N1, 256)output = self.outputlayer(latent_s1)  # (N1, 256)return output#三层卷积作为Decoder
class MLPDecoder(nn.Module):def __init__(self, dimoffeat=256):super(MLPDecoder, self).__init__()self.sharedmlp = nn.Sequential(nn.Conv1d(dimoffeat, int(dimoffeat / 2), 1),nn.LeakyReLU(negative_slope=0.2),nn.Conv1d(int(dimoffeat / 2), int(dimoffeat / 8), 1),nn.LeakyReLU(negative_slope=0.2),nn.Conv1d(int(dimoffeat / 8), 3, 1))def forward(self, feat):feat = feat.transpose(-1, -2)  # (N, d) -> (d, N)feat = feat.unsqueeze(0)  # (d, N) -> (batch, d, N)output = self.sharedmlp(feat)  # (batch, d, N) -> (batch, 3, N)output = output.squeeze(0)  # (batch, 3, N) -> (3, N)output = output.transpose(-1, -2)  # (3, N) -> (N, 3)return output#生成器
class ResampleGAN(nn.Module):def __init__(self, input_dim, dimofbottelneck, init_dim, kernel_size,init_radius, init_sigma, group_norm):super(ResampleGAN, self).__init__()self.encoder = ResampleKPConvEncoder(input_dim, dimofbottelneck,init_dim, kernel_size,init_radius, init_sigma,group_norm)self.decoder = MLPDecoder(dimoffeat=dimofbottelneck)def forward(self, data_dict):feat = self.encoder(data_dict)points_recovered = self.decoder(feat)return points_recovered

 判别器(ResampleGAN):

        判别器输入点云中的坐标矩阵和邻点坐标信息,考虑到生成器采用不同的ARM重采样自适应,会导致改变局部的密度,所以在多尺度下(小、中、大尺度,长度分别是5,10,20)进行特征提取(特征提取使用PointNet网络),并进行特征融合,判别器的目的是判断不同层次的点是真实还是合成的。

class MultiScalePointNet(nn.Module):def __init__(self, dimoffeat=256, multiscale=[5, 10, 20]) -> None:super(MultiScalePointNet, self).__init__()self.multiscale = multiscaleself.patchpointnets = nn.ModuleList()for scale in multiscale:self.patchpointnets.append(nn.Sequential(nn.Conv1d(3, dimoffeat // 4, kernel_size=1, stride=1),nn.LeakyReLU(negative_slope=0.2),nn.Conv1d(dimoffeat // 4,dimoffeat // 2,kernel_size=1,stride=1), nn.LeakyReLU(negative_slope=0.2),nn.Conv1d(dimoffeat // 2,dimoffeat,kernel_size=1,stride=1)))self.maxpool = nn.AdaptiveMaxPool1d(output_size=1)self.sharedmlp = nn.Sequential(nn.Conv1d(len(multiscale) * dimoffeat,dimoffeat,kernel_size=1,stride=1), nn.LeakyReLU(negative_slope=0.2),nn.Conv1d(dimoffeat, dimoffeat // 2, kernel_size=1, stride=1),nn.LeakyReLU(negative_slope=0.2),nn.Conv1d(dimoffeat // 2, dimoffeat // 4, kernel_size=1, stride=1),nn.LeakyReLU(negative_slope=0.2),nn.Conv1d(dimoffeat // 4, dimoffeat // 8, kernel_size=1, stride=1),nn.LeakyReLU(negative_slope=0.2),nn.Conv1d(dimoffeat // 8, 1, kernel_size=1, stride=1))def forward(self, points, neighbor_indices):patchfeats_list = []for idx in range(len(self.multiscale)):neighbors = points[neighbor_indices[:, :self.multiscale[idx]]]  # shape (N, K, 3)neighbors = neighbors - points[:, None, :]neighbors = neighbors.transpose(1, 2)  # (N, K, 3) -> (N, 3, K)feats = self.patchpointnets[idx](neighbors)  # (N, 3, K) -> (N, d, K)patchfeats = self.maxpool(feats)  # (N, d, K) -> (N, d, 1)patchfeats = patchfeats.squeeze(-1)  # (N, d, 1) -> (N, d)patchfeats = patchfeats.transpose(0, 1)  # (N, d) -> (d, N)patchfeats_list.append(patchfeats)multiscalefeats = torch.cat(patchfeats_list,dim=0)  # m x (d, N) -> (md, N)multiscalefeats = multiscalefeats.unsqueeze(0)  # (md, N) -> (batch, md, N)out = self.sharedmlp(multiscalefeats)  # (batch, md, N) -> (batch, 1, N)out = out.squeeze(0)  # (batch, 1, N) -> (1, N)out = out.squeeze(0)return out

3、配准

        配准工作backbone使用的是GeoTransformer结构作为配准模块,并且使用GeoTransformer中提到的局部到全局的配准策略LGR策略来替换RANSAC。

        LGR可以利用所有的对应关系来估计变换矩阵,而不像RANSAC使用一部分内点而存在内点分布不均匀的影响,LGR可以更好地处理重复几何结构和低重叠比例情况。

4、损失函数

        损失函数包含两个模块,对于SIRA和点云配准两个部分分别进行训练。

        对于SIRA模块,使用倒角损失,生成器损失和判别器损失三部分来训练域自适应。

        对于配准模块,使用重叠圆损失(点对应损失)和全局点对损失两部分训练(使用的就是Geotrans的配准模块,损失也一模一样)。

四、实验

1、对比不同框架

        提前获得了一部分数据集(合成数据集)的情况下,其实效果相比GeoTransformer提升并没有很大,说明这个方法idea很好,但其实用在配准工作其实一般。

2、点云配准训练中,不同数量的数据集对性能指标的影响

        在不同的backbone下,显然Samples越少,对其他backbone影响越来越明显,对SIRA-PCR影响则很微小。性能指标包括:特征匹配召回,离群比、配准召回。不得不说这不就是因为提前吃了一遍数据集,学到了特征的影响吗。

3、其他实验

        对于FlyingShapes数据集的建立,引入structure3D效果提升,这个不太了解情况,证明了删除平面确实有效。

        消融实验中对于SIRA的不同组件以及FlyingShapes的object data和scene data进行消融。

论文参考:ICCV 2023 Open Access Repository        

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java面试--框架--Spring MVC

Spring MVC 目录 Spring MVC1.spring mvc简介2.spring mvc实现原理2.1核心组件2.2工作流程 3.RESTful 风格4.Cookie&#xff0c;Session4.1 会话4.2 保存会话的两种技术 5.拦截器5.1过滤器、监听器、拦截器的对比5.2 过滤器的实现5.3 拦截器基本概念5.4 拦截器的实现 1.spring …

Ropdump:针对二进制可执行文件的安全检测工具

关于Ropdump Ropdump是一款针对二进制可执行文件的安全检测工具&#xff0c;该工具基于纯Python开发&#xff0c;是一个命令行工具&#xff0c;旨在帮助广大研究人员检测和分析二进制可执行文件中潜在的ROP小工具、缓冲区溢出漏洞和内存泄漏等安全问题。 功能介绍 1、识别二进…

使用gpreftools测试性能

参考文献&#xff1a; C 性能分析工具调研_性能分析工具 gperf perf vergi 比较-CSDN博客性能测试工具CPU profiler(gperftools)的使用心得-CSDN博客gperftools使用方法和常见问题_pprof no nodes to print-CSDN博客c 分析 gperftools 总结 | Weakyon Blog 文章目录 安装使用 …

第2章-01-网站中的资源介绍

🏆作者简介,黑夜开发者,CSDN领军人物,全栈领域优质创作者✌,CSDN博客专家,阿里云社区专家博主,2023年CSDN全站百大博主。 🏆数年电商行业从业经验,历任核心研发工程师,项目技术负责人。 🏆本文已收录于专栏:Web爬虫入门与实战精讲。 🎉欢迎 👍点赞✍评论⭐收…

微信小程序--30(网络数据请求)

1.小程序中网络数据请求的限制 只能请求HTTPS类型的接口必须将接口的域名添加到信任列表中 2.配置request合法域名 需求描述 希望请求某个域名下的接口 步骤 登录小程序管理后台→开发→开发设置→服务器域名→修改request合法域名 练习 注意事项 域…

【Linux】yum、vim、gcc/g++的使用

目录 一、Linux 软件包管理器 yum 什么是软件包 关于 rzsz 查看软件包★ 如何安装软件★ 如何卸载软件★ Linux 开发工具 二、Linux编译器-vim使用 vim的基本概念 vim的基本操作 vim正常模式命令集 vim末行模式命令集 vim操作总结 如果在vim界面不小心按了Ctrl …

Unity的粒子系统

目录 基础参数与模块 创建与编辑 功能与应用 实例与教程 结论 Unity粒子系统的最新功能和更新有哪些&#xff1f; 如何在Unity中使用Visual Effect Graph创建复杂粒子效果&#xff1f; Unity粒子系统的高级应用技巧有哪些&#xff1f; 在Unity中实现粒子系统时的性能优…

【计算机组成原理】二、数据的表示和运算:1.数值与编码(十进制二进制转换、BCD码、ASCII码、汉字编码、奇偶校验码、循环冗余检测CRC、海明码)

二、数据的表示和运算 文章目录 二、数据的表示和运算1.数值与编码1.1数据存储和排列❗1.2十进制转换1.2.1整数1.2.2小数 1.3二进制转换1.3.1 B->O1.3.2 B->H 1.4真值&机器数1.5 BCD码1.6 ASCII码1.7汉字与GBK1.8 UTF1.9检错码1.9.1奇偶校验码1.9.2循环冗余检测CRC1.…

CentOS7设置默认免密登录用户root

CentOS7设置默认免密登录用户root 步骤1、打开要更改的 CentOS 系统2、切换到root用户2、reboot重启系统 步骤 1、打开要更改的 CentOS 系统 2、切换到root用户 2、reboot重启系统

如何基于AI大模型来做数据治理?

在数字化时代的浪潮中&#xff0c;数据治理已成为企业管理的核心议题。随着人工智能&#xff08;AI&#xff09;技术的飞速发展&#xff0c;尤其是大型语言模型&#xff08;如GPT-4&#xff09;的涌现&#xff0c;AI大模型在数据治理中的应用正逐渐成为一种创新且有效的解决方案…

LLM才硬件(显存)需求

参考&#xff1a; https://www.hardware-corner.net/guides/computer-to-run-llama-ai-model/ GitHub - hiyouga/LLaMA-Factory: Efficiently Fine-Tune 100 LLMs in WebUI (ACL 2024) 直观的一个表&#xff1a;

利用队列收集单双击和长按按键

利用队列收集单双击和长按按键 引言 当我们仅仅通过在while循环里面进行判断按键类型的标志位, 然后进行操作的时候, 我们的最小例程很小, 所以能够实时的检测到按键,从而触发实验现象. 假如我们此时进入了一个事件处理函数呢 ? 并且这个这个函数的操作是不可被打断的, 如果此…

修改Docker的默认网段

1、确认修改前docker网段 [rootkfk12 ~]# ifconfig docker0 2、修改docker配置设置网段 [rootkfk12 ~]# cat > /etc/docker/daemon.json << EOF{ "registry-mirrors": [ "https://vh3bm52y.mirror.aliyuncs.com", "https://regi…

C:每日一题:字符串左旋

题目&#xff1a;实现一个函数&#xff0c;可以实现字符串的左旋 例如&#xff1a;ABCD左旋一个字符就是BCDA&#xff1b;ABCD左旋两个字符就是CDAB&#xff1b; 1、解题思路&#xff1a; 1.确定目标旋转k个字符&#xff0c;我们要获取字符串的长度 len&#xff0c;目的是根…

PyCharm单步调试

1、先在入口设置断点&#xff0c;再点击爬虫图标&#xff08;shift F9&#xff09;开始调试 调试图标如图&#xff1a; 2、蓝色光标表示当前运行在这行 3、快捷键 F7&#xff1a;进入当前行函数 F8&#xff1a;单步 F9&#xff1a;全速运行

Nuclei文件上传小Tips

前言 Nuclei对于文件上传类型Poc编写小Tips 平台 ProjectDiscovery Cloud Platform: https://cloud.projectdiscovery.io/ JsonPath: https://jsonpath.com/ Json解析&#xff1a; 在线json解析平台即可 案例 某康resourceOperations upload接口存在前台上传 具体接口&…

财务会计与管理会计(十一)

文章目录 快速切换日记账余额SUMPRODUCT、LOOKUP函数应用 销售业绩分段统计表SUMPRODUCT函数的应用 自动打印发票签收单VLOOKUP函数的应用 快速切换日记账余额 SUMPRODUCT、LOOKUP函数应用 C2SUMPRODUCT((A5:A100B2)*C5:C100) D2SUMPRODUCT((A5:A100B2)*D5:D100) E4公式1&…

【时时三省】(C语言基础)数据的额存储

山不在高&#xff0c;有仙则名。水不在深&#xff0c;有龙则灵。 ----CSDN 时时三省 例题1: i>0恒成立 会进入死循环 因为unsigned是无符号数 所以不可能会有负数 就会进入死循环 注意:i打印的时候如果它上面类型是无符号数 但是打印是%d 它会打印有符号数 例题:2 这个循…

集团数字化转型方案(二)

集团数字化转型方案通过整合物联网&#xff08;IoT&#xff09;、大数据分析、人工智能&#xff08;AI&#xff09;和云计算技术&#xff0c;构建了一个全面智能化的业务平台&#xff0c;从而实现了全集团范围内的业务流程自动化、数据驱动决策优化、以及客户体验的个性化提升。…

如何利用Jmeter从0到1做一次完整的压测

压测&#xff0c;在很多项目中都有应用&#xff0c;是测试小伙伴必备的一项基本技能&#xff0c;刚好最近接手了一个小游戏的压测任务&#xff0c;一轮压测下来&#xff0c;颇有收获&#xff0c;赶紧记录下来&#xff0c;与大家分享一下&#xff0c;希望大家能少踩坑。 一、压…