a
    d!                     @   s   d dl mZ d dlmZmZmZ d dlZd dlmZ er@d dl	Z
ddeejdddZed ejd	d
dZejejdddZejejdddZdejeddddZG dd dejZeedddZeedddZdS )    )wraps)TYPE_CHECKINGCallableListNT
np.ndarray)imagekeepdimreturnc                 C   s   t | jdkst | jdk r$td| j}t| }t |dkrL|d}nLt |dkrh|ddd}n0t |dkr|dddd}d}ntd| |s|dS |S )	a  Convert a numpy image to a PyTorch 4d tensor image.

    Args:
        image: image of the form :math:`(H, W, C)`, :math:`(H, W)` or
            :math:`(B, H, W, C)`.
        keepdim: If ``False`` unsqueeze the input image to match the shape
            :math:`(B, H, W, C)`.

    Returns:
        tensor of the form :math:`(B, C, H, W)` if keepdim is ``False``,
            :math:`(C, H, W)` otherwise.

    Example:
        >>> img = np.ones((3, 3))
        >>> image_to_tensor(img).shape
        torch.Size([1, 3, 3])

        >>> img = np.ones((4, 4, 1))
        >>> image_to_tensor(img).shape
        torch.Size([1, 4, 4])

        >>> img = np.ones((4, 4, 3))
        >>> image_to_tensor(img, keepdim=False).shape
        torch.Size([1, 3, 4, 4])
          z9Input size must be a two, three or four dimensional arrayr         Tz Cannot process image with shape )lenshape
ValueErrortorchZ
from_numpy	unsqueezeZpermute)r   r   input_shapetensor r   [/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/kornia/utils/image.pyimage_to_tensor   s    
r   )imagesr	   c                 C   sP   | st dt| d jdkr&t dg }| D ]}|t| q.t|}|S )a  Converts a list of numpy images to a PyTorch 4d tensor image.

    Args:
        images: list of images, each of the form :math:`(H, W, C)`.
        Image shapes must be consistent

    Returns:
        tensor of the form :math:`(B, C, H, W)`.

    Example:
        >>> imgs = [np.ones((4, 4, 1)), np.zeros((4, 4, 1))]
        >>> image_list_to_tensor(imgs).shape
        torch.Size([2, 1, 4, 4])
    z#Input list of numpy images is emptyr   r   z-Input images must be three dimensional arrays)r   r   r   appendr   r   stack)r   Zlist_of_tensorsr   r   r   r   r   image_list_to_tensor;   s    
r   )r   r	   c                 C   s   t | tjstdt|  t| jdk r<td| j t| jdkrT| d} t| jdkrl| d} t| jdkr| 	d| jd | jd	 | jd } | S )
zConvert a PyTorch tensor image to BCHW format.

    Args:
        tensor (torch.Tensor): image of the form :math:`(*, H, W)`.

    Returns:
        input tensor of the form :math:`(B, C, H, W)`.
    &Input type is not a torch.Tensor. Got r   z@Input size must be a two, three or four dimensional tensor. Got r   r   r
   

isinstancer   Tensor	TypeErrortyper   r   r   r   viewr   r   r   r   _to_bchwV   s    	

"r'   c                 C   s   t | tjstdt|  t| jdk r<td| j t| jdkrT| d} t| jdkrl| d} t| jdkr| 	d| jd | jd	 | jd
 | jd } | S )zConvert a PyTorch tensor image to BCDHW format.

    Args:
        tensor (torch.Tensor): image of the form :math:`(*, D, H, W)`.

    Returns:
        input tensor of the form :math:`(B, C, D, H, W)`.
    r   r   zAInput size must be a three, four or five dimensional tensor. Got r   r
      r   r   r   r    r&   r   r   r   	_to_bcdhwq   s    	

*r*   F)r   r   r	   c                 C   s   t | tjstdt|  t| jdks:t| jdk rBtd| j}|  	 
 }t|dkrfnt|dkr|d dkr| }q|ddd}n\t|dkr|dddd}|d dkr|s|d}|d dkr|d}ntd	| |S )
a  Converts a PyTorch tensor image to a numpy image.

    In case the tensor is in the GPU, it will be copied back to CPU.

    Args:
        tensor: image of the form :math:`(H, W)`, :math:`(C, H, W)` or
            :math:`(B, C, H, W)`.
        keepdim: If ``False`` squeeze the input image to match the shape
            :math:`(H, W, C)` or :math:`(H, W)`.

    Returns:
        image of the form :math:`(H, W)`, :math:`(H, W, C)` or :math:`(B, H, W, C)`.

    Example:
        >>> img = torch.ones(1, 3, 3)
        >>> tensor_to_image(img).shape
        (3, 3)

        >>> img = torch.ones(3, 4, 4)
        >>> tensor_to_image(img).shape
        (4, 4, 3)
    r   r
   r   z:Input size must be a two, three or four dimensional tensorr   r   r   r   z!Cannot process tensor with shape )r!   r   r"   r#   r$   r   r   r   cpudetachnumpyZsqueezeZ	transpose)r   r   r   r   r   r   r   tensor_to_image   s(    

r.   c                       s:   e Zd ZdZd
ed fddZdejddd	Z  Z	S )ImageToTensorzConverts a numpy image to a PyTorch 4d tensor image.

    Args:
        keepdim: If ``False`` unsqueeze the input image to match the shape :math:`(B, H, W, C)`.
    Fr   c                    s   t    || _d S )N)super__init__r   )selfr   	__class__r   r   r2      s    
zImageToTensor.__init__r   )xr	   c                 C   s   t || jdS )Nr0   )r   r   )r3   r6   r   r   r   forward   s    zImageToTensor.forward)F)
__name__
__module____qualname____doc__boolr2   r   r"   r7   __classcell__r   r   r4   r   r/      s   r/   )fr	   c                    s    t  tjd fdd}|S )zA decorator that enable `f` to be applied to an image of arbitrary leading dimensions `(*, C, H, W)`.

    It works by first viewing the image as `(B, C, H, W)`, applying the function and re-viewing the image as original
    shape.
    inputc                    s   t | tjstdt|  |  dkr2td| j}t| }  | g|R i |}t	|dkrj|d }t	|dkr~|d }t	|dkr|j
|d d |jdd    }|S )	N,Input input type is not a torch.Tensor. Got r   "Invalid input tensor, it is empty.r   r   r   r   r
   r   )r!   r   r"   r#   r$   numelr   r   r'   r   r%   r@   argskwargsr   outputr>   r   r   _wrapper   s     z*perform_keep_shape_image.<locals>._wrapperr   r   r"   r>   rJ   r   rI   r   perform_keep_shape_image   s    rM   c                    s    t  tjd fdd}|S )zA decorator that enable `f` to be applied to an image of arbitrary leading dimensions `(*, C, D, H, W)`.

    It works by first viewing the image as `(B, C, D, H, W)`, applying the function and re-viewing the image as original
    shape.
    r?   c                    s   t | tjstdt|  |  dkr2td| j}t| }  | g|R i |}t	|dkrj|d }t	|dkr~|d }t	|dkr|j
|d d |jdd    }|S )	NrA   r   rB   r
   r   rC   r(   r)   )r!   r   r"   r#   r$   rD   r   r   r*   r   r%   rE   rI   r   r   rJ      s     z*perform_keep_shape_video.<locals>._wrapperrK   rL   r   rI   r   perform_keep_shape_video   s    rN   )T)F)	functoolsr   typingr   r   r   r   Ztorch.nnnnr-   npr<   r"   r   r   r'   r*   r.   Moduler/   rM   rN   r   r   r   r   <module>   s   07 