o
    oi                  
   @   s*  d dl mZmZmZmZmZmZ d dlZd dlm	Z	m
Z
mZmZ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mZ d dlmZmZ d d	lmZmZmZ eeeee f Z d
ee! deee"  fddZ#d
ee! deee  fddZ$G dd dee  Z%dde%de&de'de
e  fddZ(dS )    )TYPE_CHECKINGListOptionalSequenceTupleUnionN)BatchSampler
DataLoaderDatasetRandomSamplerSequentialSampler)	TypeGuard)DeviceTensorstack)PinholeCamera)ImageLoadType
load_image)ImagesImageTensors)RandomRaySampler
RaySamplerUniformRaySamplerlstreturnc                 C      t | totdd | D S )Nc                 s       | ]}t |tV  qd S N
isinstancestr.0x r$   J/home/ubuntu/.local/lib/python3.10/site-packages/kornia/nerf/data_utils.py	<genexpr>"       z"_is_list_of_str.<locals>.<genexpr>r   listallr   r$   r$   r%   _is_list_of_str!      r,   c                 C   r   )Nc                 s   r   r   r   r   r!   r$   r$   r%   r&   &   r'   z&_is_list_of_tensors.<locals>.<genexpr>r(   r+   r$   r$   r%   _is_list_of_tensors%   r-   r/   c                       s   e Zd ZdZdedededededej	dd	f fd
dZ
d"dee dd	fddZdedd	fddZdedd	fddZd#ddZdedd	fddZdedd	fddZedee dee fddZdefddZdeeee f defd d!Z  ZS )$
RayDataseta  Class to represent a dataset of rays.

    Args:
        cameras: scene cameras: PinholeCamera
        min_depth: sampled rays minimal depth from cameras: float
        max_depth: sampled rays maximal depth from cameras: float
        ndc: convert ray parameters to normalized device coordinates: bool
        device: device for ray tensors: Union[str, torch.device]
        dtype: type of ray tensors: torch.dtype

    cameras	min_depth	max_depthndcdevicedtyper   Nc                    s>   t    d | _d | _|| _|| _|| _|| _|| _|| _	d S r   )
super__init___ray_sampler_imgs_cameras
_min_depth
_max_depth_ndc_device_dtype)selfr1   r2   r3   r4   r5   r6   	__class__r$   r%   r8   6   s   

zRayDataset.__init__num_img_raysc                 C   s"   |du r
|    dS | | dS )zInitialize a ray dataset.

        Args:
            num_img_rays: If not None, number of rays to randomly cast from each camera: math: `(B)`.

        N)_init_uniform_ray_dataset_init_random_ray_datasetrA   rD   r$   r$   r%   init_ray_datasetC   s   zRayDataset.init_ray_datasetimgsc                    sb     | t|r |}nt|r|}n
tdt| d |  fdd|D  _dS )zInitialize images for training.

        Images can be either a list of tensors, or a list of paths to image disk locations.

        Args:
            imgs: List of image tensors or image paths: Images

        z8Expected a list of image tensors or image paths. Gotcha .c                    s   g | ]}|  jqS r$   )tor?   r"   imgrA   r$   r%   
<listcomp>d   s    z7RayDataset.init_images_for_training.<locals>.<listcomp>N)_check_image_type_consistencyr,   _load_imagesr/   	TypeErrortype_check_dimensionsr:   )rA   rI   imagesr$   rN   r%   init_images_for_trainingO   s   
	
z#RayDataset.init_images_for_trainingc                 C   s2   t | j| j| j| j| jd| _| j| j| dS )zInitialize a random ray sampler and calculates dataset ray parameters.

        Args:
            num_img_rays: If not None, number of rays to randomly cast from each camers: math: `(B)`.

        r5   r6   N)	r   r<   r=   r>   r?   r@   r9   calc_ray_paramsr;   rG   r$   r$   r%   rF   f   s   z#RayDataset._init_random_ray_datasetc                 C   s0   t | j| j| j| j| jd| _| j| j dS )zGInitialize a uniform ray sampler and calculates dataset ray parameters.rW   N)	r   r<   r=   r>   r?   r@   r9   rX   r;   rN   r$   r$   r%   rE   r   s   z$RayDataset._init_uniform_ray_datasetc                 C   s4   t dd |D st dd |D stdd S d S )Nc                 s   r   r   r   rL   r$   r$   r%   r&   z   r'   z;RayDataset._check_image_type_consistency.<locals>.<genexpr>c                 s   r   r   r.   rL   r$   r$   r%   r&   z   r'   z9The list of input images can only be all paths or tensors)r*   
