o
    eb                     @   sX   d Z ddlmZmZmZ ddlZddlmZ	 ddl
mZ ddlmZ G dd	 d	eZdS )
zCClasses to represent heatmaps, i.e. float arrays of ``[0.0, 1.0]``.    )print_functiondivisionabsolute_importN   )imgaug   )IAugmentablec                   @   s   e Zd ZdZd1ddZdd Zd2d
dZd3ddZdd Zd4ddZ			d5ddZ
dd Zdd Zejdddd d! Zd6d#d$Zd%d& Zed1d'd(Zed1d)d*Zed+d, Zd-d. Zd/d0 ZdS )7HeatmapsOnImagea  Object representing heatmaps on a single image.

    Parameters
    ----------
    arr : (H,W) ndarray or (H,W,C) ndarray
        Array representing the heatmap(s) on a single image.
        Multiple heatmaps may be provided, in which case ``C`` is expected to
        denote the heatmap index.
        The array must be of dtype ``float32``.

    shape : tuple of int
        Shape of the image on which the heatmap(s) is/are placed.
        **Not** the shape of the heatmap(s) array, unless it is identical
        to the image shape (note the likely difference between the arrays
        in the number of channels).
        This is expected to be ``(H, W)`` or ``(H, W, C)`` with ``C`` usually
        being ``3``.
        If there is no corresponding image, use ``(H_arr, W_arr)`` instead,
        where ``H_arr`` is the height of the heatmap(s) array
        (analogous ``W_arr``).

    min_value : float, optional
        Minimum value for the heatmaps that `arr` represents. This will
        usually be ``0.0``.

    max_value : float, optional
        Maximum value for the heatmaps that `arr` represents. This will
        usually be ``1.0``.

                  ?c              	   C   s  t |sJ dt|f |jd dkr|jd dks$J d|jf |jjdv s2J d|jf |jdv s?J d|jf t|dv sLJ d	|f ||k sXJ d
||f t	|jj
}|jdd }t||| k }t||| k}|s||rt d||t|t|f  t|||}|jdkr|dtjf }d| _nd| _d| |  k od| k n  }	d| |  k od| k n  }
|	r|
r|| _n	|| ||  | _|| _|| _|| _dS )z'Construct a new HeatmapsOnImage object.z8Expected numpy array as heatmap input array, got type %sr   r   zSExpected numpy array as heatmap with height and width greater than 0, got shape %s.)float32zBHeatmap input array expected to be of dtype float32, got dtype %s.)r      z3Heatmap input array must be 2d or 3d, got shape %s.zJArgument 'shape' in HeatmapsOnImage expected to be 2d or 3d, got shape %s.z@Expected min_value to be lower than max_value, got %.4f and %.4f2   zValue range of heatmap was chosen to be (%.8f, %.8f), but found actual min/max of (%.8f, %.8f). Array will be clipped to chosen value range.r   .TFr
   r   N)iais_np_arraytypeshapedtypenamendimlennpfinfoepsZflatminmaxwarnclipnewaxis
arr_was_2darr_0to1	min_value	max_value)selfarrr   r!   r"   r   
componentsZ
beyond_minZ
beyond_maxmin_is_zero
max_is_one r(   LD:\Projects\ConvertPro\env\Lib\site-packages\imgaug/augmentables/heatmaps.py__init__+   sl   

  
zHeatmapsOnImage.__init__c                 C   s   | j r| jjd dkr| jdddddf }n| j}ttjj}d| | j  k o0d| k n  }d| | j  k oAd| k n  }|rM|rMt	|S | j| j }| j||  S )a  Get the heatmap's array in value range provided to ``__init__()``.

        The :class:`HeatmapsOnImage` object saves heatmaps internally in the
        value range ``[0.0, 1.0]``. This function converts the internal
        representation to ``[min, max]``, where ``min`` and ``max`` are
        provided to :func:`HeatmapsOnImage.__init__` upon instantiation of
        the object.

        Returns
        -------
        (H,W) ndarray or (H,W,C) ndarray
            Heatmap array of dtype ``float32``.

        r   r   Nr   r
   r   )
