o
    ep                     @   s   d Z ddlmZmZmZ ddlmZmZ ddlZddl	Z	ddl
ZddlZddlmZ ddlmZ d	d
 Ze	eG dd dejZG dd deZG dd deZG dd deZG dd deZdS )z
Augmenters that apply pooling operations to images.

List of augmenters:

    * :class:`AveragePooling`
    * :class:`MaxPooling`
    * :class:`MinPooling`
    * :class:`MedianPooling`

    )print_functiondivisionabsolute_import)ABCMetaabstractmethodN   )meta   )
parametersc                 C   s   t dd | D r| S | dd \}}|| dkr!||||  7 }|| dkr/||||  7 }t|| || gt| dd   S )Nc                 S   s   g | ]}|d kqS )r    ).0Zaxisr   r   ID:\Projects\ConvertPro\env\Lib\site-packages\imgaug/augmenters/pooling.py
<listcomp>   s    z0_compute_shape_after_pooling.<locals>.<listcomp>r   r	   )anytuplelist)Zimage_shapeksize_hksize_wheightwidthr   r   r   _compute_shape_after_pooling   s   r   c                       s   e Zd Z			d fdd	Zedd Zdd	 Zd
d Zdd Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Z  ZS )_AbstractPoolingBaseTN
deprecatedc                    s<   t t| j||||d tj|dddd| _|| _d| _d S )N)seednamerandom_statedeterministickernel_size)r   NF)Zvalue_rangeZallow_floatsT)superr   __init__iapZ!handle_discrete_kernel_size_paramr   	keep_size_resize_hm_and_sm_arraysselfr   r!   r   r   r   r   	__class__r   r   r   .   s   

z_AbstractPoolingBase.__init__c                 C   s   dS )z@Apply pooling method with given kernel height/width to an image.Nr   r$   imageZkernel_size_hZkernel_size_wr   r   r   _pool_image=   s    z _AbstractPoolingBase._pool_imagec                 C   s~   | d}| jd d u rdnd}| jd j|f|d d}|dkr$|}n| jd j|f|d d}t|dd t|dd fS )Nr	   r   singletwor   )r   )Z	duplicater   Zdraw_samplesnpZclip)r$   nb_rowsr   Zrssmodekernel_sizes_hkernel_sizes_wr   r   r   _draw_samplesA   s   



