o
    e:/                     @   s   d Z ddlmZmZmZ ddlZddlZddl	m
Z ddlZdd Zdd Zdd	 Zd
d Zdd Zdd ZdddZdddZdd Zdd Zdd ZdddZdS )z.Utility functions used in augmentable modules.    )print_functionabsolute_importdivisionNc                 C   sP   t | r
t| S g }| D ]}t |r|t| q||  q|S N)iais_np_arraynpcopyappenddeepcopy)ZaugmentablesresultZaugmentable r   ID:\Projects\ConvertPro\env\Lib\site-packages\imgaug/augmentables/utils.pycopy_augmentables
   s   


r   c                 C   s   | d u rd S t | st | r| S t| trdd | D S t| tr,tdd | D S t | r6t| S t	| dr?| 
 S t
| S )Nc                 S      g | ]}t |qS r   deepcopy_fast.0elr   r   r   
<listcomp>       z!deepcopy_fast.<locals>.<listcomp>c                 S   r   r   r   r   r   r   r   r       r   r   )r   Zis_single_numberZ	is_string
isinstancelisttupler   r   r	   hasattrr   copylib)objr   r   r   r      s   





r   c                 C   s0   t | tr| S t| sJ dt| f | jS )a  Normalize a shape ``tuple`` or ``array`` to a shape ``tuple``.

    Parameters
    ----------
    shape : tuple of int or ndarray
        The input to normalize. May optionally be an array.

    Returns
    -------
    tuple of int
        Shape ``tuple``.

    z(Expected tuple of ints or array, got %s.)r   r   r   r   typeshape)r   r   r   r   normalize_shape)   s   
r    c           	      C   s   t |}t |}|dd |dd kr| S |dd \}}|dd \}}tdd ||||fD }|s=J d||f | }t| rJ| jjdkrSt| tj	}|dddf | | |dddf< |dddf | | |dddf< |S )	a  Project coordinates from one image shape to another in-place.

    This performs a relative projection, e.g. a point at ``60%`` of the old
    image width will be at ``60%`` of the new image width after projection.

    Added in 0.4.0.

    Parameters
    ----------
    coords : ndarray or list of tuple of number
        Coordinates to project.
        Either an ``(N,2)`` numpy array or a ``list`` containing ``(x,y)``
        coordinate ``tuple`` s.

    from_shape : tuple of int or ndarray
        Old image shape.

    to_shape : tuple of int or ndarray
        New image shape.

    Returns
    -------
    ndarray
        Projected coordinates as ``(N,2)`` ``float32`` numpy array.
        This function may change the input data in-place.

    r      c                 S   s   g | ]}|d kqS )r   r   r   vr   r   r   r   c   r   z#project_coords_.<locals>.<listcomp>zdExpected from_shape and to_shape to not contain zeros. Got shapes %s (from_shape) and %s (to_shape).fN   )
r    allr   r   Zdtypekindr   arrayZastypefloat32)	coords
from_shapeto_shapeZfrom_heightZ
from_widthZ	to_heightZto_widthZno_zeros_in_shapesZcoords_projr   r   r   project_coords_>   s&   $$r-   c                 C   s    t | r
t| } t| ||S )a  Project coordinates from one image shape to another.

    This performs a relative projection, e.g. a point at ``60%`` of the old
    image width will be at ``60%`` of the new image width after projection.

    Parameters
    ----------
    coords : ndarray or list of tuple of number
        Coordinates to project.
        Either an ``(N,2)`` numpy array or a ``list`` containing ``(x,y)``
        coordinate ``tuple`` s.

    from_shape : tuple of int or ndarray
        Old image shape.

    to_shape : tuple of int or ndarray
        New image shape.

    Returns
    -------
    ndarray
        Projected coordinates as ``(N,2)`` ``float32`` numpy array.

    )r   r   r   r	   r-   )r*   r+   r,   r   r   r   project_coordsr   s   

r.   c                    sZ   |dk rg S | \|\}}t | | g}|d|    fddt|D S )a  Interpolate ``N`` points on a line segment.

    Parameters
    ----------
    point_a : iterable of number
        Start point of the line segment, given as ``(x,y)`` coordinates.

    point_b : iterable of number
        End point of the line segment, given as ``(x,y)`` coordinates.

    nb_steps : int
        Number of points to interpolate between `point_a` and `point_b`.

    Returns
    -------
    list of tuple of number
        The interpolated points.
        Does not include `point_a`.

    r%   c                    s4   g | ]}|d   d   |d   d    fqS )r%   r   r   )r   iZ	step_sizex1y1r   r   r      s    &z*interpolate_point_pair.<locals>.<listcomp>)r   r)   smxrange)point_apoint_bnb_stepsZx2y2Zvecr   r0   r   interpolate_point_pair   s   r9   Tc                 C   s|   t | dkr| S |rt| | d g } g }t| dd | dd D ]\}}||gt|||  q"|s<|| d  |S )a7  Interpolate ``N`` on each line segment in a line string.

    Parameters
    ----------
    points : iterable of iterable of number
        Points on the line segments, each one given as ``(x,y)`` coordinates.
        They are assumed to form one connected line string.

    nb_steps : int
        Number of points to interpolate on each individual line string.

    closed : bool, optional
        If ``True`` the output contains the last point in `points`.
        Otherwise it does not (but it will contain the interpolated points
        leading to the last point).

    Returns
    -------
    list of tuple of number
        Coordinates of `points`, with additional `nb_steps` new points
        interpolated between each point pair. If `closed` is ``False``,
        the last point in `points` is not returned.

    r%   r   N)lenr   zipextendr9   r
   )pointsr7   closedpoints_interpr5   r6   r   r   r   interpolate_points   s   "