r   r    r   r   r   r   r   r!   r"   copy)r#   r$   r   r&   r'   diffr(   r(   r)   get_arrb   s   ""
zHeatmapsOnImage.get_arrNjetc                 C   s   |   }g }t|jd D ]^}|d||d f }|dur'tj||dd}n|}t|tj	d }|durOddl
m} ||}	|	|}
t|
d	d}
nt|dtjf d
}
t|
d ddtj}
||
 q|S )a  Render the heatmaps as RGB images.

        Parameters
        ----------
        size : None or float or iterable of int or iterable of float, optional
            Size of the rendered RGB image as ``(height, width)``.
            See :func:`~imgaug.imgaug.imresize_single_image` for details.
            If set to ``None``, no resizing is performed and the size of the
            heatmaps array is used.

        cmap : str or None, optional
            Name of the ``matplotlib`` color map to use when convert the
            heatmaps to RGB images.
            If set to ``None``, no color map will be used and the heatmaps
            will be converted to simple intensity maps.

        Returns
        -------
        list of (H,W,3) ndarray
            Rendered heatmaps as ``uint8`` arrays.
            Always a **list** containing one RGB image per heatmap array
            channel.

        r   .r   NZnearestinterpolation     o@r   r   )r   r   r      )to_uint8smxranger   r   imresize_single_imager   Zsqueezeastyper   Zmatplotlib.pyplotZpyplotZget_cmapdeleteZtiler   r   uint8append)r#   sizecmapZheatmaps_uint8heatmaps_drawncZ	heatmap_cZheatmap_c_rsZpltZ	cmap_funcZheatmap_cmappedr(   r(   r)   draw   s2   

zHeatmapsOnImage.draw      ?heatmapsc                    s   j dksJ dj jf jd dks J djd f jjdks/J djjf d   kr9dks@n J d	  |d
v sKJ d|f |dkr]tj| jjdd dd| j|dkrjjdd nd|d} fdd|D }|S )a7  Draw the heatmaps as overlays over an image.

        Parameters
        ----------
        image : (H,W,3) ndarray
            Image onto which to draw the heatmaps.
            Expected to be of dtype ``uint8``.

        alpha : float, optional
            Alpha/opacity value to use for the mixing of image and heatmaps.
            Larger values mean that the heatmaps will be more visible and the
            image less visible.

        cmap : str or None, optional
            Name of the ``matplotlib`` color map to use.
            See :func:`HeatmapsOnImage.draw` for details.

        resize : {'heatmaps', 'image'}, optional
            In case of size differences between the image and heatmaps,
            either the image or the heatmaps can be resized. This parameter
            controls which of the two will be resized to the other's size.

        Returns
        -------
        list of (H,W,3) ndarray
            Rendered overlays as ``uint8`` arrays.
            Always a **list** containing one RGB image per heatmap array
            channel.

        r   zUExpected to draw on three-dimensional image, got %d dimensions with shape %s instead.r   z,Expected RGB image, got %d channels instead.r9   z#Expected uint8 image, got dtype %s.g:0yEg1  ?z;Expected 'alpha' to be in the interval [0.0, 1.0], got %.4f)rA   imagez<Expected resize to be "heatmaps" or "image", got %s instead.rB   r   cubicr/   rA   N)r;   r<   c                    s2   g | ]}t d     |  ddt jqS )r   r   r2   )r   r   r7   r9   ).0Z	heatmap_ialpharB   r(   r)   
