3 模型构建
3.4 根据梯度对3D gaussian 进行增加或删减
(1) 对3D高斯分布进行密集化和修剪的操作
def densify_and_prune(self, max_grad, min_opacity, extent, max_screen_size):
"""
对3D高斯分布进行密集化和修剪的操作
:param max_grad: 梯度的最大阈值,用于判断是否需要克隆或分割。
:param min_opacity: 不透明度的最小阈值,低于此值的3D高斯将被删除。
:param extent: 场景的尺寸范围,用于评估高斯分布的大小是否合适。
:param max_screen_size: 最大屏幕尺寸阈值,用于修剪过大的高斯分布。
"""
# 计算3D高斯中心的累积梯度并修正NaN值
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)
# 创建修剪掩码以删除不必要的3D高斯分布
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)
# 清理CUDA缓存以释放资源
torch.cuda.empty_cache()
这是一个用于密集化和修剪3D高斯分布的函数 densify_and_prune,其作用是根据梯度、不透明度、尺寸范围以及屏幕尺寸等参数来动态调整和优化3D高斯分布。
- max_grad: 定义梯度的最大阈值,用于判断高斯分布是否需要进一步克隆或分割。
- min_opacity: 定义不透明度的最小阈值,低于该值的高斯分布将被删除。
- extent: 定义场景的总体尺寸范围,用来评估高斯分布的大小是否在合理范围内。
- max_screen_size: 定义屏幕上的最大显示尺寸阈值,用于修剪尺寸过大的高斯分布。
功能描述
计算梯度并处理 NaN 值:
- 函数首先计算每个3D高斯中心点的累积梯度,并将任何 NaN 值替换为 0,以避免异常值影响密集化过程。
密集化操作:
- 使用
densify_and_clone
和densify_and_split
函数,根据梯度和尺寸范围的条件,来进行高斯分布的克隆和分割操作,使得数据表示更加密集,并有利于提高信息捕获效率。修剪掩码的创建:
- 生成一个
prune_mask
掩码,根据不透明度阈值min_opacity
来筛选出不符合条件的3D高斯。- 若
max_screen_size
存在,函数会额外考虑屏幕尺寸阈值,确保尺寸过大的高斯点也会被修剪掉。这里big_points_vs
和big_points_ws
用于检测高斯在屏幕和世界坐标下的尺寸是否超过限制。应用修剪掩码:
- 使用
prune_points
方法删除符合掩码条件的3D高斯分布,减少冗余并优化性能。清理 CUDA 缓存:
- 最后,通过
torch.cuda.empty_cache()
清理 GPU 缓存,释放未使用的显存资源,以确保内存占用最小化并提高计算效率。此函数适用于3D场景的稠密表示和资源优化,通过密集化和修剪操作,有效提升了3D高斯分布的适应性和计算性能,适合动态场景中的高效数据处理。
(2)删除不符合要求的3D高斯分布
def prune_points(self, mask):
"""
删除不符合要求的3D高斯分布。
:param mask: 一个布尔张量,表示需要删除的3D高斯分布。
"""
# 生成有效点的掩码并更新优化器中的参数
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]
(3) 删除不符合要求的3D高斯分布在优化器中对应的参数
def _prune_optimizer(self