U
    hc7                     @  s  d dl mZ d dlmZmZ d dlmZ d dlmZ d dl	m
Z
mZmZmZmZmZ d dlZddlmZ dd	lmZmZmZmZmZ e
rd dlZd
ddddZdddddZdddddZG dd dZG dd deeZG dd deZ dd d!d"d#d$Z!d%d&d'd(d)Z"d*d d&d+d,d-Z#d*d*d*d&d.d/d0Z$d*d*d*d1d2d3d4Z%ed>d5dd dd6d7d8Z&ed?d9dd d:d6d;d8Z&d@d<dd d1d6d=d8Z&dS )A    )annotations)ABCabstractmethod)defaultdict)Real)TYPE_CHECKINGAnyLiteralSequencecastoverloadN   )Serializable)PAIR
ScalarTypeScaleFloatTypeScaleIntType	ScaleTypeznp.ndarray | torch.Tensortuple[int, int])imgreturnc                 C  sl   t | tjr| jd d S z&dd l}|| r>| jdd  W S W n tk
rT   Y nX tdt|  d S )N   r   zVAlbumentations supports only numpy.ndarray and torch.Tensor data type for image. Got: )	
isinstancenpndarrayshapetorchZ	is_tensorImportErrorRuntimeErrortype)r   r    r!   =/tmp/pip-unpacked-wheel-e8onvpoz/albumentations/core/utils.py	get_shape   s    
r#   dict[str, Any]str)	args_dictr   c                 C  sR   g }|   D ]:\}}t|tr*d| dnt|}|| d|  qd|S )N'=z, )itemsr   r%   appendjoin)r&   Zformatted_argskvZv_formattedr!   r!   r"   format_args"   s
    r.   r   ztuple[int, Real | str])itemr   c                 C  s   t | trd| fS dt| fS )Nr   r   )r   r   r%   )r/   r!   r!   r"   custom_sort*   s    
r0   c                   @  sZ   e Zd ZddddZdd dddZdd	dd
dZdd	dddZdd	dddZdS )LabelEncoderNoner   c                 C  s   i | _ i | _d| _d| _d S )Nr   T)classes_inverse_classes_num_classesis_numericalselfr!   r!   r"   __init__1   s    zLabelEncoder.__init__zSequence[Any] | np.ndarray)yr   c                 C  s   t |tjr|  }tdd |D | _| jr6| S tt|t	d}|D ]4}|| j
krJ| j| j
|< || j| j< |  jd7  _qJ| S )Nc                 s  s   | ]}t |tV  qd S Nr   r   .0labelr!   r!   r"   	<genexpr>;   s     z#LabelEncoder.fit.<locals>.<genexpr>)keyr   )r   r   r   flattentolistallr7   sortedsetr0   r4   r6   r5   )r9   r;   Zunique_labelsr@   r!   r!   r"   fit7   s    
zLabelEncoder.fit
np.ndarrayc                   s@   t |tjr|  } jr(t|S t fdd|D S )Nc                   s   g | ]} j | qS r!   )r4   r>   r8   r!   r"   
<listcomp>O   s     z*LabelEncoder.transform.<locals>.<listcomp>r   r   r   rC   rD   r7   arrayr9   r;   r!   r8   r"   	transformH   s
    
zLabelEncoder.transformc                 C  s   |  | | |S r<   )rH   rN   rM   r!   r!   r"   fit_transformQ   s    
zLabelEncoder.fit_transformc                   s@   t |tjr|  } jr(t|S t fdd|D S )Nc                   s   g | ]} j | qS r!   )r5   r>   r8   r!   r"   rJ   \   s     z2LabelEncoder.inverse_transform.<locals>.<listcomp>rK   rM   r!   r8   r"   inverse_transformU   s
    
zLabelEncoder.inverse_transformN)__name__
__module____qualname__r:   rH   rN   rO   rP   r!   r!   r!   r"   r1   0   s
   	r1   c                   @  s*   e Zd ZdddddZdddd	Zd
S )Paramsr   zSequence[str] | Noneformatlabel_fieldsc                 C  s   || _ || _d S r<   rU   )r9   rV   rW   r!   r!   r"   r:   `   s    zParams.__init__r$   r3   c                 C  s   | j | jdS )NrU   rU   r8   r!   r!   r"   to_dict_privated   s    zParams.to_dict_privateN)rQ   rR   rS   r:   rX   r!   r!   r!   r"   rT   _   s   rT   c                   @  s  e Zd Zd?dddddZeeddd	d
ZdddddZdddddZdddddZ	dddddZ
dddddZd@ddddd d!d"Zedddd#d$d%Zedddd#d&d'Zedddd#d(d)Zedddd#d*d+Zdddd,d-Zdddd.d/d0Zddddd1d2d3Zddddd1d4d5Zdddd6d7Zdddd8d9Zdddd.d:d;Zddddd<d=d>ZdS )ADataProcessorNrT   zdict[str, str] | None)paramsadditional_targetsc                 C  s@   || _ | jg| _tt| _i | _tt| _|d k	r<| | d S r<   )	rZ   default_data_namedata_fieldsr   dictlabel_encodersis_sequence_inputis_numerical_labeladd_targets)r9   rZ   r[   r!   r!   r"   r:   i   s    