rA   c                 C   s   |dksJ d|f t | dkr| S |rt| | d g } g }t| dd | dd D ]/\}}t|d |d  d |d |d  d  }t|| d }||gt|||  q-|sf|| d  |S )a  Interpolate points with distance ``d`` on a line string.

    For a list of points ``A, B, C``, if the distance between ``A`` and ``B``
    is greater than `max_distance`, it will place at least one point between
    ``A`` and ``B`` at ``A + max_distance * (B - A)``. Multiple points can
    be placed between the two points if they are far enough away from each
    other. The process is repeated for ``B`` and ``C``.

    Parameters
    ----------
    points : iterable of iterable of number
        Points on the line segments, each one given as ``(x,y)`` coordinates.
        They are assumed to form one connected line string.

    max_distance : number
        Maximum distance between any two points in the result.

    closed : bool, optional
        If ``True`` the output contains the last point in `points`.
        Otherwise it does not (but it will contain the interpolated points
        leading to the last point).

    Returns
    -------
    list of tuple of number
        Coordinates of `points`, with interpolated points added to the
        iterable. If `closed` is ``False``, the last point in `points` is not
        returned.

    r   z3Expected max_distance to have a value >0, got %.8f.r%   Nr:   r!   )	r;   r   r<   r   sqrtintr=   r9   r
   )r>   Zmax_distancer?   r@   r5   r6   distr7   r   r   r   "interpolate_points_by_max_distance   s2   
"
rE   c                 C   s2   t | ts	|  S g }| D ]	}||  q|S )a  Convert coordinate-based augmentables to KeypointsOnImage instances.

    Added in 0.4.0.

    Parameters
    ----------
    cbaois : list of imgaug.augmentables.bbs.BoundingBoxesOnImage or list of imgaug.augmentables.bbs.PolygonsOnImage or list of imgaug.augmentables.bbs.LineStringsOnImage or imgaug.augmentables.bbs.BoundingBoxesOnImage or imgaug.augmentables.bbs.PolygonsOnImage or imgaug.augmentables.bbs.LineStringsOnImage
        Coordinate-based augmentables to convert, e.g. bounding boxes.

    Returns
    -------
    list of imgaug.augmentables.kps.KeypointsOnImage or imgaug.augmentables.kps.KeypointsOnImage
        ``KeypointsOnImage`` instances containing the coordinates of input
        `cbaois`.

    )r   r   Zto_keypoints_on_imager
   )cbaoiskpsoiscbaoir   r   r   convert_cbaois_to_kpsois  s   
rI   c                 C   sb   t | tst |trJ dt|j f| |S g }t| |D ]\}}||}|| q |S )a  Invert the output of :func:`convert_to_cbaois_to_kpsois` in-place.

    This function writes in-place into `cbaois`.

    Added in 0.4.0.

    Parameters
    ----------
    cbaois : list of imgaug.augmentables.bbs.BoundingBoxesOnImage or list of imgaug.augmentables.bbs.PolygonsOnImage or list of imgaug.augmentables.bbs.LineStringsOnImage or imgaug.augmentables.bbs.BoundingBoxesOnImage or imgaug.augmentables.bbs.PolygonsOnImage or imgaug.augmentables.bbs.LineStringsOnImage
        Original coordinate-based augmentables before they were converted,
        i.e. the same inputs as provided to :func:`convert_to_kpsois`.

    kpsois : list of imgaug.augmentables.kps.KeypointsOnImages or imgaug.augmentables.kps.KeypointsOnImages
        Keypoints to convert back to the types of `cbaois`, i.e. the outputs
        of :func:`convert_cbaois_to_kpsois`.

    Returns
    -------
    list of imgaug.augmentables.bbs.BoundingBoxesOnImage or list of imgaug.augmentables.bbs.PolygonsOnImage or list of imgaug.augmentables.bbs.LineStringsOnImage or imgaug.augmentables.bbs.BoundingBoxesOnImage or imgaug.augmentables.bbs.PolygonsOnImage or imgaug.augmentables.bbs.LineStringsOnImage
        Parameter `cbaois`, with updated coordinates and shapes derived from
        `kpsois`. `cbaois` is modified in-place.

    zFExpected non-list for `kpsois` when `cbaois` is non-list. Got type %s.)r   r   r   __name__Zinvert_to_keypoints_on_image_r<   r
   )rF   rG   r   rH   ZkpsoiZcbaoi_recoveredr   r   r    invert_convert_cbaois_to_kpsois_+  s   


rK   c                    s    fdd j D  _  S )Nc                    s    g | ]}|  jk r|qS r   )Zcompute_out_of_image_fractionr   )r   itemrH   fractionr   r   r   S  s
    z2_remove_out_of_image_fraction_.<locals>.<listcomp>)itemsrM   r   rM   r   _remove_out_of_image_fraction_R  s   rP   c                 C   s   t dd ||||fD rFtjd||||f dd |dur |nd}|dur(|nd}|dur0|nd}|dur8|nd}| | | } || | }| |fS )zCNormalize ``shift()`` arguments to x, y and handle deprecated args.c                 S   s   g | ]}|d uqS r   r   r"   r   r   r   r   \  r   z)_normalize_shift_args.<locals>.<listcomp>zGot one of the arguments `top` (%s), `right` (%s), `bottom` (%s), `left` (%s) in a shift() call. These are deprecated. Use `x` and `y` instead.   )
stacklevelNr   )anyr   Zwarn_deprecated)xytoprightbottomleftr   r   r   _normalize_shift_argsZ  s   rZ   )T)NNNN)__doc__
__future__r   r   r   r	   r   numpyr   Z	six.movesmovesr3   Zimgaugr   r   r   r    r-   r.   r9   rA   rE   rI   rK   rP   rZ   r   r   r   r   <module>   s$    4 
!
*4'