U
    diCz                     @   sR  d dl Z d dlZd dlmZ d dlmZmZmZmZm	Z	m
Z
m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mZmZmZmZmZmZmZ ddlmZmZm Z m!Z!m"Z"m#Z# e r>d dl$Z%d dl&Z%e'e'e%j(j)e'dkre%j*j+Z,ne%j*Z,e r>d d	l-m.Z. e,j/e.j/e,j0e.j0e,j1e.j1e,j2e.j2e,j3e.j3e,j4e.j4iZ5erTe rTd dl6Z6e7e8Z9ed
ej:ded
 eej: ed f Z;eed
 dded ed eed
  eed  eed  f Z<G dd deZ=G dd deZ>G dd deZ?ee@eeAe@ee f f ZBdd ZCG dd deZDdd ZEdd ZFdd ZGdd ZHej:eId d!d"ZJdMeAee; d$d%d&ZKej:d'd(d)ZLdNej:e	eeAe
eAd*f f  e=d+d,d-ZMdOej:e	ee=e@f  eAd.d/d0ZNdPej:e=e
eAeAf d1d2d3ZOee@eee
f f eId4d5d6ZPee@eee
f f eId4d7d8ZQeee@eee
f f  eId9d:d;ZReee@eee
f f  eId9d<d=ZSdQee@d
f e	eT d
d>d?d@ZUdRe	eI e	eT e	eI e	eeTeeT f  e	eeTeeT f  e	eI e	eA e	eI e	ee@eAf  e	eI e	ee@eAf  e	dA dBdCdDZVG dEdF dFZWe>e
e>d*f ee ddGdHdIZXee@ ee@ dJdKdLZYdS )S    N)BytesIO)TYPE_CHECKINGDictIterableListOptionalTupleUnion)version   )ExplicitEnumis_jax_tensoris_numpy_arrayis_tf_tensoris_torch_availableis_torch_tensoris_torchvision_availableis_vision_availableloggingrequires_backendsto_numpy)IMAGENET_DEFAULT_MEANIMAGENET_DEFAULT_STDIMAGENET_STANDARD_MEANIMAGENET_STANDARD_STDOPENAI_CLIP_MEANOPENAI_CLIP_STDz9.1.0)InterpolationModezPIL.Image.Imageztorch.Tensorz
np.ndarrayznp.ndarrrayc                   @   s   e Zd ZdZdZdS )ChannelDimensionZchannels_firstZchannels_lastN)__name__
__module____qualname__FIRSTLAST r$   r$   </tmp/pip-unpacked-wheel-bm_b0l5e/transformers/image_utils.pyr   _   s   r   c                   @   s   e Zd ZdZdZdS )AnnotationFormatZcoco_detectionZcoco_panopticN)r   r    r!   COCO_DETECTIONCOCO_PANOPTICr$   r$   r$   r%   r&   d   s   r&   c                   @   s   e Zd ZejjZejjZdS )AnnotionFormatN)r   r    r!   r&   r'   valuer(   r$   r$   r$   r%   r)   i   s   r)   c                 C   s   t  ot| tjjS N)r   
isinstancePILImageimgr$   r$   r%   is_pil_imageq   s    r1   c                   @   s    e Zd ZdZdZdZdZdZdS )	ImageTypeZpillowtorchnumpyZ
tensorflowZjaxN)r   r    r!   r-   TORCHNUMPY
TENSORFLOWJAXr$   r$   r$   r%   r2   u   s
   r2   c                 C   s\   t | rtjS t| rtjS t| r*tjS t| r8tjS t	| rFtj
