o
    oi[8                     @  s   d dl mZ d dlZd dlZd dlZd dlmZ d dlmZm	Z	m
Z
mZ d dlZddlmZmZmZmZ ddlmZ ddlmZ dd	lmZ G d
d dZG dd deeeZG dd deeeZdS )    )annotationsNwraps)AnyCallableOptionalUnion   )Module
SequentialTensor
from_numpy)PILImage)numpy)ONNXExportMixinc                   @  st   e Zd ZU dZded< 		d.d/ddZd0ddZd1ddZd2ddZd3ddZ	d4ddZ
d5d6d'd(Zd7d8d,d-ZdS )9ImageModuleMixInzA MixIn that handles image-based operations.

    This modules accepts multiple input and output data types, provides end-to-end visualization, file saving features.
    Note that this MixIn fits the classes that return one image tensor only.
    r   _output_imageNtensorinput_names_to_handleOptional[list[Any]]output_typestrreturnCallable[[Any], Any]c                   s   d fdd}|S )aT  Convert input and output types for a function.

        Args:
            input_names_to_handle: List of input names to convert, if None, handle all inputs.
            output_type: Desired output type ('tensor', 'numpy', or 'pil').

        Returns:
            Callable: Decorated function with converted input and output types.

        funcr   r   c                   s    t  d fdd}|S )	Nargsr   kwargsr   Union[Any, list[Any]]c            	        s0  d u rt fdd| D } fdd| D }n3t| } tt|  jjD ]\}\}}|v r9|| |< q(| D ]\}}|v rM|||< q> | i |}t|t fs^|f}g }|D ])}dkrn|	| qbdkr{|	
| qbdkr|	| qbtdt|d	kr|S |d
 S )Nc                 3  s(    | ]}  |r |n|V  qd S N_is_valid_arg	to_tensor).0argself F/home/ubuntu/.local/lib/python3.10/site-packages/kornia/core/module.py	<genexpr>B   s   & z\ImageModuleMixIn.convert_input_output.<locals>.decorator.<locals>.wrapper.<locals>.<genexpr>c                   s*   i | ]\}}|  |r |n|qS r&   r   )r"   kvr$   r&   r'   
<dictcomp>D   s   * z]ImageModuleMixIn.convert_input_output.<locals>.decorator.<locals>.wrapper.<locals>.<dictcomp>r   r   pilzCOutput type not supported. Choose from 'tensor', 'numpy', or 'pil'.r	   r   )tupleitemslist	enumeratezip__code__co_varnamesr!   
isinstanceappendto_numpyto_pil
ValueErrorlen)	r   r   ir#   namevaluetensor_outputsoutputsoutput)r   r   r   r%   r&   r'   wrapper=   s2   zIImageModuleMixIn.convert_input_output.<locals>.decorator.<locals>.wrapper)r   r   r   r   r   r   r   )r   r@   r   r   r%   )r   r'   	decorator<   s   &z8ImageModuleMixIn.convert_input_output.<locals>.decoratorN)r   r   r   r   r&   )r%   r   r   rB   r&   rA   r'   convert_input_output,   s   *z%ImageModuleMixIn.convert_input_outputr#   boolc                 C  sR   t |tfrtj|rdS t |tfrdS t |tjfrdS t |tjr'dS dS )zCheck if the argument is a valid type for conversion.

        Args:
            arg: The argument to check.

        Returns:
            bool: True if valid, False otherwise.

        TF)	r4   r   ospathexistsr   npndarrayImage)r%   r#   r&   r&   r'   r    h   s   
zImageModuleMixIn._is_valid_argxr   c                 C  s   t |tfrtj|tjjjd S t |tfr|S t |tj	fr*tj
j|d S t |tjfrAtt|ddd d S td)zConvert input to tensor.

        Supports image path, numpy array, PIL image, and raw tensor.

        Args:
            x: The input to convert.

        Returns:
            Tensor: The converted tensor.

              r   r	   Input type not supported)r4   r   korniaio
load_imageImageLoadType	UNCHANGEDr   rH   rI   utilsimageimage_to_tensorrJ   r   arraypermutefloat	TypeErrorr%   rK   r&   r&   r'   r!   }   s    zImageModuleMixIn.to_tensornp.arrayc                 C  sN   t |tfr|   S t |tjfr|S t |tjfr#t|S t	d)zConvert input to numpy array.

        Args:
            x: The input to convert.

        Returns:
            np.array: The converted numpy array.

        rN   )
r4   r   cpudetachr   rH   rI   rJ   rW   rZ   r[   r&   r&   r'   r6      s   

zImageModuleMixIn.to_numpyImage.Imagec                 C  s   t |tfr]|  }|jdkr:|d |ddd  	 }|j
d dkr5|dddddf }t|S |jdkr[|d |dddd }| 	 }dd	 |D S tt |tjfrftt |tjfro|S td
)zConvert input to PIL image.

        Args:
            x: The input to convert.

        Returns:
            Image.Image: The converted PIL image.

           rL   r	   rM   r   N   c                 S  s   g | ]}t |qS r&   )rJ   	fromarray)r"   imgr&   r&   r'   
<listcomp>       z+ImageModuleMixIn.to_pil.<locals>.<listcomp>rN   )r4   r   r^   r]   ndimmul_rX   
contiguousbyter   shaperJ   rb   NotImplementedErrorrH   rI   rZ   )r%   rK   r   arr
tensor_chwnumpy_batchr&   r&   r'   r7      s&   