z"_AbstractPoolingBase._draw_samplesc                 C   sZ   |j d u r
| jr
|S | |j|}|jD ]}t| d|jf |j|}t||j	| q|S )Nz_augment_%s_by_samples)
imagesr!   r1   r-   columnsgetattrr   valuesetattrZ	attr_name)r$   batchr   parentshookssamplescolumnZ	value_augr   r   r   _augment_batch_R   s   
z$_AbstractPoolingBase._augment_batch_c                 C   s   | j st|}|\}}tt|||}|D ](\}\}}}	|dks$|	dkr=| |||	}
| j r9t|
|jdd }
|
||< q|S Nr	   r   )r!   r   	enumeratezipr)   iaZimresize_single_imageshape)r$   r2   r:   r/   r0   genir(   r   r   Zimage_pooledr   r   r   _augment_images_by_samples_   s    z/_AbstractPoolingBase._augment_images_by_samplesc                 C      |  ||dS )NZarr_0to1#_augment_hms_and_segmaps_by_samples)r$   Zheatmapsr:   r   r   r   _augment_heatmaps_by_samplesr      z1_AbstractPoolingBase._augment_heatmaps_by_samplesc                 C   rE   )NZarrrF   )r$   Zsegmapsr:   r   r   r   %_augment_segmentation_maps_by_samplesw   rI   z:_AbstractPoolingBase._augment_segmentation_maps_by_samplesc                 C   s   | j r|S |\}}tt|||}|D ]3\}\}}	}
|	dks"|
dkrF| jr8tt||j|	|
}||dd }t|j|	|
}||_|||< q|S r=   )r!   r>   r?   r"   r   r4   rA   resize)r$   Zaugmentablesr:   Zarr_attr_namer/   r0   rB   rC   Zaugmentabler   r   Znew_shape_arr	new_shaper   r   r   rG   |   s&   
z8_AbstractPoolingBase._augment_hms_and_segmaps_by_samplesc                 C   sf   | j r|S |\}}tt|||}|D ]\}\}}}	|dks"|	dkr0t|j||	}
||
||< q|S )Nr	   )r!   r>   r?   r   rA   Zon_)r$   Zkeypoints_on_imagesr:   r/   r0   rB   rC   Zkpsoir   r   rL   r   r   r   _augment_keypoints_by_samples   s   z2_AbstractPoolingBase._augment_keypoints_by_samplesc                 C   s    t j| j|d}| j||d dS )Nr:   )Z	recoverer)	functoolspartialrM   Z_apply_to_polygons_as_keypoints)r$   Zpolygons_on_imagesr:   funcr   r   r   _augment_polygons_by_samples   s   z1_AbstractPoolingBase._augment_polygons_by_samplesc                 C      t j| j|d}| ||S NrN   rO   rP   rM   Z_apply_to_cbaois_as_keypoints)r$   Zline_strings_on_imagesr:   rQ   r   r   r    _augment_line_strings_by_samples   s   z5_AbstractPoolingBase._augment_line_strings_by_samplesc                 C   rS   rT   rU   )r$   Zbounding_boxes_on_imagesr:   rQ   r   r   r   "_augment_bounding_boxes_by_samples   s   z7_AbstractPoolingBase._augment_bounding_boxes_by_samplesc                 C   s   | j | jgS )z=See :func:`~imgaug.augmenters.meta.Augmenter.get_parameters`.)r   r!   )r$   r   r   r   get_parameters   s   z#_AbstractPoolingBase.get_parameters)TNNr   r   )__name__
__module____qualname__r   r   r)   r1   r<   rD   rH   rJ   rG   rM   rR   rV   rW   rX   __classcell__r   r   r%   r   r   *   s$    
r   c                       0   e Zd ZdZ			d
 fdd	Zdd	 Z  ZS )AveragePoolinga  
    Apply average pooling to images.

    This augmenter pools images with kernel sizes ``H x W`` by averaging the
    pixel values within these windows. For e.g. ``2 x 2`` this halves the image
    size. Optionally, the augmenter will automatically re-upscale the image
    to the input size (by default this is activated).

    Note that this augmenter is very similar to ``AverageBlur``.
    ``AverageBlur`` applies averaging within windows of given kernel size
    *without* striding, while ``AveragePooling`` applies striding corresponding
    to the kernel size, with optional upscaling afterwards. The upscaling
    is configured to create "pixelated"/"blocky" images by default.

    .. note::

        During heatmap or segmentation map augmentation, the respective
        arrays are not changed, only the shapes of the underlying images
        are updated. This is because imgaug can handle maps/maks that are
        larger/smaller than their corresponding image.

    **Supported dtypes**:

    See :func:`~imgaug.imgaug.avg_pool`.

    Attributes
    ----------
    kernel_size : int or tuple of int or list of int or imgaug.parameters.StochasticParameter or tuple of tuple of int or tuple of list of int or tuple of imgaug.parameters.StochasticParameter, optional
        The kernel size of the pooling operation.

        * If an int, then that value will be used for all images for both
          kernel height and width.
        * If a tuple ``(a, b)``, then a value from the discrete range
          ``[a..b]`` will be sampled per image.
        * If a list, then a random value will be sampled from that list per
          image and used for both kernel height and width.
        * If a StochasticParameter, then a value will be sampled per image
          from that parameter per image and used for both kernel height and
          width.
        * If a tuple of tuple of int given as ``((a, b), (c, d))``, then two
          values will be sampled independently from the discrete ranges
          ``[a..b]`` and ``[c..d]`` per image and used as the kernel height
          and width.
        * If a tuple of lists of int, then two values will be sampled
          independently per image, one from the first list and one from the
          second, and used as the kernel height and width.
        * If a tuple of StochasticParameter, then two values will be sampled
          indepdently per image, one from the first parameter and one from the
          second, and used as the kernel height and width.

    keep_size : bool, optional
        After pooling, the result image will usually have a different
        height/width compared to the original input image. If this
        parameter is set to True, then the pooled image will be resized
        to the input image's size, i.e. the augmenter's output shape is always
        identical to the input shape.

    seed : None or int or imgaug.random.RNG or numpy.random.Generator or numpy.random.BitGenerator or numpy.random.SeedSequence or numpy.random.RandomState, optional
        See :func:`~imgaug.augmenters.meta.Augmenter.__init__`.

    name : None or str, optional
        See :func:`~imgaug.augmenters.meta.Augmenter.__init__`.

    random_state : None or int or imgaug.random.RNG or numpy.random.Generator or numpy.random.BitGenerator or numpy.random.SeedSequence or numpy.random.RandomState, optional
        Old name for parameter `seed`.
        Its usage will not yet cause a deprecation warning,
        but it is still recommended to use `seed` now.
        Outdated since 0.4.0.

    deterministic : bool, optional
        Deprecated since 0.4.0.
        See method ``to_deterministic()`` for an alternative and for
        details about what the "deterministic mode" actually does.

    Examples
    --------
    >>> import imgaug.augmenters as iaa
    >>> aug = iaa.AveragePooling(2)

    Create an augmenter that always pools with a kernel size of ``2 x 2``.

    >>> aug = iaa.AveragePooling(2, keep_size=False)

    Create an augmenter that always pools with a kernel size of ``2 x 2``
    and does *not* resize back to the input image size, i.e. the resulting
    images have half the resolution.

    >>> aug = iaa.AveragePooling([2, 8])

    Create an augmenter that always pools either with a kernel size
    of ``2 x 2`` or ``8 x 8``.

    >>> aug = iaa.AveragePooling((1, 7))

    Create an augmenter that always pools with a kernel size of
    ``1 x 1`` (does nothing) to ``7 x 7``. The kernel sizes are always
    symmetric.

    >>> aug = iaa.AveragePooling(((1, 7), (1, 7)))

    Create an augmenter that always pools with a kernel size of
    ``H x W`` where ``H`` and ``W`` are both sampled independently from the
    range ``[1..7]``. E.g. resulting kernel sizes could be ``3 x 7``
    or ``5 x 1``.

    r      TNr   c                        t t| j||||||d d S N)r   r!   r   r   r   r   )r   r^   r   r#   r%   r   r   r   5  
   