S tdt|  d S )NzUnrecognised image type )r1   r2   r-   r   r5   r   r6   r   r7   r   r8   
ValueErrortypeimager$   r$   r%   get_image_type}   s    r=   c                 C   s(   t | p&t| p&t| p&t| p&t| S r+   )r1   r   r   r   r   r/   r$   r$   r%   is_valid_image   s    r>   c                 C   s8   t | ttfr(| D ]}t|s dS qnt| s4dS dS )NFT)r,   listtuplevalid_imagesr>   )Zimgsr0   r$   r$   r%   rA      s    
rA   c                 C   s   t | ttfrt| d S dS )Nr   F)r,   r?   r@   r>   r/   r$   r$   r%   
is_batched   s    rB   )r<   returnc                 C   s,   | j tjkrdS t| dko*t| dkS )zV
    Checks to see whether the pixel values have already been rescaled to [0, 1].
    Fr   r   )dtypenpuint8minmaxr;   r$   r$   r%   is_scaled_image   s    rI      )expected_ndimsrC   c                 C   s   t | r| S t| tjjr | gS t| rx| j|d kr@t| } n4| j|krR| g} n"td|d  d| d| j d| S tdt|  ddS )	a  
    Ensure that the input is a list of images. If the input is a single image, it is converted to a list of length 1.
    If the input is a batch of images, it is converted to a list of images.

    Args:
        images (`ImageInput`):
            Image of images to turn into a list of images.
        expected_ndims (`int`, *optional*, defaults to 3):
            Expected number of dimensions for a single input image. If the input image has a different number of
            dimensions, an error is raised.
    r   z%Invalid image shape. Expected either z or z dimensions, but got z dimensions.ztInvalid image type. Expected either PIL.Image.Image, numpy.ndarray, torch.Tensor, tf.Tensor or jax.ndarray, but got .N)	rB   r,   r-   r.   r>   ndimr?   r9   r:   )ZimagesrK   r$   r$   r%   make_list_of_images   s     

rN   )rC   c                 C   s@   t | stdt|  t r8t| tjjr8t| S t	| S )NzInvalid image type: )
r>   r9   r:   r   r,   r-   r.   rE   arrayr   r/   r$   r$   r%   to_numpy_array   s
    
rP   .)r<   num_channelsrC   c                 C   s   |dk	r|nd}t |tr |fn|}| jdkr8d\}}n$| jdkrLd\}}ntd| j | j| |kr| j| |krtd| j d tjS | j| |krtjS | j| |krtj	S td	dS )
a[  
    Infers the channel dimension format of `image`.

    Args:
        image (`np.ndarray`):
            The image to infer the channel dimension of.
        num_channels (`int` or `Tuple[int, ...]`, *optional*, defaults to `(1, 3)`):
            The number of channels of the image.

    Returns:
        The channel dimension of the image.
    Nr   rJ   rJ   )r         z(Unsupported number of image dimensions: z4The channel dimension is ambiguous. Got image shape z,. Assuming channels are the first dimension.z(Unable to infer channel dimension format)
r,   intrM   r9   shapeloggerwarningr   r"   r#   )r<   rQ   Z	first_dimZlast_dimr$   r$   r%   infer_channel_dimension_format   s"    



rY   )r<   input_data_formatrC   c                 C   sJ   |dkrt | }|tjkr$| jd S |tjkr8| jd S td| dS )a  
    Returns the channel dimension axis of the image.

    Args:
        image (`np.ndarray`):
            The image to get the channel dimension axis of.
        input_data_format (`ChannelDimension` or `str`, *optional*):
            The channel dimension format of the image. If `None`, will infer the channel dimension from the image.

    Returns:
        The channel dimension axis of the image.
    NrJ   r   Unsupported data format: )rY   r   r"   rM   r#   r9   )r<   rZ   r$   r$   r%   get_channel_dimension_axis  s    



r\   )r<   channel_dimrC   c                 C   s^   |dkrt | }|tjkr.| jd | jd fS |tjkrL| jd | jd fS td| dS )a  
    Returns the (height, width) dimensions of the image.

    Args:
        image (`np.ndarray`):
            The image to get the dimensions of.
        channel_dim (`ChannelDimension`, *optional*):
            Which dimension the channel dimension is in. If `None`, will infer the channel dimension from the image.

    Returns:
        A tuple of the image's height and width.
    Nr[   )rY   r   r"   rV   r#   r9   )r<   r]   r$   r$   r%   get_image_size  s    

