o
    oi7                     @  s   d dl mZ d dlmZ d dlmZ d dlZd dlmZm	Z	 d dl
Zd dlmZmZmZ d dlmZmZ d dlmZmZmZmZmZ d d	lmZmZmZ d d
lmZ eZeZ G dd dZ!dS )    )annotations)Path)AnyN)from_dlpack	to_dlpack)DeviceDtypeTensor)KORNIA_CHECKKORNIA_CHECK_SHAPE)ChannelsOrder
ColorSpaceImageLayout	ImageSizePixelFormat)ImageLoadType
load_imagewrite_image)image_to_stringc                   @  sZ  e Zd ZdZdSd
dZdTddZdUdVddZdWddZedXddZ	edYddZ
edZddZed[d!d"Zed\d#d$Zed]d%d&Zed^d(d)Zed_d+d,Zed^d-d.Zed^d/d0Zed`d2d3ZdWd4d5ZdWd6d7ZdWd8d9ZdWd:d;Zeejejfdad@dAZdbdBdCZedcdEdFZdddGdHZ ededKdLZ!dfdMdNZ"dgdhdQdRZ#dS )iImagea>  Class that holds an Image Tensor representation.

    .. note::

        Disclaimer: This class provides the minimum functionality for image manipulation. However, as soon
        as you start to experiment with advanced tensor manipulation, you might expect fancy
        polymorphic behaviours.

    .. warning::

        This API is experimental and might suffer changes in the future.

    Args:
        data: a torch tensor containing the image data.
        layout: a dataclass containing the image layout information.

    Examples:
        >>> # from a torch.tensor
        >>> data = torch.randint(0, 255, (3, 4, 5), dtype=torch.uint8)  # CxHxW
        >>> pixel_format = PixelFormat(
        ...     color_space=ColorSpace.RGB,
        ...     bit_depth=8,
        ... )
        >>> layout = ImageLayout(
        ...     image_size=ImageSize(4, 5),
        ...     channels=3,
        ...     channels_order=ChannelsOrder.CHANNELS_FIRST,
        ... )
        >>> img = Image(data, pixel_format, layout)
        >>> assert img.channels == 3

        >>> # from a numpy array (like opencv)
        >>> data = np.ones((4, 5, 3), dtype=np.uint8)  # HxWxC
        >>> img = Image.from_numpy(data, color_space=ColorSpace.RGB)
        >>> assert img.channels == 3
        >>> assert img.width == 5
        >>> assert img.height == 4

    datar	   pixel_formatr   layoutr   returnNonec                 C  s   |j tjkrt|jt|jjt|jjg}n |j tjkr.t|jjt|jjt|jg}n	t	d|j  dt
|| t| |jd kd || _|| _|| _dS )zImage constructor.

        Args:
            data: a torch tensor containing the image data.
            pixel_format: the pixel format of the image.
            layout: a dataclass containing the image layout information.

        zLayout z not implemented.   zInvalid bit depth.N)channels_orderr   CHANNELS_FIRSTstrchannels
image_sizeheightwidthCHANNELS_LASTNotImplementedErrorr   r
   element_size	bit_depth_data_pixel_format_layout)selfr   r   r   shape r,   F/home/ubuntu/.local/lib/python3.10/site-packages/kornia/image/image.py__init__O   s   
""

zImage.__init__r   c                 C  s   d| j  d| j d| j S )NzImage data: z
Pixel Format: z

 Layout: )r   r   r   r*   r,   r,   r-   __repr__g   s   zImage.__repr__Ndevicer   dtyper   c                 C  s2   |durt |tjr|d}}| j||| _| S )a  Move the image to the given device and dtype.

        Args:
            device: the device to move the image to.
            dtype: the data type to cast the image to.

        Returns:
            Image: the image moved to the given device and dtype.

        N)