ValueError)rA   rI   r$   r$   r%   rP   y   s   $z(RayDataset._check_image_type_consistencyc              
   C   s   t || jjkrtdt | d| jj tdd |D s#tdtt|| jj| jjD ]-\}\}}}|j	dd  ||fkr\td| d|j	d |j	d	 f d
|
 |
 f q/d S )NzNumber of images z" does not match number of cameras c                 s   s    | ]
}|j d  dkV  qdS )r      N)shaperL   r$   r$   r%   r&      s    z/RayDataset._check_dimensions.<locals>.<genexpr>z$Not all input images have 3 channels   zImage index z dimensions    z4 are inconsistent with equivalent camera dimensions )lenr;   
batch_sizerY   r*   	enumeratezipheightwidthr[   item)rA   rI   irM   rb   rc   r$   r$   r%   rT   }   s   &zRayDataset._check_dimensions	img_pathsc                 C   s$   g }| D ]}| t|tj q|S r   )appendr   r   	UNCHANGED)rf   rI   img_pathr$   r$   r%   rQ      s   zRayDataset._load_imagesc                 C   s   t | jtrt| jS dS Nr   )r   r9   r   r^   rN   r$   r$   r%   __len__   s   
zRayDataset.__len__idxsc                    s   t  jts
td jj| } jj| } jdu r ||dfS  jj| } jj| }d} fdd|D }t	dd t
||D }|j jdd }|||fS )a*  Get a dataset item.

        Args:
            idxs: An index or group of indices of ray parameter object: Union[int, List[int]]

        Return:
            A ray parameter object that includes ray origins, directions, and rgb values at the ray 2d pixel
            coordinates: RayGroup

        zRRay sampler is not initiate yet, please run self.init_ray_dataset() before use it.Nc                    s   g | ]} j | qS r$   )r:   )r"   re   rN   r$   r%   rO      s    z*RayDataset.__getitem__.<locals>.<listcomp>c                 S   s2   g | ]\}}|d d |d   |d   f qS )Nr\   r   )rd   )r"   rM   point2dr$   r$   r%   rO      s   2 )r6   g     o@)r   r9   r   rR   origins
directionsr:   
camera_ids	points_2dr   ra   rK   r@   )rA   rl   rn   ro   
camerd_idsrq   rgbsimgs_for_idsr$   rN   r%   __getitem__   s   


zRayDataset.__getitem__r   )r   N)__name__
__module____qualname____doc__r   floatboolr   torchr6   r8   r   r   rH   r   rV   rF   rE   rP   r   rT   staticmethodr   r    rQ   intrk   r   RayGroupru   __classcell__r$   r$   rB   r%   r0   )   s6    
&r0   r\   Tdatasetr_   shufflec                 C   sJ   dt t dtfdd}trt| S t| t|rt| nt| |dd|dS )zInitialize a dataloader to manage a ray dataset.

    Args:
        dataset: A ray dataset: RayDataset
        batch_size: Number of rays to sample in a batch: int
        shuffle: Whether to shuffle rays or sample then sequentially: bool

    itemsr   c                 S   s   | d S rj   r$   )r   r$   r$   r%   collate_rays   s   z0instantiate_ray_dataloader.<locals>.collate_raysF)	drop_last)sampler
collate_fn)r   r   r   r	   r   r   r   )r   r_   r   r   r$   r$   r%   instantiate_ray_dataloader   s   
r   )r\   T))typingr   r   r   r   r   r   r|   torch.utils.datar   r	   r
   r   r   typing_extensionsr   kornia.corer   r   r   kornia.geometry.camerar   	kornia.ior   r   kornia.nerf.corer   r   kornia.nerf.samplersr   r   r   r   objectr    r,   r/   r0   r~   r{   r   r$   r$   r$   r%   <module>   s     $