ra   )
annotationrC   c                 C   sV   t | trRd| krRd| krRt | d ttfrRt| d dksNt | d d trRdS dS )Nimage_idannotationsr   TFr,   dictr?   r@   lenrb   r$   r$   r%   "is_valid_annotation_coco_detection1  s    
ri   c                 C   s^   t | trZd| krZd| krZd| krZt | d ttfrZt| d dksVt | d d trZdS dS )Nrc   Zsegments_info	file_namer   TFre   rh   r$   r$   r%   !is_valid_annotation_coco_panoptic@  s     rk   )rd   rC   c                 C   s   t dd | D S )Nc                 s   s   | ]}t |V  qd S r+   )ri   .0annr$   r$   r%   	<genexpr>Q  s     z3valid_coco_detection_annotations.<locals>.<genexpr>allrd   r$   r$   r%    valid_coco_detection_annotationsP  s    rs   c                 C   s   t dd | D S )Nc                 s   s   | ]}t |V  qd S r+   )rk   rl   r$   r$   r%   ro   U  s     z2valid_coco_panoptic_annotations.<locals>.<genexpr>rp   rr   r$   r$   r%   valid_coco_panoptic_annotationsT  s    rt   )r<   timeoutrC   c              
   C   s  t tdg t| tr| ds*| drHtjtt	j
| |dj} qtj| rbtj| } q| drz| dd } z"t|  }tjt|} W q tk
r } ztd|  d	| W 5 d
}~X Y qX nt| tjjr| } ntdtj| } | d} | S )a3  
    Loads `image` to a PIL Image.

    Args:
        image (`str` or `PIL.Image.Image`):
            The image to convert to the PIL Image format.
        timeout (`float`, *optional*):
            The timeout value in seconds for the URL request.

    Returns:
        `PIL.Image.Image`: A PIL Image.
    Zvisionzhttp://zhttps://)ru   zdata:image/,r   zIncorrect image source. Must be a valid URL starting with `http://` or `https://`, a valid path to an image file, or a base64 encoded string. Got z. Failed with NzuIncorrect format used for image. Should be an url linking to an image, a base64 string, a local path, or a PIL image.RGB)r   
load_imager,   str
startswithr-   r.   openr   requestsgetcontentospathisfilesplitbase64decodebytesencode	Exceptionr9   	TypeErrorZImageOpsZexif_transposeconvert)r<   ru   Zb64er$   r$   r%   rx   X  s.    


rx   PILImageResamplingZ
do_rescaleZrescale_factorZdo_normalizeZ
image_meanZ	image_stdZdo_padZsize_divisibilityZdo_center_cropZ	crop_sizeZ	do_resizesizeresamplec                 C   sx   | r|dkrt d|r(|dkr(t d|rD|dks<|dkrDt d|rX|dkrXt d|	rt|
dksl|dkrtt ddS )a  
    Checks validity of typically used arguments in an `ImageProcessor` `preprocess` method.
    Raises `ValueError` if arguments incompatibility is caught.
    Many incompatibilities are model-specific. `do_pad` sometimes needs `size_divisor`,
    sometimes `size_divisibility`, and sometimes `size`. New models and processors added should follow
    existing arguments when possible.

    Nz=`rescale_factor` must be specified if `do_rescale` is `True`.zzDepending on the model, `size_divisibility`, `size_divisor`, `pad_size` or `size` must be specified if `do_pad` is `True`.zP`image_mean` and `image_std` must both be specified if `do_normalize` is `True`.z<`crop_size` must be specified if `do_center_crop` is `True`.zA`size` and `resample` must be specified if `do_resize` is `True`.)r9   r   r$   r$   r%   validate_preprocess_arguments  s    r   c                   @   s   e Zd ZdZdd ZdddZdd Zeje	e
ef ejd	d
dZdddZdd ZdddZd ddZdd Zdd Zd!ddZdS )"ImageFeatureExtractionMixinzD
    Mixin that contain utilities for preparing image features.
    c                 C   s4   t |tjjtjfs0t|s0tdt| dd S )Nz	Got type zS which is not supported, only `PIL.Image.Image`, `np.array` and `torch.Tensor` are.)r,   r-   r.   rE   ndarrayr   r9   r:   selfr<   r$   r$   r%   _ensure_format_supported  s    z4ImageFeatureExtractionMixin._ensure_format_supportedNc                 C   s   |  | t|r| }t|tjr|dkr@t|jd tj}|jdkrf|j	d dkrf|
