o
    ?߱i{                     @   s   d Z ddlZddlmZ ddlZddlZddlmZ ddl	m
Z
 ddlmZ ddgZdd
ejejB deeB defddZ					dd
ejejB deeB dedededdfddZdded
eejejf deeef ddfddZdS )zoimage visualization utilities.

based on https://gitlab.com/qsh.zh/jam/-/blob/master/jamviz/img.py MIT License
    N)Union)	rearrange)Image)	make_gridshow_batch_imgsave_batch_img   img_datashapereturnc                 C   s  t |tr||}}n.t |tr1d|vrt|t|}}n|d}t|d t|d }}ntd| dt | tjr_| jd dv sHJ t| d||  	 
 |}|ddd}n(t | tjr| jd dv rzt| d||  d	|d
}nt| d||  d|d
}|||fS )aE  
    Reshapes a batch of images for visualization, organizing them into a grid format.

    Args:
        img_data (torch.Tensor | np.ndarray): The image data to be reshaped, can be either a PyTorch tensor or a NumPy array.
        shape (int | str, optional): Defines the layout of the grid. If an integer is provided, it specifies both the number of rows and columns. If a string is provided in the format 'nrowxncol', it parses to individual row and column numbers. Defaults to 7.

    Returns:
        tuple: A tuple containing:
            img (np.ndarray | torch.Tensor): The image data arranged in grid format.
            nrow (int): Number of rows in the grid.
            ncol (int): Number of columns in the grid.

    Raises:
        RuntimeError: If the shape parameter is neither an int nor a string, or if it's a string that doesn't contain 'x'.

    Example:
        >>> tensor_images = torch.rand(64, 3, 28, 28)  # Example tensor of 64 images
        >>> img_grid, rows, cols = _reshape_viz_batch_img(tensor_images, '8x8')
        >>> img_grid.shape
        (224, 224, 3)
    xr      zshape z not support)r      N   z(b t) c h w -> (b h) (t w) c)bz(b t) h w c -> (b h) (t w) c)
isinstanceintstrsplitRuntimeErrortorchTensorr
   r   detachcpupermutenpndarrayr   )r	   r
   nrowncolZgrid_imgimg r    W/data/cameron/vidgen/cosmos-predict2.5/cosmos_predict2/_src/imaginaire/visualize/img.py_reshape_viz_batch_img$   s"   



r"   r   FTgridis_n1p1	auto_n1p1c           	      C   s   ddl m} |r| d d } n*|r9t| tjr&|   dk r%| d d } nt| tjr9t| dk r9| d d } t	| |\}}}|j
|| || fd |d || dS )a  
    Displays a batch of images using matplotlib after arranging them into a specified grid layout.

    Args:
        img_data (torch.Tensor | np.ndarray): The image data to be displayed.
        shape (int | str, optional): The grid shape to organize the images. Defaults to 7.
        grid (int, optional): Scaling factor for each image in the grid, affecting the overall size of the displayed figure. Defaults to 3.
        is_n1p1 (bool, optional): Whether to normalize the images from [-1, 1] to [0, 1] for visualization. Defaults to False.
        auto_n1p1 (bool, optional): If true, automatically adjusts images from [-1, 1] to [0, 1] based on minimum pixel value detection. Defaults to True.

    Returns:
        None: This function does not return anything but displays the image grid using matplotlib.

    Example:
        >>> tensor_images = torch.rand(64, 3, 28, 28)  # Example tensor of 64 images
        >>> show_batch_img(tensor_images, '8x8')
    r   Nr   r   g      )figsizeoff)matplotlib.pyplotpyplotr   r   r   minitemr   r   r"   figureaxisimshow)	r	   r
   r#   r$   r%   pltr   r   r   r    r    r!   r   Q   s   
fpathc                 C   sz   t ||\}}}t|tjrt|}|dddd	dtj
 }t|}tjtj| dd ||  dS )a  
    Saves a batch of images to a file after arranging them into a grid format. Handles both PyTorch tensors and NumPy arrays as input.

    Args:
        fpath (str): File path where the image will be saved.
        img_data (Union[torch.Tensor, np.ndarray]): The image data to be saved. Can be a PyTorch tensor or a NumPy array.
        shape (Union[int, str], optional): The grid shape to organize the images. Can be an integer specifying equal number of rows and columns, or a string specifying 'nrowxncol'. Defaults to 7.

    Returns:
        None: This function does not return anything but saves the image to the specified file path.

    Raises:
        RuntimeError: If the input shape is neither an integer nor a string, or it does not include 'x' when provided as a string.

    Example:
        >>> tensor_images = torch.rand(64, 3, 28, 28)  # Example tensor of 64 images
        >>> save_batch_img('path/to/save/image.png', tensor_images, '8x8')
        # This saves the image grid to 'path/to/save/image.png'
       g      ?r   r   T)exist_okN)r"   r   r   r   r   
from_numpymuladd_clamp_touint8numpyr   	fromarrayosmakedirspathdirnamesave)r0   r	   r
   r   _ndarrimr    r    r!   r   {   s   
&
)r   )r   r   FT)__doc__r;   typingr   r9   r   r   einopsr   PILr   Ztorchvision.utilsr   __all__r   r   r   r   tupler"   boolr   r   r    r    r    r!   <module>   s<   $/

4*