3DGS学习(七)—— 自适应高斯密度控制

3DGS中的优化方案

由于初始化点云可能导致生成高斯在空间中密度过大或过小,3dgs给出一些手段来在学习过程中自适应地调控密度,具体方法有点密集化和点剪枝。

点密集化

重建过度的区域拆分大高斯

在这里插入图片描述

官方代码

    def densify_and_split(self, grads, grad_threshold, scene_extent, N=2):
        n_init_points = self.get_xyz.shape[0]
        # Extract points that satisfy the gradient condition
        padded_grad = torch.zeros((n_init_points), device="cuda")
        padded_grad[:grads.shape[0]] = grads.squeeze()
        selected_pts_mask = torch.where(padded_grad >= grad_threshold, True, False)
        selected_pts_mask = torch.logical_and(selected_pts_mask,
                                              torch.max(self.get_scaling, dim=1).values > self.percent_dense*scene_extent)

        stds = self.get_scaling[selected_pts_mask].repeat(N,1)
        means =torch.zeros((stds.size(0), 3),device="cuda")
        samples = torch.normal(mean=means, std=stds)
        rots = build_rotation(self._rotation[selected_pts_mask]).repeat(N,1,1)
        # 新生成点云信息(由大高斯分割并按一定系数缩放得到)
        new_xyz = torch.bmm(rots, samples.unsqueeze(-1)).squeeze(-1) + self.get_xyz[selected_pts_mask].repeat(N, 1)
        new_scaling = self.scaling_inverse_activation(self.get_scaling[selected_pts_mask].repeat(N,1) / (0.8*N))
        new_rotation = self._rotation[selected_pts_mask].repeat(N,1)
        new_features_dc = self._features_dc[selected_pts_mask].repeat(N,1,1)
        new_features_rest = self._features_rest[selected_pts_mask].repeat(N,1,1)
        new_opacity = self._opacity[selected_pts_mask].repeat(N,1)

        self.densification_postfix(new_xyz, new_features_dc, new_features_rest, new_opacity, new_scaling, new_rotation)

        prune_filter = torch.cat((selected_pts_mask, torch.zeros(N * selected_pts_mask.sum(), device="cuda", dtype=bool)))
        # 裁剪过程参照其不透明度值进行,裁剪掉不必要的点提高效率
        self.prune_points(prune_filter)

实现过程

  1. 获取初始点云的数量 n_init_points。
  2. 创建一个与梯度相同大小的零张量 padded_grad,并将梯度值填充到其中。
  3. 根据梯度的阈值条件和点云的缩放因子,生成一个选择点的掩码 selected_pts_mask。
  4. 将满足梯度和缩放条件的点复制 N次,并计算新的坐标、缩放、旋转和特征。
  5. 将新生成的点云和特征附加到原始点云中。
  6. 创建一个用于剪枝的过滤器prune_filter,其中包括原始点云和新生成的点云的掩码。
  7. 根据剪枝过滤器删除不需要的点。

重建不足的区域克隆小高斯

在这里插入图片描述

官方代码

    def densify_and_clone(self, grads, grad_threshold, scene_extent):
        # Extract points that satisfy the gradient condition
        selected_pts_mask = torch.where(torch.norm(grads, dim=-1) >= grad_threshold, True, False)
        selected_pts_mask = torch.logical_and(selected_pts_mask,
                                              torch.max(self.get_scaling, dim=1).values <= self.percent_dense*scene_extent)
        
        new_xyz = self._xyz[selected_pts_mask]
        new_features_dc = self._features_dc[selected_pts_mask]
        new_features_rest = self._features_rest[selected_pts_mask]
        new_opacities = self._opacity[selected_pts_mask]
        new_scaling = self._scaling[selected_pts_mask]
        new_rotation = self._rotation[selected_pts_mask]

        self.densification_postfix(new_xyz, new_features_dc, new_features_rest, new_opacities, new_scaling, new_rotation)

实现过程

  1. 根据梯度的阈值条件和点云的缩放因子,生成一个选择点的掩码 selected_pts_mask。
  2. 基于选择的点生成新的点云坐标、特征、不透明度、缩放和旋转。
  3. 将新生成的点云和特征附加到原始点云中。
  4. 调用 densification_postfix 函数对点云进行后处理。

点剪枝

将不透明度小于一定阈值的点减去,将过大的也减去,类似于正则化过程。并且在迭代一定次数后,高斯会被设置为几乎透明。这样就能有控制地增加必要的高斯密度,同时剔除多余的高斯。