ddd}|rr|d }|tj}tj|S |S )a"  
        Converts `image` to a PIL Image. Optionally rescales it and puts the channel dimension back as the last axis if
        needed.

        Args:
            image (`PIL.Image.Image` or `numpy.ndarray` or `torch.Tensor`):
                The image to convert to the PIL Image format.
            rescale (`bool`, *optional*):
                Whether or not to apply the scaling factor (to make pixel values integers between 0 and 255). Will
                default to `True` if the image type is a floating type, `False` otherwise.
        Nr   rJ   rR   r   rS      )r   r   r4   r,   rE   r   flatZfloatingrM   rV   	transposeastyperF   r-   r.   Z	fromarray)r   r<   rescaler$   r$   r%   to_pil_image  s    
z(ImageFeatureExtractionMixin.to_pil_imagec                 C   s&   |  | t|tjjs|S |dS )z
        Converts `PIL.Image.Image` to RGB format.

        Args:
            image (`PIL.Image.Image`):
                The image to convert.
        rw   )r   r,   r-   r.   r   r   r$   r$   r%   convert_rgb  s    
z'ImageFeatureExtractionMixin.convert_rgb)r<   scalerC   c                 C   s   |  | || S )z7
        Rescale a numpy image by scale amount
        )r   )r   r<   r   r$   r$   r%   r     s    
z#ImageFeatureExtractionMixin.rescaleTc                 C   s   |  | t|tjjr"t|}t|r2| }|dkrLt|jd tj	n|}|rh| 
|tjd}|r|jdkr|ddd}|S )a  
        Converts `image` to a numpy array. Optionally rescales it and puts the channel dimension as the first
        dimension.

        Args:
            image (`PIL.Image.Image` or `np.ndarray` or `torch.Tensor`):
                The image to convert to a NumPy array.
            rescale (`bool`, *optional*):
                Whether or not to apply the scaling factor (to make pixel values floats between 0. and 1.). Will
                default to `True` if the image is a PIL Image or an array/tensor of integers, `False` otherwise.
            channel_first (`bool`, *optional*, defaults to `True`):
                Whether or not to permute the dimensions of the image to put the channel dimension first.
        Nr   p?rJ   rS   r   )r   r,   r-   r.   rE   rO   r   r4   r   integerr   r   float32rM   r   )r   r<   r   channel_firstr$   r$   r%   rP     s    

z*ImageFeatureExtractionMixin.to_numpy_arrayc                 C   sB   |  | t|tjjr|S t|r0|d}ntj|dd}|S )z
        Expands 2-dimensional `image` to 3 dimensions.

        Args:
            image (`PIL.Image.Image` or `np.ndarray` or `torch.Tensor`):
                The image to expand.
        r   )Zaxis)r   r,   r-   r.   r   Z	unsqueezerE   expand_dimsr   r$   r$   r%   r     s    
z'ImageFeatureExtractionMixin.expand_dimsFc                 C   sv  |  | t|tjjr(| j|dd}n>|rft|tjrN| |tj	d}nt
|rf| | d}t|tjrt|tjst||j}t|tjst||j}nrt
|r"ddl}t||jst|tjr||}n
||}t||js"t|tjr||}n
||}|jdkrf|jd dkrf||ddddf  |ddddf  S || | S dS )a  
        Normalizes `image` with `mean` and `std`. Note that this will trigger a conversion of `image` to a NumPy array
        if it's a PIL Image.

        Args:
            image (`PIL.Image.Image` or `np.ndarray` or `torch.Tensor`):
                The image to normalize.
            mean (`List[float]` or `np.ndarray` or `torch.Tensor`):
                The mean (per channel) to use for normalization.
            std (`List[float]` or `np.ndarray` or `torch.Tensor`):
                The standard deviation (per channel) to use for normalization.
            rescale (`bool`, *optional*, defaults to `False`):
                Whether or not to rescale the image to be between 0 and 1. If a PIL image is provided, scaling will
                happen automatically.
        T)r   r   r   NrJ   rR   )r   r,   r-   r.   rP   rE   r   r   r   r   r   floatrO   rD   r3   ZTensorZ