zImageModuleMixIn.to_piloutput_image*Union[Tensor, list[Tensor], tuple[Tensor]]c                   sZ   t |tfr|  S t |ttfr t| fdd|D S td| dt| d)aw  Detach the input tensor (or list/tuple of tensors) from the GPU and move it to the CPU.

        Args:
            output_image (Union[Tensor, list[Tensor], tuple[Tensor]]): The input tensor(s) to be moved.

        Returns:
            Union[Tensor, list[Tensor], tuple[Tensor]]: The tensor(s) moved to the CPU and detached from
            the computational graph.
        c                   s   g | ]}  |qS r&   )_detach_tensor_to_cpu)r"   outr$   r&   r'   rd      re   z:ImageModuleMixIn._detach_tensor_to_cpu.<locals>.<listcomp>zUnexpected object z with a type of ``)r4   r   r^   r]   r/   r-   typeRuntimeError)r%   ro   r&   r$   r'   rq      s   z&ImageModuleMixIn._detach_tensor_to_cpur,   Tn_rowOptional[int]backenddisplayOptional[Any]c                 C  s   | j du r	tdt| j jdkr| j }n%t| j jdkr8|du r,t| j jd d }tjjj	| j |dd}nt|d	krX|rXt
|d
dd  d tj  dS |d	krpt
|d
dd  d tjS td| d)zReturn PIL images.

        Args:
            n_row: Number of images displayed in each row of the grid.
            backend: visualization backend. Only PIL is supported now.
            display: whether to display the image.

        Nz5No pre-computed images found. Needs to execute first.r`   ra   r         ?rM   paddingr,   r	   rL   zUnsupported backend `z`.)r   r8   r9   rj   mathceilrO   rT   rU   	make_gridrJ   rb   rX   squeezer   astyperH   uint8show)r%   rv   rx   ry   	out_imager&   r&   r'   r      s   
	,(zImageModuleMixIn.showr;   Optional[str]Nonec                 C  s   |du rdt j jt jjddd}t| jjdkr| j}t| jjdkrA|du r6t	| jjd d	 }t
jjj| j|d
d}t
j||d  dS )zSave the output image(s) to a directory.

        Args:
            name: Directory to save the images.
            n_row: Number of images displayed in each row of the grid.

        NzKornia-)tzz%Y%m%d%H%M%Sz.jpgr`   ra   r   r{   rM   r|   g     o@)datetimenowtimezoneutcstrftimer9   r   rj   r~   r   rO   rT   rU   r   rP   write_imagemulri   )r%   r;   rv   r   r&   r&   r'   save   s    zImageModuleMixIn.save)Nr   )r   r   r   r   r   r   )r#   r   r   rD   )rK   r   r   r   )rK   r   r   r\   )rK   r   r   r_   )ro   rp   r   rp   )Nr,   T)rv   rw   rx   r   ry   rD   r   rz   )NN)r;   r   rv   rw   r   r   )__name__
__module____qualname____doc____annotations__rC   r    r!   r6   r7   rq   r   r   r&   r&   r&   r'   r   #   s   
 
<



r   c                      X   e Zd ZdZd fddZedd
dZejddddZdddd fddZ  Z	S )ImageModulea  Handles image-based operations.

    This modules accepts multiple input and output data types, provides end-to-end
    visualization, file saving features. Note that this module fits the classes that
    return one image tensor only.

    Note:
        The additional add-on features increase the use of memories. To restore the
        original behaviour, you may set `disable_features = True`.

    r   r   r   r   r   c                      t  j|i | d| _d S NFsuper__init___disable_featuresr%   r   r   	__class__r&   r'   r        
zImageModule.__init__rD   c                 C     | j S r   r   r$   r&   r&   r'   disable_features     zImageModule.disable_featuresTr<   c                 C  
   || _ d S r   r   r%   r<   r&   r&   r'   r         
Nr   r   r   inputsr   r   r   r   c                  b   | j s&| j||dt j}||i |}|dkr!| || _|S || _|S t j|i |}|S a  Overwrite the __call__ function to handle various inputs.

        Args:
            inputs: Inputs to operate on.
            input_names_to_handle: List of input names to convert, if None, handle all inputs.
            output_type: Desired output type ('tensor', 'numpy', or 'pil').
            kwargs: Additional arguments.

        Returns:
            Callable: Decorated function with converted input and output types.

        r   r   r   rC   r   __call__rq   r   r%   r   r   r   r   decorated_forwardr   r   r&   r'   r   $     zImageModule.__call__r   r   r   r   r   r   r   rD   Tr<   rD   r   r   
r   r   r   r   r   r   r   r   r   r   
r   r   r   r   r   propertyr   setterr   __classcell__r&   r&   r   r'   r         r   c                      r   )ImageSequentiala  Handles image-based operations as a sequential module.

    This modules accepts multiple input and output data types, provides end-to-end
    visualization, file saving features. Note that this module fits the classes that
    return one image tensor only.

    Note:
        The additional add-on features increase the use of memories. To restore the
        original behaviour, you may set `disable_features = True`.

    r   r   r   r   r   c                   r   r   r   r   r   r&   r'   r   S  r   zImageSequential.__init__rD   c                 C  r   r   r   r$   r&   r&   r'   r   W  r   z ImageSequential.disable_featuresTr<   c                 C  r   r   r   r   r&   r&   r'   r   [  r   Nr   r   r   r   r   r   r   c                  r   r   r   r   r   r&   r'   r   _  r   zImageSequential.__call__r   r   r   r   r   r   r&   r&   r   r'   r   F  r   r   )
__future__r   r   r~   rE   	functoolsr   typingr   r   r   r   rO   _backendr
   r   r   r   externalr   rJ   r   rH   
mixin.onnxr   r   r   r   r&   r&   r&   r'   <module>   s    i;