nerf_factory源码笔记(三)
本文最后更新于70 天前,其中的信息可能已经过时,如有错误请发送邮件到chengyulong@csu.edu.cn

这一节主要讲nerf中的位置编码以及体渲染函数两部分:

  1. 位置编码

    位置编码是nerf取得成功的原因之一,因为研究表明神经网络中更加倾向于学习到低频特征,而难以学习到高频特征,进而丢失较多的细节。因此nerf对采样后输入的点和视角方向都进行位置编码。

    根据原文所述,编码公式为:

    其中:

    对于采样后的点,输入的视角方向

    那假设x的维度是,那么编码后应该是,与前面所说的输入维度相对应。

    同理对于应该是

    具体代码如下:

    def pos_enc(x, min_deg, max_deg):
        scales = torch.tensor([2**i for i in range(min_deg, max_deg)]).type_as(x)  # 对于sin和cos中的各个维度的系数
        #例如L=4的话scales=[1,2,4,8]
        xb = torch.reshape((x[..., None, :] * scales[:, None]), list(x.shape[:-1]) + [-1])  # 利用广播策略做矩阵元素对应相乘
        #  xb维度为(B,4,3)
        four_feat = torch.sin(torch.cat([xb, xb + 0.5 * np.pi], dim=-1))  #  分别求sin和cos,最后拼接在一起  four_feat维度为[B,4,6]
        return torch.cat([x] + [four_feat], dim=-1)  # 最后和自身拼接得到最后结果 [B,27]
    

     

  2. 体渲染函数:

    首先我们回顾论文中给出的公式:


    具体函数为:

    def volumetric_rendering(rgb, density, t_vals, dirs, white_bkgd):
    
        eps = 1e-10
    
        dists = torch.cat(
            [
                t_vals[..., 1:] - t_vals[..., :-1],
                torch.ones(t_vals[..., :1].shape, device=t_vals.device) * 1e10,
            ],
            dim=-1,
        )
        dists = dists * torch.norm(dirs[..., None, :], dim=-1)
        #  计算光线采样点之间的实际距离(采样点距离与方向向量范数相乘)
        alpha = 1.0 - torch.exp(-density[..., 0] * dists)
        #  计算alpha即透明度
        accum_prod = torch.cat(
            [
                torch.ones_like(alpha[..., :1]),
                torch.cumprod(1.0 - alpha[..., :-1] + eps, dim=-1),
            ],
            dim=-1,
        )  # 计算T
    
        weights = alpha * accum_prod  # 计算权重ω
    
        comp_rgb = (weights[..., None] * rgb).sum(dim=-2)  # 把整个同一光线上的所有采样点合在一起,得到最终值
        depth = (weights * t_vals).sum(dim=-1)  # 计算最后的加权深度值
        acc = weights.sum(dim=-1)  # 每条光线的加权值
        inv_eps = 1 / eps
    
        if white_bkgd:
            comp_rgb = comp_rgb + (1.0 - acc[..., None])  
    
        return comp_rgb, acc, weights
    

     

这其中alpha代表为每个点的透明度,那么1-alpha则为

根据指数函数的性质:

所以:

    accum_prod = torch.cat(
        [
            torch.ones_like(alpha[..., :1]),
            torch.cumprod(1.0 - alpha[..., :-1] + eps, dim=-1),
        ],
        dim=-1,
    ) 

通过torch.cumprod函数进行累成求积得到

weights = alpha * accum_prod得到权重

然后进行每条光线上的所有采样点求和得到最终的rgb

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