zDataProcessor.__init__r%   r3   c                 C  s   t d S r<   )NotImplementedErrorr8   r!   r!   r"   r\   s   s    zDataProcessor.default_data_namezdict[str, str]r2   )r[   r   c                 C  s6   |  D ](\}}|| jkr|| jkr| j| qdS )zFAdd targets to transform them the same way as one of existing targets.N)r)   r\   r]   r*   )r9   r[   r,   r-   r!   r!   r"   rb   x   s    zDataProcessor.add_targetsr$   )datar   c                 C  s   d S r<   r!   )r9   rd   r!   r!   r"   ensure_data_valid~   s    zDataProcessor.ensure_data_validzSequence[object])
transformsr   c                 C  s   d S r<   r!   )r9   rf   r!   r!   r"   ensure_transforms_valid   s    z%DataProcessor.ensure_transforms_validc                 C  s   t |d }| |}t| jt| @ D ]}| || |||< |dkrt|| dkrtjg tj	d
dt| jj||< | j|| |dd||< | j|dr,||  ||< q,|S )Nimage	keypointsr   Zdtypefrom	directionF)r#   remove_label_fields_from_datarG   r]   keysfilterlenr   rL   float32reshaperZ   rV   check_and_convertr`   getrD   r9   rd   image_shape	data_namer!   r!   r"   postprocess   s    
$zDataProcessor.postprocessc                 C  s   t |d }t| jt| @ D ]@}t|| trXd| j|< tj|| tj	d||< q"d| j|< q"| 
|}t| jt| @ D ]}| j|| |dd||< qd S )Nrh   Trj   Ftorl   )r#   rG   r]   ro   r   r
   r`   r   rL   rr   add_label_fields_to_datart   rv   r!   r!   r"   
preprocess   s    

zDataProcessor.preprocessrz   rI   r   zLiteral[('to', 'from')])rd   rw   rm   r   c                 C  s:   | j jdkr| || |S |dkr*| jn| j}|||S )NZalbumentationsrz   )rZ   rV   checkconvert_to_albumentationsconvert_from_albumentations)r9   rd   rw   rm   Zprocess_funcr!   r!   r"   rt      s
    zDataProcessor.check_and_convert)rd   rw   r   c                 C  s   d S r<   r!   r9   rd   rw   r!   r!   r"   rp      s    zDataProcessor.filterc                 C  s   d S r<   r!   r   r!   r!   r"   r}      s    zDataProcessor.checkc                 C  s   d S r<   r!   r   r!   r!   r"   r~      s    z'DataProcessor.convert_to_albumentationsc                 C  s   d S r<   r!   r   r!   r!   r"   r      s    z)DataProcessor.convert_from_albumentationsc                 C  sH   | j js|S t| jt| @ D ] }|| js2q"| ||||< q"|S r<   )rZ   rW   rG   r]   ro   size_process_label_fieldsr9   rd   rx   r!   r!   r"   r{      s    
z&DataProcessor.add_label_fields_to_data)rd   rx   r   c                 C  sV   || }| j jd k	rR| j jD ]4}| ||| | |||}t||f}||= q|S r<   )rZ   rW   _validate_label_field_length_encode_label_fieldr   Zhstack)r9   rd   rx   
data_arraylabel_fieldencoded_labelsr!   r!   r"   r      s    z#DataProcessor._process_label_fields)rd   rx   r   r   c                 C  sN   t || t || krJtd| d| dt ||  dt ||  d	d S )NzThe lengths of z and z do not match. Got z respectively.)rq   
ValueError)r9   rd   rx   r   r!   r!   r"   r      s    ,z*DataProcessor._validate_label_field_lengthc                 C  sr   t dd || D }|| j| |< |rDtj|| tjdddS t }||| dd}|| j| |< |S )Nc                 s  s   | ]}t |ttfV  qd S r<   r   intfloatr>   r!   r!   r"   rA      s     z4DataProcessor._encode_label_field.<locals>.<genexpr>rj   r   )	rE   ra   r   rL   rr   rs   r1   rO   r_   )r9   rd   rx   r   r7   encoderr   r!   r!   r"   r      s    z!DataProcessor._encode_label_fieldc                 C  sN   | j js|S t| jt| @ D ]&}|| js<| | q"| || q"|S r<   )rZ   rW   rG   r]   ro   r   _handle_empty_data_array_remove_label_fieldsr   r!   r!   r"   rn      s    

z+DataProcessor.remove_label_fields_from_datac                 C  s&   | j jd k	r"| j jD ]}g ||< qd S r<   )rZ   rW   )r9   rd   r   r!   r!   r"   r      s    z&DataProcessor._handle_empty_data_arrayc           
      C  s   | j jd krd S || }t| j j}|jd | }t| j jD ]6\}}|d d || f }| |||}	|	 ||< q>|d d d |f ||< d S )Nr   )rZ   rW   rq   r   	enumerate_decode_label_fieldrD   )
r9   rd   rx   r   Znum_label_fieldsZnon_label_columnsidxr   r   Zdecoded_labelsr!   r!   r"   r     s    z"DataProcessor._remove_label_fields)rx   r   r   r   c                 C  sN   | j | | r|S | j|i |}|r:||tS td| dd S )NzLabel encoder for z
 not found)ra   r_   ru   rP   Zastyper   r   )r9   rx   r   r   r   r!   r!   r"   r     s    z!DataProcessor._decode_label_field)N)rz   )rQ   rR   rS   r:   propertyr   r\   rb   re   rg   ry   r|   rt   rp   r}   r~   r   r{   r   r   r   rn   r   r   r   r!   r!   r!   r"   rY   h   s6   
 
rY   zScaleType | NonezScalarType | Noner2   )lowbiasr   c                 C  s   | d k	r|d k	rt dd S )Nz3Arguments 'low' and 'bias' cannot be used together.)r   )r   r   r!   r!   r"   validate_args  s    r   zSequence[ScalarType]ztuple[ScalarType, ScalarType])paramr   c                 C  s$   t | tkrtdt| t| fS )Nz)Sequence must contain exactly 2 elements.)rq   r   r   minmax)r   r!   r!   r"   process_sequence   s    r   r   )r   r   r   c                 C  s,   t |tr"|| k r|| fS | |fS |  | fS r<   r=   )r   r   r!   r!   r"   process_scalar&  s    
r   )min_valmax_valr   r   c                 C  s   ||  || fS r<   r!   )r   r   r   r!   r!   r"   
apply_bias,  s    r   z%tuple[int, int] | tuple[float, float])r   r   r   r   c                 C  s*   t |trt| t|fS t| t|fS r<   r   )r   r   r   r!   r!   r"   ensure_int_output0  s    r   r   )r   r   r   r   c                 C  s   d S r<   r!   r   r   r   r!   r!   r"   to_tuple8  s    r   r   ztuple[float, float]c                 C  s   d S r<   r!   r   r!   r!   r"   r   <  s    r   c                 C  s   t || t| tr"t| \}}n(t| trBt| tt|\}}ntd|dk	rbt	|||\}}t
||t| ttfrz| n|S )a  Convert input argument to a min-max tuple.

    This function processes various input types and returns a tuple representing a range.
    It handles single values, sequences, and can apply optional low bounds or biases.

    Args:
        param (ScaleType): The primary input value. Can be:
            - A single int or float: Converted to a symmetric range around zero.
            - A tuple of two ints or two floats: Used directly as min and max values.

        low (ScaleType | None, optional): A lower bound value. Used when param is a single value.
            If provided, the result will be (low, param) or (param, low), depending on which is smaller.
            Cannot be used together with 'bias'. Defaults to None.

        bias (ScalarType | None, optional): A value to be added to both elements of the resulting tuple.
            Cannot be used together with 'low'. Defaults to None.

    Returns:
        tuple[int, int] | tuple[float, float]: A tuple representing the processed range.
            - If input is int-based, returns tuple[int, int]
            - If input is float-based, returns tuple[float, float]

    Raises:
        ValueError: If both 'low' and 'bias' are provided.
        TypeError: If 'param' is neither a scalar nor a sequence of 2 elements.

    Examples:
        >>> to_tuple(5)
        (-5, 5)
        >>> to_tuple(5.0)
        (-5.0, 5.0)
        >>> to_tuple((1, 10))
        (1, 10)
        >>> to_tuple(5, low=3)
        (3, 5)
        >>> to_tuple(5, bias=1)
        (-4, 6)

    Notes:
        - When 'param' is a single value and 'low' is not provided, the function creates a symmetric range around zero.
        - The function preserves the type (int or float) of the input in the output.
        - If a sequence is provided, it must contain exactly 2 elements.
    zEArgument 'param' must be either a scalar or a sequence of 2 elements.N)r   r   r
   r   r   r   r   r   	TypeErrorr   r   r   r   )r   r   r   r   r   r!   r!   r"   r   D  s    0


)NN)NN)NN)'
__future__r   abcr   r   collectionsr   Znumbersr   typingr   r   r	   r
   r   r   Znumpyr   Zserializationr   typesr   r   r   r   r   r   r#   r.   r0   r1   rT   rY   r   r   r   r   r   r   r!   r!   r!   r"   <module>   s<    /	 4  	  