<listcomp>   s    z1HeatmapsOnImage.draw_on_image.<locals>.<listcomp>)r   r   r   r   r   r6   r    r?   )r#   rB   rF   r<   resizer=   Zmixr(   rE   r)   draw_on_image   sD    
zHeatmapsOnImage.draw_on_imagec                 C   s*   t jd| j | j| j| jd}| j|_|S )a  Invert each component in the heatmap.

        This shifts low values towards high values and vice versa.

        This changes each value to::

            v' = max - (v - min)

        where ``v`` is the value at a spatial location, ``min`` is the
        minimum value in the heatmap and ``max`` is the maximum value.
        As the heatmap uses internally a ``0.0`` to ``1.0`` representation,
        this simply becomes ``v' = 1.0 - v``.

        This function can be useful e.g. when working with depth maps, where
        algorithms might have an easier time representing the furthest away
        points with zeros, requiring an inverted depth map.

        Returns
        -------
        imgaug.augmentables.heatmaps.HeatmapsOnImage
            Inverted heatmap.

        r   r   r!   r"   )r	   	from_0to1r    r   r!   r"   r   )r#   Zarr_invr(   r(   r)   invert   s   zHeatmapsOnImage.invertr   constantc           	   	   C   s>   ddl m} |j| j||||||d}tj|| j| j| jdS )aP  Pad the heatmaps at their top/right/bottom/left side.

        Parameters
        ----------
        top : int, optional
            Amount of pixels to add at the top side of the heatmaps.
            Must be ``0`` or greater.

        right : int, optional
            Amount of pixels to add at the right side of the heatmaps.
            Must be ``0`` or greater.

        bottom : int, optional
            Amount of pixels to add at the bottom side of the heatmaps.
            Must be ``0`` or greater.

        left : int, optional
            Amount of pixels to add at the left side of the heatmaps.
            Must be ``0`` or greater.

        mode : string, optional
            Padding mode to use. See :func:`~imgaug.imgaug.pad` for details.

        cval : number, optional
            Value to use for padding `mode` is ``constant``.
            See :func:`~imgaug.imgaug.pad` for details.

        Returns
        -------
        imgaug.augmentables.heatmaps.HeatmapsOnImage
            Padded heatmaps of height ``H'=H+top+bottom`` and
            width ``W'=W+left+right``.

        r   r;   )toprightbottomleftmodecvalrJ   )	
augmentersr;   padr    r	   rK   r   r!   r"   )	r#   rO   rP   rQ   rR   rS   rT   iasizearr_0to1_paddedr(   r(   r)   rV      s    #	zHeatmapsOnImage.padFc           	      C   sN   ddl m} |j| j|||dd\}}tj|| j| j| jd}|r%||fS |S )aZ  Pad the heatmaps until they match a target aspect ratio.

        Depending on which dimension is smaller (height or width), only the
        corresponding sides (left/right or top/bottom) will be padded. In
        each case, both of the sides will be padded equally.

        Parameters
        ----------
        aspect_ratio : float
            Target aspect ratio, given as width/height. E.g. ``2.0`` denotes
            the image having twice as much width as height.

        mode : str, optional
            Padding mode to use.
            See :func:`~imgaug.imgaug.pad` for details.

        cval : number, optional
            Value to use for padding if `mode` is ``constant``.
            See :func:`~imgaug.imgaug.pad` for details.

        return_pad_amounts : bool, optional
            If ``False``, then only the padded instance will be returned.
            If ``True``, a tuple with two entries will be returned, where
            the first entry is the padded instance and the second entry are
            the amounts by which each array side was padded. These amounts are
            again a tuple of the form ``(top, right, bottom, left)``, with
            each value being an integer.

        Returns
        -------
        imgaug.augmentables.heatmaps.HeatmapsOnImage
            Padded heatmaps as :class:`HeatmapsOnImage` instance.

        tuple of int
            Amounts by which the instance's array was padded on each side,
            given as a tuple ``(top, right, bottom, left)``.
            This tuple is only returned if `return_pad_amounts` was set to
            ``True``.

        r   rN   T)aspect_ratiorS   rT   return_pad_amountsrJ   )	rU   r;   pad_to_aspect_ratior    r	   rK   r   r!   r"   )	r#   rY   rS   rT   rZ   rW   rX   Zpad_amountsrA   r(   r(   r)   r[   S  s"   *
z#HeatmapsOnImage.pad_to_aspect_ratioc                 C   s*   t j| j|dd}tj|| j| j| jdS )a  Average-pool the heatmap(s) array using a given block/kernel size.

        Parameters
        ----------
        block_size : int or tuple of int
            Size of each block of values to pool, aka kernel size.
            See :func:`~imgaug.imgaug.pool` for details.

        Returns
        -------
        imgaug.augmentables.heatmaps.HeatmapsOnImage
            Heatmaps after average pooling.

        r
   )Zpad_cvalrJ   )r   avg_poolr    r	   rK   r   r!   r"   r#   
