Convert NeRFW fine network output to rendered colors This version is implemented in nerf_pl https://github.com/kwea123/nerf_pl/tree/nerfw Inputs: raw: torch.Tensor() [N_rays, N_samples, 9]
(raw, z_vals, rays_d, raw_noise_std=0, output_transient=False, beta_min=0.1, white_bkgd=False, test_time=False, static_only=True, typ="coarse")
| 130 | return rgb_map, disp_map, acc_map, weights, depth_map |
| 131 | |
| 132 | def raw2outputs_NeRFW(raw, z_vals, rays_d, raw_noise_std=0, output_transient=False, beta_min=0.1, white_bkgd=False, test_time=False, static_only=True, typ="coarse"): |
| 133 | ''' Convert NeRFW fine network output to rendered colors |
| 134 | This version is implemented in nerf_pl https://github.com/kwea123/nerf_pl/tree/nerfw |
| 135 | Inputs: |
| 136 | raw: torch.Tensor() [N_rays, N_samples, 9] |
| 137 | |
| 138 | ''' |
| 139 | |
| 140 | if typ=="coarse" and test_time: |
| 141 | static_sigmas = raw[..., 0] |
| 142 | transient_sigmas = None |
| 143 | else: |
| 144 | if output_transient==False: |
| 145 | N_rays, N_samples, ch = raw.size() |
| 146 | ch_rgbs = ch - 1 # rgb sigma - sigma channel. for rgb: ch_rgbs = 3, for feature: ch_rgbs = args.out_channel_size |
| 147 | else: |
| 148 | N_rays, N_samples, ch = raw.size() |
| 149 | ch_rgbs = (ch - 3) // 2 # rgb sigma - static_sigma - transient_sigmas - transient_betas channels |
| 150 | |
| 151 | static_rgbs = raw[..., :ch_rgbs] # (N_rays, N_samples, 3), [..., 0:3] |
| 152 | static_sigmas = raw[..., ch_rgbs] # (N_rays, N_samples) [..., 3] |
| 153 | if output_transient: |
| 154 | transient_rgbs = raw[..., ch_rgbs + 1: 2 * ch_rgbs + 1] # [..., 4:7] |
| 155 | transient_sigmas = raw[..., 2 * ch_rgbs + 1] # [..., 7] |
| 156 | transient_betas = raw[..., 2 * ch_rgbs + 2] # [..., 8] |
| 157 | else: |
| 158 | transient_sigmas = None |
| 159 | |
| 160 | # Convert these values using volume rendering |
| 161 | deltas = z_vals[:, 1:] - z_vals[:, :-1] # (N_rays, N_samples_-1) |
| 162 | delta_inf = 1e2 * torch.ones_like(deltas[:, :1]) # (N_rays, 1) the last delta is infinity, nerf used 1e10 |
| 163 | |
| 164 | # In original NeRF, Multiply each distance by the norm of its corresponding direction ray |
| 165 | # but not in this implementation |
| 166 | deltas = torch.cat([deltas, delta_inf], -1) # (N_rays, N_samples_) [32768, 128] |
| 167 | |
| 168 | if output_transient: |
| 169 | static_alphas = 1-torch.exp(-deltas*static_sigmas) |
| 170 | transient_alphas = 1-torch.exp(-deltas*transient_sigmas) |
| 171 | alphas = 1-torch.exp(-deltas*(static_sigmas+transient_sigmas)) |
| 172 | else: |
| 173 | noise = torch.randn_like(static_sigmas) * raw_noise_std |
| 174 | alphas = 1-torch.exp(-deltas*torch.relu(static_sigmas+noise)) |
| 175 | |
| 176 | alphas_shifted = \ |
| 177 | torch.cat([torch.ones_like(alphas[:, :1]), 1-alphas], -1) # [1, 1-a1, 1-a2, ...] |
| 178 | transmittance = torch.cumprod(alphas_shifted[:, :-1], -1) # [1, 1-a1, (1-a1)(1-a2), ...] |
| 179 | |
| 180 | if output_transient: |
| 181 | static_weights = static_alphas * transmittance |
| 182 | transient_weights = transient_alphas * transmittance |
| 183 | |
| 184 | weights = alphas * transmittance |
| 185 | weights_sum = reduce(weights, 'n1 n2 -> n1', 'sum') |
| 186 | acc_map = weights_sum |
| 187 | |
| 188 | if typ=="coarse" and test_time: |
| 189 | rgb_map=None |