from_numpyZtensorrM   rV   )r   r<   ZmeanZstdr   r3   r$   r$   r%   	normalize!  s4    



(z%ImageFeatureExtractionMixin.normalizec                 C   sT  |dk	r|nt j}| | t|tjjs4| |}t|trFt|}t|t	s^t
|dkrF|rt|t	rt||fn|d |d f}n|j\}}||kr||fn||f\}}	t|t	r|n|d }
||
kr|S |
t	|
|	 |  }}|dk	r,||
krtd| d| ||kr,t	|| | | }}||kr>||fn||f}|j||dS )a  
        Resizes `image`. Enforces conversion of input to PIL.Image.

        Args:
            image (`PIL.Image.Image` or `np.ndarray` or `torch.Tensor`):
                The image to resize.
            size (`int` or `Tuple[int, int]`):
                The size to use for resizing the image. If `size` is a sequence like (h, w), output size will be
                matched to this.

                If `size` is an int and `default_to_square` is `True`, then image will be resized to (size, size). If
                `size` is an int and `default_to_square` is `False`, then smaller edge of the image will be matched to
                this number. i.e, if height > width, then image will be rescaled to (size * height / width, size).
            resample (`int`, *optional*, defaults to `PILImageResampling.BILINEAR`):
                The filter to user for resampling.
            default_to_square (`bool`, *optional*, defaults to `True`):
                How to convert `size` when it is a single int. If set to `True`, the `size` will be converted to a
                square (`size`,`size`). If set to `False`, will replicate
                [`torchvision.transforms.Resize`](https://pytorch.org/vision/stable/transforms.html#torchvision.transforms.Resize)
                with support for resizing only the smallest edge and providing an optional `max_size`.
            max_size (`int`, *optional*, defaults to `None`):
                The maximum allowed for the longer edge of the resized image: if the longer edge of the image is
                greater than `max_size` after being resized according to `size`, then the image is resized again so
                that the longer edge is equal to `max_size`. As a result, `size` might be overruled, i.e the smaller
                edge may be shorter than `size`. Only used if `default_to_square` is `False`.

        Returns:
            image: A resized `PIL.Image.Image`.
        Nr   r   zmax_size = zN must be strictly greater than the requested size for the smaller edge size = )r   )r   BILINEARr   r,   r-   r.   r   r?   r@   rU   rg   r   r9   resize)r   r<   r   r   Zdefault_to_squaremax_sizewidthheightshortlongZrequested_new_shortZ	new_shortZnew_longr$   r$   r%   r   U  s0    


$



z"ImageFeatureExtractionMixin.resizec                 C   s  |  | t|ts||f}t|s0t|tjrp|jdkrD| |}|jd dkr`|jdd n|jdd }n|j	d |j	d f}|d |d  d }||d  }|d |d  d }||d  }t|t
jjr|||||fS |jd dkrdnd}|s4t|tjr|ddd}t|r4|ddd}|dkrz||d krz|dkrz||d krz|d||||f S |jdd	 t|d |d t|d |d f }	t|tjrtj||	d
}
nt|r||	}
|	d	 |d  d }||d  }|	d |d  d }||d  }||
d||||f< ||7 }||7 }||7 }||7 }|
dtd|t|
jd	 |td|t|
jd |f }
|
S )a  
        Crops `image` to the given size using a center crop. Note that if the image is too small to be cropped to the
        size given, it will be padded (so the returned result has the size asked).

        Args:
            image (`PIL.Image.Image` or `np.ndarray` or `torch.Tensor` of shape (n_channels, height, width) or (height, width, n_channels)):
                The image to resize.
            size (`int` or `Tuple[int, int]`):
                The size to which crop the image.

        Returns:
            new_image: A center cropped `PIL.Image.Image` or `np.ndarray` or `torch.Tensor` of shape: (n_channels,
            height, width).
        rS   r   rR   r   NTF.r^   )rV   r_   )r   r,   r@   r   rE   r   rM   r   rV   r   r-   r.   Zcropr   ZpermuterH   Z
