add new comments

This commit is contained in:
lzhi 2024-07-15 01:01:54 +08:00
parent b405eb02e7
commit 47a1808453
3 changed files with 61 additions and 57 deletions

View File

@ -25,53 +25,56 @@ class GaussianModel:
def setup_functions(self):
"""
定义和初始化处理高斯体模型参数的 激活函数
定义和初始化处理高斯体模型参数的 激活函数
"""
# 定义 从尺度、旋转构建3D高斯的 协方差矩阵 的函数
def build_covariance_from_scaling_rotation(scaling, scaling_modifier, rotation):
L = build_scaling_rotation(scaling_modifier * scaling, rotation) # 从尺度、尺度的缩放、旋转得到L矩阵
actual_covariance = L @ L.transpose(1, 2) # 计算实际的协方差矩阵
symm = strip_symmetric(actual_covariance) # 提取对称部分
"""
缩放因子旋转四元数 构建 各3D高斯体的 协方差矩阵
"""
L = build_scaling_rotation(scaling_modifier * scaling, rotation) # 从缩放因子、旋转四元数得到高斯体的变化N 3 3
actual_covariance = L @ L.transpose(1, 2) # 计算实际的 协方差矩阵
symm = strip_symmetric(actual_covariance) # 提取上半对角元素
return symm
# 初始化一些激活函数
self.scaling_activation = torch.exp # 用exp函数确保尺度参数非负
self.scaling_inverse_activation = torch.log # 尺度的逆激活函数,用于梯度回传
self.scaling_activation = torch.exp # 缩放因子的激活函数exp函数确保缩放因子非负
self.scaling_inverse_activation = torch.log # 缩放因子的逆激活函数用于梯度回传log函数
self.covariance_activation = build_covariance_from_scaling_rotation # 协方差矩阵的激活函数
self.covariance_activation = build_covariance_from_scaling_rotation # 协方差矩阵的激活函数(实际未使用激活函数,直接构建)
self.opacity_activation = torch.sigmoid # 用sigmoid函数确保不透明度在0到1之间
self.opacity_activation = torch.sigmoid # 不透明的激活函数,sigmoid函数确保不透明度在0到1之间
self.inverse_opacity_activation = inverse_sigmoid # 不透明度的逆激活函数
self.rotation_activation = torch.nn.functional.normalize # 用于标准化旋转参数的函数
self.rotation_activation = torch.nn.functional.normalize # 旋转四元数的激活函数,归一化函数(取模)
def __init__(self, sh_degree : int):
"""
初始化3D高斯模型的参数
3D高斯模型的各参数 初始化为0或空
sh_degree: 设定的 球谐函数的最大阶数默认为3用于控制颜色表示的复杂度
"""
self.active_sh_degree = 0 # 当前激活的球谐阶数初始为0
self.active_sh_degree = 0 # 当前球谐函数的阶数初始为0
self.max_sh_degree = sh_degree # 允许的最大球谐阶数j
# 初始化3D高斯模型的各项参数
self._xyz = torch.empty(0) # 3D高斯的 中心位置(均值)
self._features_dc = torch.empty(0) # 第一个球谐系数,用于表示基础颜色
self._features_rest = torch.empty(0) # 其余球谐系数,用于表示颜色的细节和变化
self._scaling = torch.empty(0) # 3D高斯的尺度控制高斯的形状
self._rotation = torch.empty(0) # 3D高斯的旋转一系列四元数
self._opacity = torch.empty(0) # 3D高斯的不透明度sigmoid前的控制可见性
self.max_radii2D = torch.empty(0) # 在2D投影中每个高斯的最大半径
self._xyz = torch.empty(0) # 各3D高斯的 中心位置
self.xyz_gradient_accum = torch.empty(0) # 累积3D高斯中心位置的梯度当它太大的时候要对Gaussian进行分裂小时代表under要复制
self.denom = torch.empty(0) # 与累积梯度配合使用表示统计了多少次累积梯度算平均梯度时除掉这个denom = denominator分母
self._features_dc = torch.empty(0) # 球谐函数的直流分量,第一个元素,用于表示基础颜色
self._features_rest = torch.empty(0) # 球谐函数的高阶分量,用于表示颜色的细节和变化
self._scaling = torch.empty(0) # 各3D高斯的 缩放因子,控制高斯的形状
self._rotation = torch.empty(0) # 各3D高斯的 旋转四元数
self._opacity = torch.empty(0) # 各3D高斯的不透明度sigmoid前的控制可见性
self.max_radii2D = torch.empty(0) # 各3D高斯投影到2D平面上的 最大半径
self.xyz_gradient_accum = torch.empty(0) # 3D高斯中心位置 梯度的累及值当它太大的时候要对Gaussian进行分裂小时代表under要复制
self.denom = torch.empty(0) # 与累积梯度配合使用表示统计了多少次累积梯度用于计算每个高斯体的平均梯度时需除以它denom = denominator分母
self.optimizer = None # 优化器用于调整上述参数以改进模型论文中采用Adam见附录B Algorithm 1的伪代码
self.percent_dense = 0 # 控制Gaussian密集程度的超参数
self.spatial_lr_scale = 0 # 位置坐标的学习率要乘上这个,抵消在不同尺度下应用同一个学习率带来的问题
self.percent_dense = 0 # 百分比密度控制3D高斯的密度
self.spatial_lr_scale = 0 # 各3D高斯的位置学习率的变化因子位置的学习率 乘以它,以抵消在不同尺度下应用同一个学习率带来的问题
# 调用 setup_functions初始化处理高斯体模型参数的 激活函数
# 初始化高斯体模型参数的 激活函数
self.setup_functions()
def capture(self):
@ -109,11 +112,11 @@ class GaussianModel:
self.optimizer.load_state_dict(opt_dict)
@property
def get_scaling(self):
def get_scaling(self): # 获取的是激活后的 缩放因子
return self.scaling_activation(self._scaling)
@property
def get_rotation(self):
def get_rotation(self): # 获取的是激活后的 旋转四元数
return self.rotation_activation(self._rotation)
@property
@ -127,13 +130,14 @@ class GaussianModel:
return torch.cat((features_dc, features_rest), dim=1)
@property
def get_opacity(self):
def get_opacity(self): # 获取的是激活后的 不透明度
return self.opacity_activation(self._opacity)
def get_covariance(self, scaling_modifier = 1):
return self.covariance_activation(self.get_scaling, scaling_modifier, self._rotation)
def oneupSHdegree(self):
# 当前球谐函数的阶数 < 规定的最大阶数,则 阶数+1
if self.active_sh_degree < self.max_sh_degree:
self.active_sh_degree += 1
@ -141,17 +145,17 @@ class GaussianModel:
"""
从稀疏点云数据pcd 初始化模型参数
pcd: 稀疏点云包含点的位置和颜色
spatial_lr_scale: 空间学习率缩放因子影响 位置坐标参数的学习率
spatial_lr_scale: 位置学习率的 变化因子
"""
# 根据scene.Scene.__init__ 以及 scene.dataset_readers.SceneInfo.nerf_normalization即scene.dataset_readers.getNerfppNorm的代码
# 这个值似乎是训练相机中离它们的坐标平均值即中心最远距离的1.1倍,根据命名推断应该与学习率有关,防止固定的学习率适配不同尺度的场景时出现问题。
self.spatial_lr_scale = spatial_lr_scale
# 将点云的 位置 和 颜色 数据从numpy数组转换为PyTorch张量并传送到CUDA设备上
fused_point_cloud = torch.tensor(np.asarray(pcd.points)).float().cuda() # 稀疏点云的3D坐标大小为(P, 3)
fused_color = RGB2SH(torch.tensor(np.asarray(pcd.colors)).float().cuda()) # 球谐的直流分量,大小为(P, 3)
# RGB2SH(x) = (x - 0.5) / 0.28209479177387814看样子pcd.colors的原始范围应该是0到1。0.28209479177387814是1 / (2*sqrt(pi))是直流分量Y(l=0,m=0)的值
# 点云的3D位置从array转换为tensor并放到cuda上(N, 3)
fused_point_cloud = torch.tensor(np.asarray(pcd.points)).float().cuda()
# 点云的颜色从RGB array转换为tensor放到cuda上再转为球谐函数直流分量系数(N, 3)
fused_color = RGB2SH(torch.tensor(np.asarray(pcd.colors)).float().cuda())
# 初始化存储 球谐系数 的张量RGB三通道球谐的所有系数每个通道有(max_sh_degree + 1) ** 2个球谐系数
features = torch.zeros((fused_color.shape[0], 3, (self.max_sh_degree + 1) ** 2)).float().cuda() # (P, 3, 16)