block_sizeZarr_0to1_reducedr(   r(   r)   r\     s   zHeatmapsOnImage.avg_poolc                 C   s&   t | j|}tj|| j| j| jdS )a  Max-pool the heatmap(s) array using a given block/kernel size.

        Parameters
        ----------
        block_size : int or tuple of int
            Size of each block of values to pool, aka kernel size.
            See :func:`~imgaug.imgaug.pool` for details.

        Returns
        -------
        imgaug.augmentables.heatmaps.HeatmapsOnImage
            Heatmaps after max-pooling.

        rJ   )r   max_poolr    r	   rK   r   r!   r"   r]   r(   r(   r)   r_     s   zHeatmapsOnImage.max_poolzHeatmapsOnImage.resize()z(resize() has the exactly same interface.)Zalt_funccommentc                 O   s   | j |i |S )zBResize the heatmap(s) array given a target size and interpolation.)rH   )r#   argskwargsr(   r(   r)   scale  s   zHeatmapsOnImage.scalerC   c                 C   s8   t j| j||d}t|dd}tj|| j| j| j	dS )ad  Resize the heatmap(s) array given a target size and interpolation.

        Parameters
        ----------
        sizes : float or iterable of int or iterable of float
            New size of the array in ``(height, width)``.
            See :func:`~imgaug.imgaug.imresize_single_image` for details.

        interpolation : None or str or int, optional
            The interpolation to use during resize.
            See :func:`~imgaug.imgaug.imresize_single_image` for details.

        Returns
        -------
        imgaug.augmentables.heatmaps.HeatmapsOnImage
            Resized heatmaps object.

        r/   r
   r   rJ   )
r   r6   r    r   r   r	   rK   r   r!   r"   )r#   sizesr0   Zarr_0to1_resizedr(   r(   r)   rH     s   zHeatmapsOnImage.resizec                 C   s*   t t | jd dd}|t j}|S )zConvert this heatmaps object to an ``uint8`` array.

        Returns
        -------
        (H,W,C) ndarray
            Heatmap as an ``uint8`` array, i.e. with the discrete value
            range ``[0, 255]``.

        r2   r   )r   r   roundr    r7   r9   )r#   Z
arr_0to255	arr_uint8r(   r(   r)   r3     s   zHeatmapsOnImage.to_uint8c                 C   s"   |  tjd }tj||||dS )a  Create a ``float``-based heatmaps object from an ``uint8`` array.

        Parameters
        ----------
        arr_uint8 : (H,W) ndarray or (H,W,C) ndarray
            Heatmap(s) array, where ``H`` is height, ``W`` is width
            and ``C`` is the number of heatmap channels.
            Expected dtype is ``uint8``.

        shape : tuple of int
            Shape of the image on which the heatmap(s) is/are placed.
            **Not** the shape of the heatmap(s) array, unless it is identical
            to the image shape (note the likely difference between the arrays
            in the number of channels).
            If there is not a corresponding image, use the shape of the
            heatmaps array.

        min_value : float, optional
            Minimum value of the float heatmaps that the input array
            represents. This will usually be 0.0. In most other cases it will
            be close to the interval ``[0.0, 1.0]``.
            Calling :func:`~imgaug.HeatmapsOnImage.get_arr`, will automatically
            convert the interval ``[0.0, 1.0]`` float array to this
            ``[min, max]`` interval.

        max_value : float, optional
            Minimum value of the float heatmaps that the input array
            represents. This will usually be 1.0.
            See parameter `min_value` for details.

        Returns
        -------
        imgaug.augmentables.heatmaps.HeatmapsOnImage
            Heatmaps object.

        r1   r!   r"   )r7   r   r   r	   rK   )rf   r   r!   r"   r    r(   r(   r)   
from_uint8  s   &zHeatmapsOnImage.from_uint8c                 C   s    t | |ddd}||_||_|S )a  Create a heatmaps object from a ``[0.0, 1.0]`` float array.

        Parameters
        ----------
        arr_0to1 : (H,W) or (H,W,C) ndarray
            Heatmap(s) array, where ``H`` is the height, ``W`` is the width
            and ``C`` is the number of heatmap channels.
            Expected dtype is ``float32``.

        shape : tuple of ints
            Shape of the image on which the heatmap(s) is/are placed.
            **Not** the shape of the heatmap(s) array, unless it is identical
            to the image shape (note the likely difference between the arrays
            in the number of channels).
            If there is not a corresponding image, use the shape of the
            heatmaps array.

        min_value : float, optional
            Minimum value of the float heatmaps that the input array
            represents. This will usually be 0.0. In most other cases it will
            be close to the interval ``[0.0, 1.0]``.
            Calling :func:`~imgaug.HeatmapsOnImage.get_arr`, will automatically
            convert the interval ``[0.0, 1.0]`` float array to this
            ``[min, max]`` interval.

        max_value : float, optional
            Minimum value of the float heatmaps that the input array
            represents. This will usually be 1.0.
            See parameter `min_value` for details.

        Returns
        -------
        imgaug.augmentables.heatmaps.HeatmapsOnImage
            Heatmaps object.

        r
   r   rg   )r	   r!   r"   )r    r   r!   r"   rA   r(   r(   r)   rK     s   &zHeatmapsOnImage.from_0to1c                 C   s,  t |sJ dt|f dd }t|tr|j|jf}n|d| t|tr/|j|jf}n|d| t|j	j
}|d d|  |d   k oR|d d|  k n  }|d d|  |d   k ol|d d|  k n  }|rx|rxt|S |\}}	|\}
}|	| }||
 }|| | }|