zeros_likeZ	new_zerosrG   )r   r<   r   Zimage_shapetopZbottomleftrightr   Z	new_shapeZ	new_imageZtop_padZ
bottom_padZleft_padZ	right_padr$   r$   r%   center_crop  sZ    



,
02

   z'ImageFeatureExtractionMixin.center_cropc                 C   s>   |  | t|tjjr"| |}|dddddddf S )a  
        Flips the channel order of `image` from RGB to BGR, or vice versa. Note that this will trigger a conversion of
        `image` to a NumPy array if it's a PIL Image.

        Args:
            image (`PIL.Image.Image` or `np.ndarray` or `torch.Tensor`):
                The image whose color channels to flip. If `np.ndarray` or `torch.Tensor`, the channel dimension should
                be first.
        Nr_   )r   r,   r-   r.   rP   r   r$   r$   r%   flip_channel_order  s    


z.ImageFeatureExtractionMixin.flip_channel_orderr   c                 C   sL   |dk	r|nt jj}| | t|t jjs6| |}|j||||||dS )a  
        Returns a rotated copy of `image`. This method returns a copy of `image`, rotated the given number of degrees
        counter clockwise around its centre.

        Args:
            image (`PIL.Image.Image` or `np.ndarray` or `torch.Tensor`):
                The image to rotate. If `np.ndarray` or `torch.Tensor`, will be converted to `PIL.Image.Image` before
                rotating.

        Returns:
            image: A rotated `PIL.Image.Image`.
        N)r   expandcenter	translate	fillcolor)r-   r.   NEARESTr   r,   r   rotate)r   r<   Zangler   r   r   r   r   r$   r$   r%   r     s    

     z"ImageFeatureExtractionMixin.rotate)N)NT)F)NTN)Nr   NNN)r   r    r!   __doc__r   r   r   rE   r   r	   r   rU   r   rP   r   r   r   r   r   r   r$   r$   r$   r%   r     s   

 
4
CKr   )annotation_formatsupported_annotation_formatsrd   rC   c                 C   sT   | |krt dt d| | tjkr6t|s6t d| tjkrPt|sPt dd S )NzUnsupported annotation format: z must be one of zInvalid COCO detection annotations. Annotations must a dict (single image) or list of dicts (batch of images) with the following keys: `image_id` and `annotations`, with the latter being a list of annotations in the COCO format.zInvalid COCO panoptic annotations. Annotations must a dict (single image) or list of dicts (batch of images) with the following keys: `image_id`, `file_name` and `segments_info`, with the latter being a list of annotations in the COCO format.)r9   formatr&   r'   rs   r(   rt   )r   r   rd   r$   r$   r%   validate_annotations  s    

r   )valid_processor_keyscaptured_kwargsc                 C   s6   t |t | }|r2d|}td| d d S )Nz, zUnused or unrecognized kwargs: rL   )set
differencejoinrW   rX   )r   r   Zunused_keysZunused_key_strr$   r$   r%   validate_kwargs&  s    
r   )rJ   )N)N)N)N)NNNNNNNNNNNN)Zr   r   ior   typingr   r   r   r   r   r   r	   r4   rE   r|   	packagingr
   utilsr   r   r   r   r   r   r   r   r   r   r   Zutils.constantsr   r   r   r   r   r   Z	PIL.Imager-   ZPIL.ImageOpsparse__version__base_versionr.   Z
Resamplingr   Ztorchvision.transformsr   r   ZBOXr   ZHAMMINGZBICUBICZLANCZOSZpil_torch_interpolation_mappingr3   Z
get_loggerr   rW   r   Z
ImageInputZ
VideoInputr   r&   r)   ry   rU   ZAnnotationTyper1   r2   r=   r>   rA   rB   boolrI   rN   rP   rY   r\   ra   ri   rk   rs   rt   r   rx   r   r   r   r   r$   r$   r$   r%   <module>   s   $4 

      




'
  &    $$ -            *  b
