mirror of
https://github.com/graphdeco-inria/gaussian-splatting
synced 2025-03-31 07:36:51 +00:00
add new comments
This commit is contained in:
parent
b405eb02e7
commit
47a1808453
@ -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)
|
||||
|
@ -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") # 初始化缩放矩阵为0,N 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):
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user