Gaussian_model
讨论Gaussian_model这个类,是因为里面包含了三维高斯分布的基本信息,里面定义了各种参量的构建方式、用于优化学习的激活函数、学习率设置方法和高斯点优化过程中的增加与删除方式及对应优化器的处理方法。这个类定义在scene文件夹中的gaussian_module.py文件里。
scene/gaussian_model中进行函数构建

协方差矩阵和各种参数的激活函数
首先这个方法构建了协方差矩阵,而其中旋转、缩放矩阵在以下文件中:
utils/general_utils的build_rotation中构建旋转矩阵
'''
用来计算四元数表示的旋转矩阵(Rotation Matrix)的。。
首先,通过计算每个四元数的模长,来标准化它们。这是为了确保旋转向量(四元数)的单位长度,以便于正确地进行旋转计算。
接着,将标准化后的四元数应用到旋转矩阵上。这里,代码创建了一个大小为 (batch_size, 3, 3) 的零张量 R,然后,通过四元数的各个分量进行矩阵赋值,根据四元数到旋转矩阵的转换公式来填充这个张量。
最后,返回填充完的旋转矩阵 R。
需要注意的是,这段代码是针对批处理的,因此输入 r 是一个张量,其中每一行代表一个四元数。
'''
def build_rotation(r):
norm = torch.sqrt(r[:,0]*r[:,0] + r[:,1]*r[:,1] + r[:,2]*r[:,2] + r[:,3]*r[:,3])
q = r / norm[:, None]
R = torch.zeros((q.size(0), 3, 3), device='cuda')
r = q[:, 0]
x = q[:, 1]
y = q[:, 2]
z = q[:, 3]
R[:, 0, 0] = 1 - 2 * (y*y + z*z)
R[:, 0, 1] = 2 * (x*y - r*z)
R[:, 0, 2] = 2 * (x*z + r*y)
R[:, 1, 0] = 2 * (x*y + r*z)
R[:, 1, 1] = 1 - 2 * (x*x + z*z)
R[:, 1, 2] = 2 * (y*z - r*x)
R[:, 2, 0] = 2 * (x*z - r*y)
R[:, 2, 1] = 2 * (y*z + r*x)
R[:, 2, 2] = 1 - 2 * (x*x + y*y)
return R
utils/general_utils的build_scaling_rotation中构建缩放矩阵并将旋转矩阵和缩放矩阵合并
def build_scaling_rotation(s, r):
L = torch.zeros((s.shape[0], 3, 3), dtype=torch.float, device="cuda")
R = build_rotation(r)
L[:,0,0] = s[:,0]
L[:,1,1] = s[:,1]
L[:,2,2] = s[:,2]
L = R @ L
return L
scene/gaussian_model的setup_functions中用build_covariance_from_scaling_rotation中将旋转矩阵和缩放矩阵合并并处理成协方差矩阵。并在setup_functions中设定激活函数。
def setup_functions(self):
def build_covariance_from_scaling_rotation(scaling, scaling_modifier, rotation):
L = build_scaling_rotation(scaling_modifier * scaling, rotation)
actual_covariance = L @ L.transpose(1, 2)
symm = strip_symmetric(actual_covariance)
return symm
self.scaling_activation = torch.exp
self.scaling_inverse_activation = torch.log
self.covariance_activation = build_covariance_from_scaling_rotation
self.opacity_activation = torch.sigmoid
self.inverse_opacity_activation = inverse_sigmoid
self.rotation_activation = torch.nn.functional.normalize
'''
self.scaling_activation = torch.exp:这行代码将指数函数 torch.exp 赋值给了 self.scaling_activation。这意味着在网络中,会使用指数函数作为缩放操作的激活函数。
self.scaling_inverse_activation = torch.log:这行代码将对数函数 torch.log 赋值给了 self.scaling_inverse_activation。这表示在网络中,会使用对数函数作为缩放的逆操作的激活函数。
self.covariance_activation = build_covariance_from_scaling_rotation:这行代码将一个函数 build_covariance_from_scaling_rotation 赋值给了 self.covariance_activation。这可能是一个自定义的函数,用于构建协方差矩阵,该函数可能会使用了缩放和旋转操作。
self.opacity_activation = torch.sigmoid:这行代码将 sigmoid 函数 torch.sigmoid 赋值给了 self.opacity_activation。这表示在网络中,会使用 sigmoid 函数作为不透明度的激活函数。
self.inverse_opacity_activation = inverse_sigmoid:这行代码将一个函数 inverse_sigmoid 赋值给了 self.inverse_opacity_activation。这可能是一个自定义的函数,用于计算 sigmoid 函数的逆操作。
self.rotation_activation = torch.nn.functional.normalize:这行代码将归一化函数 torch.nn.functional.normalize 赋值给了 self.rotation_activation。这表示在网络中,会使用归一化函数作为旋转操作的激活函数。
'''
点云数据的处理
初始化参数的含义:
def __init__(self, sh_degree: int):
# 初始化球谐函数相关的度数
# 初始化当前活动的球谐函数度数为 0,并将最大球谐函数度数设置为传入的 sh_degree 参数。
self.active_sh_degree = 0
self.max_sh_degree = sh_degree
# 初始化存储点、球谐函数系数、缩放、旋转、不透明度等的张量为空张量
self._xyz = torch.empty(0)
self._features_dc = torch.empty(0)
self._features_rest = torch.empty(0)
self._scaling = torch.empty(0)
self._rotation = torch.empty(0)
self._opacity = torch.empty(0)
# 初始化高斯分布投影后的最大二维半径、梯度累积器(用于辨别是否需要新增和删除高斯)和分母张量(表示统计了多少次累计梯度,最后要把这个分母张量除掉)为空张量
self.max_radii2D = torch.empty(0)
self.xyz_gradient_accum = torch.empty(0)
self.denom = torch.empty(0)
# 初始化优化器optimizer为 None
self.optimizer = None
# 初始化密度百分比和空间学习率缩放因子(用于处理不同参数对学习率的要求)
self.percent_dense = 0
self.spatial_lr_scale = 0
# 调用设置函数的方法进行必要的初始化
self.setup_functions()
scene/gaussian_model的create_from_pcd
def create_from_pcd(self, pcd : BasicPointCloud, spatial_lr_scale : float):
self.spatial_lr_scale = spatial_lr_scale
# 将点云数据中的点坐标转换为 PyTorch 张量,并放置在 GPU 上进行加速处理
fused_point_cloud = torch.tensor(np.asarray(pcd.points)).float().cuda()
'''
球谐函数这一堆写在另一个文件里。
'''
print("Number of points at initialisation : ", fused_point_cloud.shape[0])
# 计算点云中每个点与原点的欧氏距离的平方,并将其限制在一个最小值以上,以避免出现除以零的情况
'''
这行代码使用了函数 distCUDA2 来计算点云中每个点之间的距离,并将结果存储在 dist2 变量中。
torch.from_numpy(np.asarray(pcd.points)).float().cuda() 将点云数据转换为 PyTorch 张量,并将其移到 GPU 上。
torch.clamp_min 函数用于将 dist2 中的所有元素的最小值限制为 0.0000001,以确保不会出现零距离。
'''
dist2 = torch.clamp_min(distCUDA2(torch.from_numpy(np.asarray(pcd.points)).float().cuda()), 0.0000001)
'''
这行代码首先计算了 dist2 中每个元素的平方根,然后取其自然对数。
[..., None] 用于在张量的最后一个维度上添加一个新的维度。
repeat(1, 3) 表示沿着第一个维度将张量复制三次,以便将其扩展为与 fused_point_cloud 相同的形状,其中 fused_point_cloud 是点云的坐标。
最终,scales 是一个与 fused_point_cloud 具有相同形状的张量,用于存储每个点的缩放因子。
'''
scales = torch.log(torch.sqrt(dist2))[...,None].repeat(1, 3)
'''
这行代码创建了一个形状为 (点数, 4) 的全零张量 rots,用于存储点云中每个点的旋转信息。
每个点的旋转信息是一个四维向量,其中第一个元素为1,其余元素为0,表示点云中的每个点都没有旋转。
'''
rots = torch.zeros((fused_point_cloud.shape[0], 4), device="cuda")
'''
这行代码将 rots 张量的第一列(即第一个元素)设置为1,以表示每个点的旋转信息中的第一个元素为1,其余元素为0,即单位四元数。
'''
rots[:, 0] = 1
# 计算每个点的不透明度,这里使用了一个 sigmoid 函数的逆函数
opacities = inverse_sigmoid(0.1 * torch.ones((fused_point_cloud.shape[0], 1), dtype=torch.float, device="cuda"))
# 将点云的坐标、特征、尺度、旋转和不透明度分别存储为对象的参数,并设置为可训练
self._xyz = nn.Parameter(fused_point_cloud.requires_grad_(True))
self._features_dc = nn.Parameter(features[:,:,0:1].transpose(1, 2).contiguous().requires_grad_(True))
self._features_rest = nn.Parameter(features[:,:,1:].transpose(1, 2).contiguous().requires_grad_(True))
self._scaling = nn.Parameter(scales.requires_grad_(True))
self._rotation = nn.Parameter(rots.requires_grad_(True))
self._opacity = nn.Parameter(opacities.requires_grad_(True))
# 初始化一个用于存储二维最大半径的张量,其形状与点云的数量相同
self.max_radii2D = torch

最低0.47元/天 解锁文章
2933

被折叠的 条评论
为什么被折叠?



