4
0
mirror of https://github.com/nerfstudio-project/nerfstudio.git synced 2026-11-11 10:34:29 +08:00
nerfstudio/nerfactory/dataloaders/pixel_sampler.py
Ethan Weber 0b042be956
Pipeline v2 (#258)
* Model class done, pipeline class still needs more visualization stuffs

* Renaming the BaseDataContainer to DataloaderOutputs and adding documentation

* Pushing more documentation, removing some trivial functions

* Updating dict typing

* Removing config dicts for collider

* Passing tests

* Pushing shell new dataloader

* Saving work, need to fix NGP model's get_loss_dict and Pipeline

* V1 of the ngp pipeline should be done. Need train script and debugging

* Updating with latest instant-ngp code

* Syntax updates from latest ngp graph code

* Linter, removing unneeded code in new NGP graph code

* Style

* Should be good now. Linter is happy and the code is verbatum current instant-ngp

* Everything done except novel view testing code

* Fixing some nitpicks

* Debugging dataloader

* merged master

* WOP. integrating pipeline with configs and notebook demo

* removing model folder

* a lot of name changing from Graph to Model

* in progress... changing trainer to use pipeline... broken right now

* pipeline code runs

* switched to val dataset

* makes run_eval.py work

* updated configs for pipeline change

* fixing test_run_train script

* fixing black and linting

* fix docs

* small updates to trainer

Co-authored-by: Jake Austin <jake-austin@berkeley.edu>
2022-08-10 14:59:45 -07:00

85 lines
3.0 KiB
Python

# Copyright 2022 The Plenoptix Team. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
Code for sampling pixels.
"""
import random
import torch
def collate_image_dataset_batch(batch, num_rays_per_batch, keep_full_image: bool = False):
"""
Operates on a batch of images and samples pixels to use for generating rays.
Returns a collated batch which is input to the Graph.
It will sample only within the valid 'mask' if it's specified.
"""
device = batch["image"].device
num_images, image_height, image_width, _ = batch["image"].shape
# only sample within the mask, if the mask is in the batch
if "mask" in batch:
nonzero_indices = torch.nonzero(batch["mask"][..., 0], as_tuple=False)
chosen_indices = random.sample(range(len(nonzero_indices)), k=num_rays_per_batch)
indices = nonzero_indices[chosen_indices]
else:
indices = torch.floor(
torch.rand((num_rays_per_batch, 3), device=device)
* torch.tensor([num_images, image_height, image_width], device=device)
).long()
c, y, x = (i.flatten() for i in torch.split(indices, 1, dim=-1))
image = batch["image"][c, y, x]
mask, semantics = None, None
if "mask" in batch:
mask = batch["mask"][c, y, x]
if "semantics" in batch:
semantics = batch["semantics"][c, y, x]
assert image.shape == (num_rays_per_batch, 3), image.shape
# Needed to correct the random indices to their actual camera idx locations.
local_indices = indices.clone()
indices[:, 0] = batch["image_idx"][c]
collated_batch = {
"local_indices": local_indices, # local to the batch returned
"indices": indices, # with the abs camera indices
"image": image,
}
if mask is not None:
collated_batch["mask"] = mask
if semantics is not None:
collated_batch["semantics"] = semantics
if keep_full_image:
collated_batch["full_image"] = batch["image"]
return collated_batch
class PixelSampler: # pylint: disable=too-few-public-methods
"""Samples 'pixel_batch's from 'image_batch's."""
def __init__(self, num_rays_per_batch, keep_full_image=False) -> None:
self.num_rays_per_batch = num_rays_per_batch
self.keep_full_image = keep_full_image
def sample(self, image_batch):
"""Sample an image batch and return a pixel batch."""
pixel_batch = collate_image_dataset_batch(
image_batch, self.num_rays_per_batch, keep_full_image=self.keep_full_image
)
return pixel_batch