当前位置:   article > 正文

3D Gaussian Splatting学习记录11.2_sibrviewers

sibrviewers

训练结果可视化的尝试

  • cmd输入以下命令,开始训练
python train.py -s ./dataset/db/drjohnson -m ./dataset/db/drjohnson/output
  • 整个训练(30,000步)大约需要20分钟,但7000步后会保存一个中间模型,效果已经很不错了。训练结束后得到output文件
  • 在Ubuntu 22.04上,运行以下命令来构建可视化工具:
  1. # Dependencies
  2. sudo apt install -y libglew-dev libassimp-dev libboost-all-dev libgtk-3-dev libopencv-dev libglfw3-dev libavdevice-dev libavcodec-dev libeigen3-dev libxxf86vm-dev libembree-dev
  3. # Project setup
  4. cd SIBR_viewers
  5. cmake -Bbuild . -DCMAKE_BUILD_TYPE=Release # add -G Ninja to build faster
  6. cmake --build build -j24 --target install
  • 安装后,找到SIBR_gaussianViewer_app二进制文件,并以模型的路径作为参数运行它:
SIBR_gaussianViewer_app -m ./dataset/db/drjohnson/output

代码细节

参考​​​​​​​AI葵的代码讲解

cuda_rasterizer文件夹中,forward.cu文件的preprocessCUDA函数

(1)计算投影出来的半径圆心等,把椭圆近似成圆;

  • line200,将3D点的矩阵投影;
  1. // Transform point by projecting
  2. float3 p_orig = { orig_points[3 * idx], orig_points[3 * idx + 1], orig_points[3 * idx + 2] };
  3. float4 p_hom = transformPoint4x4(p_orig, projmatrix);
  4. float p_w = 1.0f / (p_hom.w + 0.0000001f);
  5. float3 p_proj = { p_hom.x * p_w, p_hom.y * p_w, p_hom.z * p_w };
  • line215,计算椭球投影成椭圆的样子,用对称2D矩阵记录abbc;
  1. // Compute 2D screen-space covariance matrix
  2. float3 cov = computeCov2D(p_orig, focal_x, focal_y, tan_fovx, tan_fovy, cov3D, viewmatrix);
  • line229,求矩阵特征值,解出椭圆的半径,取长轴的半径;
  1. float mid = 0.5f * (cov.x + cov.z);
  2. float lambda1 = mid + sqrt(max(0.1f, mid * mid - det));
  3. float lambda2 = mid - sqrt(max(0.1f, mid * mid - det));
  4. float my_radius = ceil(3.f * sqrt(max(lambda1, lambda2)));
  • line243,计算每个高斯的颜色
  1. // If colors have been precomputed, use them, otherwise convert
  2. // spherical harmonics coefficients to RGB color.
  3. if (colors_precomp == nullptr)
  4. {
  5. glm::vec3 result = computeColorFromSH(idx, D, M, (glm::vec3*)orig_points, *cam_pos, shs, clamped);
  6. rgb[idx * C + 0] = result.x;
  7. rgb[idx * C + 1] = result.y;
  8. rgb[idx * C + 2] = result.z;
  9. }

(2)计算圆所覆盖的像素,即高斯对颜色的贡献。一种加速的方式是,将整张图片分割成很多16*16的小格子,将与圆有交集的格子近似;

  • line235,getRect函数计算圆覆盖了哪些tile
	getRect(point_image, my_radius, rect_min, rect_max, grid);
  • line249,保存各个值,其中tilesTouch存储了所覆盖的tile
  1. // Store some useful helper data for the next steps.
  2. depths[idx] = p_view.z;
  3. radii[idx] = my_radius;
  4. points_xy_image[idx] = point_image;
  5. // Inverse 2D covariance and opacity neatly pack into one float4
  6. conic_opacity[idx] = { conic.x, conic.y, conic.z, opacities[idx] };
  7. tiles_touched[idx] = (rect_max.y - rect_min.y) * (rect_max.x - rect_min.x);

(3)计算每个Gaussian的前后顺序(深度),还有alpha blending;

  • 排顺序,tile(32位的编号)+gaussian(32位)

cuda_rasterizer文件夹中,forward.cu文件的renderCUDA函数

(4)计算每个像素的颜色

  • line263,把每个tile当做一个block,每一个block里的thread就是tile的pixel
  1. // Main rasterization method. Collaboratively works on one tile per
  2. // block, each thread treats one pixel. Alternates between fetching
  3. // and rasterizing data.
  4. template <uint32_t CHANNELS>
  5. __global__ void __launch_bounds__(BLOCK_X * BLOCK_Y)
  6. renderCUDA(
  7. const uint2* __restrict__ ranges,
  8. const uint32_t* __restrict__ point_list,
  9. int W, int H,
  10. const float2* __restrict__ points_xy_image,
  11. const float* __restrict__ features,
  12. const float4* __restrict__ conic_opacity,
  13. float* __restrict__ final_T,
  14. uint32_t* __restrict__ n_contrib,
  15. const float* __restrict__ bg_color,
  16. float* __restrict__ out_color)
  • line295,存在共享内存里,读取一次就好
  1. // Allocate storage for batches of collectively fetched data.
  2. __shared__ int collected_id[BLOCK_SIZE];
  3. __shared__ float2 collected_xy[BLOCK_SIZE];
  4. __shared__ float4 collected_conic_opacity[BLOCK_SIZE];
  • line300,T是透过率,穿过越多gaussian就越小,小到一定程度就提前终止,contributor记录经过了多少gaussian
  1. // Initialize helper variables
  2. float T = 1.0f;
  3. uint32_t contributor = 0;
  4. uint32_t last_contributor = 0;
  5. float C[CHANNELS] = { 0 };
  • line333,d是gaussian到中心的距离,power计算点在gaussian分布的概率
  1. // Resample using conic matrix (cf. "Surface
  2. // Splatting" by Zwicker et al., 2001)
  3. float2 xy = collected_xy[j];
  4. float2 d = { xy.x - pixf.x, xy.y - pixf.y };
  5. float4 con_o = collected_conic_opacity[j];
  6. float power = -0.5f * (con_o.x * d.x * d.x + con_o.z * d.y * d.y) - con_o.y * d.x * d.y;
  7. if (power > 0.0f)
  8. continue;
  • line343,透明度随着概率的减小而减小
  1. // Eq. (2) from 3D Gaussian splatting paper.
  2. // Obtain alpha by multiplying with Gaussian opacity
  3. // and its exponential falloff from mean.
  4. // Avoid numerical instabilities (see paper appendix).
  5. float alpha = min(0.99f, con_o.w * exp(power));
  6. if (alpha < 1.0f / 255.0f)
  7. continue;
  8. float test_T = T * (1 - alpha);
  9. if (test_T < 0.0001f)
  10. {
  11. done = true;
  12. continue;
  13. }
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/101362
推荐阅读
相关标签
  

闽ICP备14008679号