zAveragePooling.__init__c                 C      t |||fS N)r@   Zavg_poolr'   r   r   r   r)   =  s   zAveragePooling._pool_imager_   TNNr   r   rY   rZ   r[   __doc__r   r)   r\   r   r   r%   r   r^      s    mr^   c                       r]   )
MaxPoolinga  
    Apply max pooling to images.

    This augmenter pools images with kernel sizes ``H x W`` by taking the
    maximum pixel value over windows. For e.g. ``2 x 2`` this halves the image
    size. Optionally, the augmenter will automatically re-upscale the image
    to the input size (by default this is activated).

    The maximum within each pixel window is always taken channelwise..

    .. note::

        During heatmap or segmentation map augmentation, the respective
        arrays are not changed, only the shapes of the underlying images
        are updated. This is because imgaug can handle maps/maks that are
        larger/smaller than their corresponding image.

    **Supported dtypes**:

    See :func:`~imgaug.imgaug.max_pool`.

    Attributes
    ----------
    kernel_size : int or tuple of int or list of int or imgaug.parameters.StochasticParameter or tuple of tuple of int or tuple of list of int or tuple of imgaug.parameters.StochasticParameter, optional
        The kernel size of the pooling operation.

        * If an int, then that value will be used for all images for both
          kernel height and width.
        * If a tuple ``(a, b)``, then a value from the discrete range
          ``[a..b]`` will be sampled per image.
        * If a list, then a random value will be sampled from that list per
          image and used for both kernel height and width.
        * If a StochasticParameter, then a value will be sampled per image
          from that parameter per image and used for both kernel height and
          width.
        * If a tuple of tuple of int given as ``((a, b), (c, d))``, then two
          values will be sampled independently from the discrete ranges
          ``[a..b]`` and ``[c..d]`` per image and used as the kernel height
          and width.
        * If a tuple of lists of int, then two values will be sampled
          independently per image, one from the first list and one from the
          second, and used as the kernel height and width.
        * If a tuple of StochasticParameter, then two values will be sampled
          indepdently per image, one from the first parameter and one from the
          second, and used as the kernel height and width.

    keep_size : bool, optional
        After pooling, the result image will usually have a different
        height/width compared to the original input image. If this
        parameter is set to True, then the pooled image will be resized
        to the input image's size, i.e. the augmenter's output shape is always
        identical to the input shape.

    seed : None or int or imgaug.random.RNG or numpy.random.Generator or numpy.random.BitGenerator or numpy.random.SeedSequence or numpy.random.RandomState, optional
        See :func:`~imgaug.augmenters.meta.Augmenter.__init__`.

    name : None or str, optional
        See :func:`~imgaug.augmenters.meta.Augmenter.__init__`.

    random_state : None or int or imgaug.random.RNG or numpy.random.Generator or numpy.random.BitGenerator or numpy.random.SeedSequence or numpy.random.RandomState, optional
        Old name for parameter `seed`.
        Its usage will not yet cause a deprecation warning,
        but it is still recommended to use `seed` now.
        Outdated since 0.4.0.

    deterministic : bool, optional
        Deprecated since 0.4.0.
        See method ``to_deterministic()`` for an alternative and for
        details about what the "deterministic mode" actually does.

    Examples
    --------
    >>> import imgaug.augmenters as iaa
    >>> aug = iaa.MaxPooling(2)

    Create an augmenter that always pools with a kernel size of ``2 x 2``.

    >>> aug = iaa.MaxPooling(2, keep_size=False)

    Create an augmenter that always pools with a kernel size of ``2 x 2``
    and does *not* resize back to the input image size, i.e. the resulting
    images have half the resolution.

    >>> aug = iaa.MaxPooling([2, 8])

    Create an augmenter that always pools either with a kernel size
    of ``2 x 2`` or ``8 x 8``.

    >>> aug = iaa.MaxPooling((1, 7))

    Create an augmenter that always pools with a kernel size of
    ``1 x 1`` (does nothing) to ``7 x 7``. The kernel sizes are always
    symmetric.

    >>> aug = iaa.MaxPooling(((1, 7), (1, 7)))

    Create an augmenter that always pools with a kernel size of
    ``H x W`` where ``H`` and ``W`` are both sampled independently from the
    range ``[1..7]``. E.g. resulting kernel sizes could be ``3 x 7``
    or ``5 x 1``.

    r_   TNr   c                    ra   rb   )r   ri   r   r#   r%   r   r   r     rc   zMaxPooling.__init__c                 C   rd   re   )r@   Zmax_poolr'   r   r   r   r)        zMaxPooling._pool_imagerf   rg   r   r   r%   r   ri   D      iri   c                       r]   )