View File

@ -78,13 +78,13 @@ def get_expon_lr_func(
def strip_lowerdiag(L):
"""
从协方差矩阵中提取六个独立参数
:param L: 协方差矩阵
:return: 六个独立参数组成的张量
从协方差矩阵中提取6个上半对角元素节省内存
[ _ _ _ ]
[ _ _ ]
[ _ ]
"""
uncertainty = torch.zeros((L.shape[0], 6), dtype=torch.float, device="cuda")
uncertainty = torch.zeros((L.shape[0], 6), dtype=torch.float, device="cuda") # N 6
# 提取协方差矩阵的独立元素
uncertainty[:, 0] = L[:, 0, 0]
uncertainty[:, 1] = L[:, 0, 1]
uncertainty[:, 2] = L[:, 0, 2]
@ -95,15 +95,15 @@ def strip_lowerdiag(L):
def strip_symmetric(sym):
"""
提取协方差矩阵的对称部分
提取协方差矩阵的上半对角元素
sym: 协方差矩阵
return: 对称部分
return: 上半对角元素
"""
return strip_lowerdiag(sym)
def build_rotation(r):
'''
旋转四元数 -> 单位化 -> 3x3的旋转矩阵
旋转四元数 -> 单位化 -> 3x3的旋转矩阵
'''
norm = torch.sqrt(r[:,0]*r[:,0] + r[:,1]*r[:,1] + r[:,2]*r[:,2] + r[:,3]*r[:,3])
@ -129,20 +129,20 @@ def build_rotation(r):
def build_scaling_rotation(s, r):
"""
构建3D高斯模型的尺度-旋转矩阵
s: 尺度参数
r: 旋转参数
构建3D高斯模型的 缩放-旋转矩阵
s: 缩放因子, N 3
r: 旋转四元素, N 4
return: 尺度-旋转矩阵
"""
L = torch.zeros((s.shape[0], 3, 3), dtype=torch.float, device="cuda") # 初始化尺度矩阵
R = build_rotation(r) # 四元数 -> 旋转矩阵
L = torch.zeros((s.shape[0], 3, 3), dtype=torch.float, device="cuda") # 初始化缩放矩阵为0N 3 3
R = build_rotation(r) # 旋转四元数 -> 旋转矩阵N 3 3
# 设置尺度矩阵的对角线元素
# 构建缩放矩阵其对角线元素对应为缩放因子的s1, s2, s3
L[:,0,0] = s[:,0]
L[:,1,1] = s[:,1]
L[:,2,2] = s[:,2]
L = R @ L # 应用旋转
L = R @ L # 高斯体的变化:旋转 矩阵乘 缩放
return L
def safe_state(silent):

View File

@ -23,7 +23,7 @@
import torch
C0 = 0.28209479177387814
C0 = 0.28209479177387814 # 球谐函数直流分量的值sqrt(1 / (4*pi))是0阶的球谐函数即直流分量Y(l=0,m=0)的值
C1 = 0.4886025119029199
C2 = [
1.0925484305920792,
@ -61,14 +61,14 @@ def eval_sh(deg, sh, dirs):
Works with torch/np/jnp.
... Can be 0 or more batch dimensions.
Args:
deg: int SH deg. Currently, 0-3 supported
sh: jnp.ndarray SH coeffs [..., C, (deg + 1) ** 2]
dirs: jnp.ndarray unit directions [..., 3]
deg: 球谐函数的 阶数这里可能为 0-3
sh: 球谐函数的 系数 [..., C, (deg + 1) ** 2]
dirs: 方向值 jnp.ndarray unit directions [..., 3]
Returns:
[..., C]
"""
assert deg <= 4 and deg >= 0
coeff = (deg + 1) ** 2
coeff = (deg + 1) ** 2 # 球谐函数当前阶数要求的系数 个数
assert sh.shape[-1] >= coeff
result = C0 * sh[..., 0]
@ -113,9 +113,9 @@ def eval_sh(deg, sh, dirs):
def RGB2SH(rgb):
"""
将RGB颜色值转换为球谐系数C0项的系数
:param rgb: RGB颜色值
:return: 转换后的球谐系数C0项的系数
将RGB颜色值 转换为 球谐系数直流分量的系数
rgb: RGB颜色值
C0球谐函数直流分量的值sqrt(1 / (4*pi))是0阶的球谐函数即直流分量Y(l=0,m=0)的值
"""
return (rgb - 0.5) / C0