||  }|S )	a  Change the value range of a heatmap array.

        E.g. the value range may be changed from the interval ``[0.0, 1.0]``
        to ``[-1.0, 1.0]``.

        Parameters
        ----------
        arr : ndarray
            Heatmap array to modify.

        source : tuple of float
            Current value range of the input array, given as a
            tuple ``(min, max)``, where both are ``float`` values.

        target : tuple of float
            Desired output value range of the array, given as a
            tuple ``(min, max)``, where both are ``float`` values.

        Returns
        -------
        ndarray
            Input array, with value range projected to the desired target
            value range.

        z-Expected 'arr' to be an ndarray, got type %s.c                 S   sl   t |tsJ d| t|f t|dksJ d| t|f |d |d k s4J d| |d |d f d S )NzO'%s' was not a HeatmapsOnImage instance, expected type tuple then. Got type %s.r   z;Expected tuple '%s' to contain exactly two entries, got %d.r   r   zYExpected tuple '%s' to have two entries with entry 1 < entry 2, got values %.4f and %.4f.)
isinstancetupler   r   )Zarg_name	arg_valuer(   r(   r)   _validate_tuplei  s"   
z=HeatmapsOnImage.change_normalization.<locals>._validate_tuplesourcetargetr   
   r   )r   r   r   ri   r	   r!   r"   r   r   r   r   r+   )clsr$   rm   rn   rl   r   Z	mins_sameZ	maxs_sameZ
min_sourceZ
max_sourceZ
min_targetZ
max_targetZdiff_sourceZdiff_targetr    Z
arr_targetr(   r(   r)   change_normalizationK  s,   



44
z$HeatmapsOnImage.change_normalizationc                 C   s   |   S )zCreate a shallow copy of the heatmaps object.

        Returns
        -------
        imgaug.augmentables.heatmaps.HeatmapsOnImage
            Shallow copy.

        )deepcopyr#   r(   r(   r)   r+     s   	zHeatmapsOnImage.copyc                 C   s   t |  | j| j| jdS )zCreate a deep copy of the heatmaps object.

        Returns
        -------
        imgaug.augmentables.heatmaps.HeatmapsOnImage
            Deep copy.

        rJ   )r	   r-   r   r!   r"   rs   r(   r(   r)   rr     s   	zHeatmapsOnImage.deepcopy)r
   r   )Nr.   )r@   r.   rA   )r   r   r   r   rM   r
   )rM   r
   F)rC   )__name__
__module____qualname____doc__r*   r-   r?   rI   rL   rV   r[   r\   r_   r   
deprecatedrc   rH   r3   staticmethodrh   rK   classmethodrq   r+   rr   r(   r(   r(   r)   r	      s6    
7
!
:C
 3
;

!+,
Jr	   )rw   
__future__r   r   r   numpyr   Z	six.movesmovesr4    r   r   baser   r	   r(   r(   r(   r)   <module>   s    