官方代码

def densify_and_prune(self, max_grad, min_opacity, extent, max_screen_size):
        grads = self.xyz_gradient_accum / self.denom
        grads[grads.isnan()] = 0.0
		# 点密集化过程
        self.densify_and_clone(grads, max_grad, extent)
        self.densify_and_split(grads, max_grad, extent)

        prune_mask = (self.get_opacity < min_opacity).squeeze()
        if max_screen_size:
            big_points_vs = self.max_radii2D > max_screen_size
            big_points_ws = self.get_scaling.max(dim=1).values > 0.1 * extent
            prune_mask = torch.logical_or(torch.logical_or(prune_mask, big_points_vs), big_points_ws)
        self.prune_points(prune_mask)

        torch.cuda.empty_cache()

    def prune_points(self, mask):
        valid_points_mask = ~mask
        optimizable_tensors = self._prune_optimizer(valid_points_mask)

        self._xyz = optimizable_tensors["xyz"]
        self._features_dc = optimizable_tensors["f_dc"]
        self._features_rest = optimizable_tensors["f_rest"]
        self._opacity = optimizable_tensors["opacity"]
        self._scaling = optimizable_tensors["scaling"]
        self._rotation = optimizable_tensors["rotation"]

        self.xyz_gradient_accum = self.xyz_gradient_accum[valid_points_mask]

        self.denom = self.denom[valid_points_mask]
        self.max_radii2D = self.max_radii2D[valid_points_mask]

实现过程

  1. 上述代码根据最小不透明度和最大屏幕尺寸等条件生成剪枝掩码 prune_mask,并调用 prune_points 函数进行点云的剪枝操作。

  2. prune_points 函数根据给定的掩码 mask 对点云进行剪枝操作,将不需要的点从点云中删除,并更新相关的张量数据。

### MM3DGS-SLAM 三维重建算法实现 #### 背景介绍 MM3DGS-SLAM 是一种结合了多模态数据处理和3D高斯表示的同步定位与建图(SLAM)技术。该方法通过引入3D高斯模型来增强对环境的理解能力,特别是在复杂场景下的鲁棒性和精度方面表现出色[^1]。 #### 关键组件和技术细节 ##### 多传感器融合 为了提高系统的稳定性和准确性,MM3DGS-SLAM采用了多种类型的传感设备采集的数据作为输入源,包括但不限于RGB-D相机、激光雷达(LiDAR),以及惯性测量单元(IMU)[^2]。这些不同性质的信息被有效地整合在一起用于构建更加精确的地图。 ##### 高效特征提取与匹配 针对视觉信息部分,采用先进的深度学习框架进行语义分割和支持向量机(SVMs)分类器完成目标识别任务;对于点云数据,则运用迭代最近点(ICP)算法及其变体寻找最佳配准变换矩阵,从而实现场景间的精准对应关系建立[^3]。 ##### 动态优化求解过程 整个系统的核心在于其独特的动态优化机制——即利用扩展卡尔曼滤波(EKF)/粒子滤波(PF)等贝叶斯估计理论指导下的状态更新策略,配合自适应权重调整方案确保全局最优解收敛速度更快的同时保持局部一致性良好特性不变。 ```python import numpy as np from scipy.spatial.transform import Rotation as R def ekf_update(x, P, z, H, R_matrix): """ EKF Update Step 参数: x (numpy.ndarray): 当前的状态向量. P (numpy.ndarray): 协方差矩阵. z (numpy.ndarray): 测量值. H (numpy.ndarray): 观测函数雅可比矩阵. R_matrix (numpy.ndarray): 测量噪声协方差. 返回: tuple: 更新后的状态向量和协方差矩阵. """ y = z - H @ x # 计算残差 S = H @ P @ H.T + R_matrix # 创造预测误差协方差 K = P @ H.T @ np.linalg.inv(S) # 计算卡尔曼增益 x_new = x + K @ y # 更新状态估计 I = np.eye(len(x)) P_new = (I - K @ H) @ P # 更新协方差矩阵 return x_new, P_new ``` ##### 地图表达形式 最终生成的地图不仅限于传统的二维栅格地图或是简单的三角网格表面,而是以概率密度分布的形式呈现出来,这使得机器人能够更好地理解周围空间中存在的不确定性因素,并据此做出更合理的决策动作.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蜡笔小新配吉良吉影

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值