isinstancetorchr2   r   tor'   )r*   r1   r2   r,   r,   r-   r5   k   s   
zImage.toc                 C  s   t | j | j| jS )zReturn a copy of the image.)r   r   cloner   r   r/   r,   r,   r-   r6   }   s   zImage.clonec                 C     | j S )z"Return the underlying tensor data.)r'   r/   r,   r,   r-   r         z
Image.datatuple[int, ...]c                 C     | j jS )zReturn the image shape.)r   r+   r/   r,   r,   r-   r+         zImage.shapetorch.dtypec                 C  r:   )zReturn the image data type.)r   r2   r/   r,   r,   r-   r2      r;   zImage.dtypetorch.devicec                 C  r:   )zReturn the image device.)r   r1   r/   r,   r,   r-   r1      r;   zImage.devicec                 C  r7   )zReturn the pixel format.)r(   r/   r,   r,   r-   r      r8   zImage.pixel_formatc                 C  r7   )zReturn the image layout.)r)   r/   r,   r,   r-   r      r8   zImage.layoutintc                 C  r:   )z(Return the number channels of the image.)r   r   r/   r,   r,   r-   r      r;   zImage.channelsr   c                 C  r:   )zReturn the image size.)r   r    r/   r,   r,   r-   r       r;   zImage.image_sizec                 C     t | jjjS )z"Return the image height (columns).)r>   r   r    r!   r/   r,   r,   r-   r!         zImage.heightc                 C  r?   )zReturn the image width (rows).)r>   r   r    r"   r/   r,   r,   r-   r"      r@   zImage.widthr   c                 C  r:   )zReturn the channels order.)r   r   r/   r,   r,   r-   r      r;   zImage.channels_orderc                 C  s   | j  | _| S )zReturn the image as float.)r   floatr'   r/   r,   r,   r-   rA      s   zImage.floatc                 C  s  | j j}| j}|tjkr| S | jjtjk}|r+|j	dkr$|
ddddn|
ddd}|tjkr7tj|}n|tjkrCtj|}ntd| |ro|j	dkrZ|
dddd}n|j	dkrg|
ddd}ntd|j ttj| j jd}t| jjd| jjd	}t|||S )
z Converts the image to grayscale.   r            z.Unsupported source color space for to_gray(): z-Unexpected shape after grayscale conversion: color_spacer&   r   r   )r(   rG   r'   r   GRAYr)   r   r   r#   ndimpermuteRGBkorniacolorrgb_to_grayscaleBGRbgr_to_grayscale
ValueErrorr+   r   r&   r   r    r   r*   srcr   is_channels_lastoutnew_pf
new_layoutr,   r,   r-   to_gray   s*   
(



zImage.to_grayc                 C  s  | j j}| j}|tjkr| S | jjtjk}|r+|j	dkr$|
ddddn|
ddd}|tjkr7tj|}n%|tjkrU|j	dkrL|ddg ddf n|g ddf }ntd	| |rr|j	dkrk|
ddddn|
ddd}ttj| j jd
}t| jjd| jjd}t|||S )zConverts the image to RGB.rB   r   rC   rD   rE   NrE   rD   r   .z-Unsupported source color space for to_rgb(): rF   rH   )r(   rG   r'   r   rL   r)   r   r   r#   rJ   rK   rI   rM   rN   grayscale_to_rgbrP   rR   r   r&   r   r    r   rS   r,   r,   r-   to_rgb   s"   
(

2(zImage.to_rgbc                 C  sH  | j j}| j}|tjkr| S | jjtjk}|r+|j	dkr$|
ddddn|
ddd}|tjkrOtj|}|j	dkrF|ddg ddf n|g ddf }n%|tjkrm|j	dkrd|ddg ddf n|g ddf }ntd	| |r|j	dkr|
ddddn|
ddd}ttj| j jd
}t| jjd| jjd}t|||S )zConverts the image to BGR.rB   r   rC   rD   rE   NrZ   .z-Unsupported source color space for to_bgr(): rF   rH   )r(   rG   r'   r   rP   r)   r   r   r#   rJ   rK   rI   rM   rN   r[   rL   rR   r   r&   r   r    r   )r*   rT   r   rU   rgb_datarV   rW   rX   r,   r,   r-   to_bgr   s$   
(
2
2(zImage.to_bgr
np_ndarrayrG   r   r   c                 C  s   |t jkrt|jd |jd d}|jd }n|t jkr.t|jd |jd d}|jd }ntdt||jd d}t|||d}| t	
|||S )	aV  Construct an image tensor from a numpy array.

        Args:
            data: a numpy array containing the image data.
            color_space: the color space of the image.
            pixel_format: the pixel format of the image.
            channels_order: what dimension the channels are in the image tensor.

        Example:
            >>> data = np.ones((4, 5, 3), dtype=np.uint8)  # HxWxC
            >>> img = Image.from_numpy(data, color_space=ColorSpace.RGB)
            >>> assert img.channels == 3
            >>> assert img.width == 5
            >>> assert img.height == 4

        r   rD   r!   r"   rE   zAchannels_order must be either `CHANNELS_LAST` or `CHANNELS_FIRST`r   rF   r    r   r   )r   r#   r   r+   r   rR   r   itemsizer   r4   
