o
    oiF#                     @  s   d dl mZ d dlZd dlmZ d dlmZ d dlZd dlm  m	Z
 d dlmZ d dlmZmZmZ d dlmZ d dlmZ d d	lmZ d d
lmZ d dlmZmZ d dlmZ d dlmZ ee Z!G dd dZ"dS )    )annotationsN)datetime)cast)optim)ModuleTensortensor)KORNIA_CHECK)PinholeCamera)psnr)Images)
RayDatasetinstantiate_ray_dataloader)	NerfModel)
deprecatedc                   @  sn   e Zd ZdZd.dd	Z	
	
	d/d0ddZedd d!	
	
	d/d0d"d#Zed1d%d&Z	d2d'd(Z
d3d4d+d,Zd-S )5
NerfSolverzNeRF solver class.

    Args:
        device: device for class tensors: Union[str, Device]
        dtype: type for all floating point calculations: torch.dtype

    devicetorch.devicedtypetorch.dtypereturnNonec                 C  sL   d | _ d| _d| _d| _d | _d | _d| _d| _d | _d | _	|| _
|| _d S )N        Tr   )_cameras
_min_depth
_max_depth_ndc_imgs_num_img_rays_batch_size_num_ray_points_nerf_model_nerf_optimizer_device_dtype)selfr   r    r&   K/home/ubuntu/.local/lib/python3.10/site-packages/kornia/nerf/nerf_solver.py__init__1   s   
zNerfSolver.__init__TMbP?camerasr
   	min_depthfloat	max_depthndcboolimgsr   num_img_raysTensor | int
batch_sizeintnum_ray_pointsirregular_ray_samplinglog_space_encodinglrc                 C  s   || _ || _|| _|| _|| _tt|to|dkd tt|to$|dkd t|dud t|tr=t|g|j	 | _
nt|rF|| _
ntd|| _t||	|
d| _| jj| j| jd tj| j |d	| _dS )
a  Initialize training settings and model.

        Args:
            cameras: Scene cameras in the order of input images.
            min_depth: sampled rays minimal depth from cameras.
            max_depth: sampled rays maximal depth from cameras.
            ndc: convert ray parameters to normalized device coordinates.
            imgs: Scene 2D images (one for each camera).
            num_img_rays: Number of rays to randomly cast from each camera: math: `(B)`.
            batch_size: Number of rays to sample in a batch.
            num_ray_points: Number of points to sample along rays.
            irregular_ray_sampling: Whether to sample ray points irregularly.
            log_space_encoding: Whether frequency sampling should be log spaced.
            lr: Learning rate.

        r   z%batch_size must be a positive integerz)num_ray_points must be a positive integerNznum_img_rays must be specifiedz-num_img_rays can be either an int or a Tensor)r6   r7   r   r   )r8   )r   r   r   r   r   r	   
isinstancer4   r   r3   r   torch	is_tensor	TypeErrorr   r   r!   tor#   r$   r   Adam
parametersr"   r%   r*   r+   r-   r.   r0   r1   r3   r5   r6   r7   r8   r&   r&   r'   setup_solverP   s2   

zNerfSolver.setup_solverrB   z0.7.0)replace_withversionc                 C  s"   |  |||||||||	|
| d S )N)rB   rA   r&   r&   r'   init_training   s   zNerfSolver.init_trainingModule | Nonec                 C  s   | j S )zReturns the NeRF model.)r!   )r%   r&   r&   r'   
nerf_model   s   zNerfSolver.nerf_modelc                 C  sN  t | jdud t | jdud t | jdud t | jdud t | jdud tt| j}tt| j}tt	| j}tt
| j}ttj| j}t|| j| j| j| j| jd}|| || t|| jdd	}tjd
| j| jd}d}	|D ](\}
}}||
|}t||}|t||d7 }|  |  |  |	d7 }	qvt||	d  S )a  Trains the NeRF model one epoch.

        1) A dataset of rays is initialized, and sent over to a data loader.
        2) The data loader sample a batch of rays randomly, and runs them through the NeRF model,
        to predict ray associated rgb model values.
        3) The model rgb is compared with the image pixel rgb, and the loss between the two is back
        propagated to update the model weights.

        Implemented steps:
            - Create an object of class RayDataset
            - Initialize ray dataset with group of images on disk, and number of rays to randomly sample
            - Initialize a data loader with batch size info
            - Iterate over data loader
            -- Reset optimizer
            -- Run ray batch through Nerf model
            -- Find loss
            -- Back propagate loss
            -- Optimizer step

        Returns:
            Average psnr over all epoch rays.

        Nz!The model should be a NeRF model.z*The optimizer should be an Adam optimizer.z%The camera should be a PinholeCamera.z'The images should be a list of tensors.z/The number of images of Ray should be a tensor.r9   T)shuffler   r   g      ?   ) r	   r!   r"   r   r   r   r   r
   r   r   r   r   	Optimizerr   r   r   r   r#   r$   init_ray_datasetinit_images_for_trainingr   r   r;   r   Fmse_lossr   	zero_gradbackwardstepr,   )r%   r*   r1   imagesrG   nerf_optimizerray_datasetray_data_loader
total_psnri_batchorigins
directionsrgbs
rgbs_modellossr&   r&   r'   _train_one_epoch   s6   



zNerfSolver._train_one_epochrI   
num_epochsc                 C  sD   t |D ]}|  }|d dkrt d}td||| qdS )zjRun training epochs.

        Args:
            num_epochs: number of epochs to run. Default: 1.

        
   r   z%H:%M:%Sz$Epoch: %d: epoch_psnr = %f; time: %sN)ranger]   r   nowstrftimeloggerinfo)r%   r^   i_epoch
epoch_psnrcurrent_timer&   r&   r'   run   s   zNerfSolver.runN)r   r   r   r   r   r   )TTr)   )r*   r
   r+   r,   r-   r,   r.   r/   r0   r   r1   r2   r3   r4   r5   r4   r6   r/   r7   r/   r8   r,   r   r   )r   rF   )r   r,   )rI   )r^   r4   r   r   )__name__
__module____qualname____doc__r(   rB   r   rE   propertyrG   r]   rh   r&   r&   r&   r'   r   (   s     
)
A
Ar   )#
__future__r   loggingr   typingr   r;   torch.nn.functionalnn
functionalrM   r   kornia.corer   r   r   kornia.core.checkr	   kornia.geometry.camerar
   kornia.metricsr   kornia.nerf.corer   kornia.nerf.data_utilsr   r   kornia.nerf.nerf_modelr   kornia.utilsr   	getLoggerri   rc   r   r&   r&   r&   r'   <module>   s"   