MinPoolinga  
    Apply minimum pooling to images.

    This augmenter pools images with kernel sizes ``H x W`` by taking the
    minimum pixel value over windows. For e.g. ``2 x 2`` this halves the image
    size. Optionally, the augmenter will automatically re-upscale the image
    to the input size (by default this is activated).

    The minimum within each pixel window is always taken channelwise.

    .. note::

        During heatmap or segmentation map augmentation, the respective
        arrays are not changed, only the shapes of the underlying images
        are updated. This is because imgaug can handle maps/maks that are
        larger/smaller than their corresponding image.

    **Supported dtypes**:

    See :func:`~imgaug.imgaug.min_pool`.

    Attributes
    ----------
    kernel_size : int or tuple of int or list of int or imgaug.parameters.StochasticParameter or tuple of tuple of int or tuple of list of int or tuple of imgaug.parameters.StochasticParameter, optional
        The kernel size of the pooling operation.

        * If an int, then that value will be used for all images for both
          kernel height and width.
        * If a tuple ``(a, b)``, then a value from the discrete range
          ``[a..b]`` will be sampled per image.
        * If a list, then a random value will be sampled from that list per
          image and used for both kernel height and width.
        * If a StochasticParameter, then a value will be sampled per image
          from that parameter per image and used for both kernel height and
          width.
        * If a tuple of tuple of int given as ``((a, b), (c, d))``, then two
          values will be sampled independently from the discrete ranges
          ``[a..b]`` and ``[c..d]`` per image and used as the kernel height
          and width.
        * If a tuple of lists of int, then two values will be sampled
          independently per image, one from the first list and one from the
          second, and used as the kernel height and width.
        * If a tuple of StochasticParameter, then two values will be sampled
          indepdently per image, one from the first parameter and one from the
          second, and used as the kernel height and width.

    keep_size : bool, optional
        After pooling, the result image will usually have a different
        height/width compared to the original input image. If this
        parameter is set to True, then the pooled image will be resized
        to the input image's size, i.e. the augmenter's output shape is always
        identical to the input shape.

    seed : None or int or imgaug.random.RNG or numpy.random.Generator or numpy.random.BitGenerator or numpy.random.SeedSequence or numpy.random.RandomState, optional
        See :func:`~imgaug.augmenters.meta.Augmenter.__init__`.

    name : None or str, optional
        See :func:`~imgaug.augmenters.meta.Augmenter.__init__`.

    random_state : None or int or imgaug.random.RNG or numpy.random.Generator or numpy.random.BitGenerator or numpy.random.SeedSequence or numpy.random.RandomState, optional
        Old name for parameter `seed`.
        Its usage will not yet cause a deprecation warning,
        but it is still recommended to use `seed` now.
        Outdated since 0.4.0.

    deterministic : bool, optional
        Deprecated since 0.4.0.
        See method ``to_deterministic()`` for an alternative and for
        details about what the "deterministic mode" actually does.

    Examples
    --------
    >>> import imgaug.augmenters as iaa
    >>> aug = iaa.MinPooling(2)

    Create an augmenter that always pools with a kernel size of ``2 x 2``.

    >>> aug = iaa.MinPooling(2, keep_size=False)

    Create an augmenter that always pools with a kernel size of ``2 x 2``
    and does *not* resize back to the input image size, i.e. the resulting
    images have half the resolution.

    >>> aug = iaa.MinPooling([2, 8])

    Create an augmenter that always pools either with a kernel size
    of ``2 x 2`` or ``8 x 8``.

    >>> aug = iaa.MinPooling((1, 7))

    Create an augmenter that always pools with a kernel size of
    ``1 x 1`` (does nothing) to ``7 x 7``. The kernel sizes are always
    symmetric.

    >>> aug = iaa.MinPooling(((1, 7), (1, 7)))

    Create an augmenter that always pools with a kernel size of
    ``H x W`` where ``H`` and ``W`` are both sampled independently from the
    range ``[1..7]``. E.g. resulting kernel sizes could be ``3 x 7``
    or ``5 x 1``.

    r_   TNr   c                    ra   rb   )r   rl   r   r#   r%   r   r   r   )  rc   zMinPooling.__init__c                 C   rd   re   )r@   Zmin_poolr'   r   r   r   r)   1  rj   zMinPooling._pool_imagerf   rg   r   r   r%   r   rl     rk   rl   c                       r]   )MedianPoolinga  
    Apply median pooling to images.

    This augmenter pools images with kernel sizes ``H x W`` by taking the
    median pixel value over windows. For e.g. ``2 x 2`` this halves the image
    size. Optionally, the augmenter will automatically re-upscale the image
    to the input size (by default this is activated).

    The median within each pixel window is always taken channelwise.

    .. note::

        During heatmap or segmentation map augmentation, the respective
        arrays are not changed, only the shapes of the underlying images
        are updated. This is because imgaug can handle maps/maks that are
        larger/smaller than their corresponding image.

    **Supported dtypes**:

    See :func:`~imgaug.imgaug.median_pool`.

    Attributes
    ----------
    kernel_size : int or tuple of int or list of int or imgaug.parameters.StochasticParameter or tuple of tuple of int or tuple of list of int or tuple of imgaug.parameters.StochasticParameter, optional
        The kernel size of the pooling operation.

        * If an int, then that value will be used for all images for both
          kernel height and width.
        * If a tuple ``(a, b)``, then a value from the discrete range
          ``[a..b]`` will be sampled per image.
        * If a list, then a random value will be sampled from that list per
          image and used for both kernel height and width.
        * If a StochasticParameter, then a value will be sampled per image
          from that parameter per image and used for both kernel height and
          width.
        * If a tuple of tuple of int given as ``((a, b), (c, d))``, then two
          values will be sampled independently from the discrete ranges
          ``[a..b]`` and ``[c..d]`` per image and used as the kernel height
          and width.
        * If a tuple of lists of int, then two values will be sampled
          independently per image, one from the first list and one from the
          second, and used as the kernel height and width.
        * If a tuple of StochasticParameter, then two values will be sampled
          indepdently per image, one from the first parameter and one from the
          second, and used as the kernel height and width.

    keep_size : bool, optional
        After pooling, the result image will usually have a different
        height/width compared to the original input image. If this
        parameter is set to True, then the pooled image will be resized
        to the input image's size, i.e. the augmenter's output shape is always
        identical to the input shape.

    seed : None or int or imgaug.random.RNG or numpy.random.Generator or numpy.random.BitGenerator or numpy.random.SeedSequence or numpy.random.RandomState, optional
        See :func:`~imgaug.augmenters.meta.Augmenter.__init__`.

    name : None or str, optional
        See :func:`~imgaug.augmenters.meta.Augmenter.__init__`.

    random_state : None or int or imgaug.random.RNG or numpy.random.Generator or numpy.random.BitGenerator or numpy.random.SeedSequence or numpy.random.RandomState, optional
        Old name for parameter `seed`.
        Its usage will not yet cause a deprecation warning,
        but it is still recommended to use `seed` now.
        Outdated since 0.4.0.

    deterministic : bool, optional
        Deprecated since 0.4.0.
        See method ``to_deterministic()`` for an alternative and for
        details about what the "deterministic mode" actually does.

    Examples
    --------
    >>> import imgaug.augmenters as iaa
    >>> aug = iaa.MedianPooling(2)

    Create an augmenter that always pools with a kernel size of ``2 x 2``.

    >>> aug = iaa.MedianPooling(2, keep_size=False)

    Create an augmenter that always pools with a kernel size of ``2 x 2``
    and does *not* resize back to the input image size, i.e. the resulting
    images have half the resolution.

    >>> aug = iaa.MedianPooling([2, 8])

    Create an augmenter that always pools either with a kernel size
    of ``2 x 2`` or ``8 x 8``.

    >>> aug = iaa.MedianPooling((1, 7))

    Create an augmenter that always pools with a kernel size of
    ``1 x 1`` (does nothing) to ``7 x 7``. The kernel sizes are always
    symmetric.

    >>> aug = iaa.MedianPooling(((1, 7), (1, 7)))

    Create an augmenter that always pools with a kernel size of
    ``H x W`` where ``H`` and ``W`` are both sampled independently from the
    range ``[1..7]``. E.g. resulting kernel sizes could be ``3 x 7``
    or ``5 x 1``.

    r_   TNr   c                    ra   rb   )r   rm   r   r#   r%   r   r   r     rc   zMedianPooling.__init__c                 C   rd   re   )r@   Zmedian_poolr'   r   r   r   r)     rj   zMedianPooling._pool_imagerf   rg   r   r   r%   r   rm   :  rk   rm   )rh   
__future__r   r   r   abcr   r   rO   sixnumpyr,   Zimgaugr@    r   r
   r    r   add_metaclassZ	Augmenterr   r^   ri   rl   rm   r   r   r   r   <module>   s"     }{{