from_numpy)clsr   rG   r   r    r   r   r   r,   r,   r-   rc     s   

zImage.from_numpyc                 C  s   | j    S )z2Return a numpy array in cpu from the image tensor.)r   cpudetachnumpyr/   r,   r,   r-   to_numpy<  s   zImage.to_numpyDLPackc                 C  sT   t |}ttj| d d}tt|jd |jd d|jd tj	d}| |||S )zConstruct an image tensor from a DLPack capsule.

        Args:
            data: a DLPack capsule from numpy, tvm or jax.

        Example:
            >>> x = np.ones((4, 5, 3))
            >>> img = Image.from_dlpack(x.__dlpack__())

        r   rF   rD   rE   r`   r   ra   )
r   r   r   rL   r%   r   r   r+   r   r   )rd   r   r'   r   r   r,   r,   r-   r   @  s   zImage.from_dlpackc                 C  s
   t | jS )z.Return a DLPack capsule from the image tensor.)r   r   r/   r,   r,   r-   r   Y  s   
zImage.to_dlpack	file_path
str | Pathc                 C  s\   t |tjdd}ttj| d d}tt|j	d |j	d d|j	d t
jd	}| |||S )
zConstruct an image tensor from a file.

        Args:
            file_path: the path to the file to read the image from.

        re   )desired_typer1   r   rF   rD   rE   r`   r   ra   )r   r   RGB8r   r   rL   r%   r   r   r+   r   r   )rd   rj   r   r   r   r,   r,   r-   	from_file]  s   	zImage.from_filec                 C  s.   | j }| jtjkr|ddd}t|| dS )aU  Write the image to a file.

        For now, only support writing to JPEG format.

        Args:
            file_path: the path to the file to write the image to.

        Example:
            >>> data = np.ones((4, 5, 3), dtype=np.uint8)  # HxWxC
            >>> img = Image.from_numpy(data)
            >>> img.write("test.jpg")

        rE   r   rD   N)r   r   r   r#   rK   r   )r*   rj   r   r,   r,   r-   writeq  s   zImage.write   	max_widthc                 C  s   t t| j| dS )a=  Print the image tensor to the console.

        Args:
            max_width: the maximum width of the image to print.

        .. code-block:: python

            img = Image.from_file("panda.png")
            img.print()

        .. image:: https://github.com/kornia/data/blob/main/print_image.png?raw=true

        N)printr   r   )r*   rq   r,   r,   r-   rr     s   zImage.print)r   r	   r   r   r   r   r   r   )r   r   )NN)r1   r   r2   r   r   r   )r   r   )r   r	   )r   r9   )r   r<   )r   r=   )r   r   )r   r   )r   r>   )r   r   )r   r   )r   r_   rG   r   r   r   r   r   )r   r_   )r   ri   r   r   )r   ri   )rj   rk   r   r   )rj   rk   r   r   )rp   )rq   r>   r   r   )$__name__
__module____qualname____doc__r.   r0   r5   r6   propertyr   r+   r2   r1   r   r   r   r    r!   r"   r   rA   rY   r\   r^   classmethodr   rL   r   r#   rc   rh   r   r   rn   ro   rr   r,   r,   r,   r-   r   &   sX    
(




 

(

r   )"
__future__r   pathlibr   typingr   r4   torch.utils.dlpackr   r   kornia.colorrM   kornia.corer   r   r	   kornia.core.checkr
   r   kornia.image.baser   r   r   r   r   kornia.io.ior   r   r   kornia.utils.image_printr   r_   ri   r   r,   r,   r,   r-   <module>   s   