Ë
    ÃÓ^j3  ã                  ó®   — d Z ddlmZ ddlmZ ddlmZ ddlmZ ddl	m
Z
 ddlmZ ddlZdd	„Zdd
„Z G d„ d«      Ze G d„ d«      «       Z G d„ d«      Zy)aæ  Module for managing and transforming label data during augmentation.

This module provides utilities for encoding, decoding, and tracking metadata for labels
during the augmentation process. It includes classes for managing label transformations,
preserving data types, and ensuring consistent handling of categorical, numerical, and
mixed label types. The module supports automatic encoding of string labels to numerical
values and restoration of original data types after processing.
é    )Úannotations)Údefaultdict)ÚSequence)Ú	dataclass)ÚReal)ÚAnyNc                óD   — t        | t        «      rd| fS dt        | «      fS )a^  Sort items by type then value for consistent label ordering.

    This function is used to sort labels in a consistent order, prioritizing numerical
    values before string values. All numerical values are given priority 0, while
    string values are given priority 1, ensuring numerical values are sorted first.

    Args:
        item (Any): Item to be sorted, can be either a numeric value or any other type.

    Returns:
        tuple[int, Real | str]: A tuple with sort priority (0 for numbers, 1 for others)
            and the value itself (or string representation for non-numeric values).

    r   é   )Ú
isinstancer   Ústr)Úitems    úl/var/www/ramen.bs-engineer-server.com/venv/lib/python3.12/site-packages/albumentations/core/label_manager.pyÚcustom_sortr      s$   € ô # 4¬Ô.ˆAˆtˆ9ÐB°Q¼¸D»	°NÐBó    c                óf   — g }g }| D ]%  }t        |t        «      r|n|j                  |«       Œ' ||fS ©N)r   r   Úappend)ÚlabelsÚnumeric_labelsÚstring_labelsÚlabels       r   Ú_categorize_labelsr   '   sA   € Ø!#€NØ!€Màò UˆÜ% e¬TÔ2‰¸×MÑMÈeÕTðUà˜=Ð(Ð(r   c                  ó@   — e Zd ZdZd	d„Zd
d„Zdd„Zdd„Zdd„Zd
d„Z	y)ÚLabelEncodera  Encodes labels into integer indices.

    This class handles the conversion between original label values and their
    numerical representations. It supports both numerical and categorical labels.

    Args:
        classes_ (dict[str | Real, int]): Mapping from original labels to encoded indices.
        inverse_classes_ (dict[int, str | Real]): Mapping from encoded indices to original labels.
        num_classes (int): Number of unique classes.
        is_numerical (bool): Whether the original labels are numerical.

    c                ó<   — i | _         i | _        d| _        d| _        y )Nr   T)Úclasses_Úinverse_classes_Únum_classesÚis_numerical©Úselfs    r   Ú__init__zLabelEncoder.__init__>   s!   € Ø/1ˆŒØ79ˆÔØ !ˆÔØ"&ˆÕr   c                óÄ  — t        |t        j                  «      r|j                  «       j	                  «       }|s	d| _        | S t        d„ |D «       «      | _        | j
                  r| S t        t        |«      t        ¬«      }|D ]X  }|| j                  vsŒ| j                  | j                  |<   || j                  | j                  <   | xj                  dz  c_        ŒZ | S )zÓFit the encoder to the input labels.

        Args:
            y (Sequence[Any] | np.ndarray): Input labels to fit the encoder.

        Returns:
            LabelEncoder: The fitted encoder instance.

        Fc              3  ó<   K  — | ]  }t        |t        «      –— Œ y ­wr   )r   r   ©Ú.0r   s     r   ú	<genexpr>z#LabelEncoder.fit.<locals>.<genexpr>V   s   è ø€ ÒG¸E¤
¨5´$× 7ÑGùs   ‚©Úkeyr
   )r   ÚnpÚndarrayÚflattenÚtolistr   ÚallÚsortedÚsetr   r   r   r   )r!   ÚyÚunique_labelsr   s       r   ÚfitzLabelEncoder.fitD   sÆ   € ô �aœŸ™Ô$Ø—	‘	“×"Ñ"Ó$ˆAñ Ø %ˆDÔØˆKäÑGÀQÔGÓGˆÔà×ÒØˆKäœs 1›v¬;Ô7ˆØ"ò 	&ˆEØ˜DŸM™MÒ)Ø'+×'7Ñ'7�—‘˜eÑ$Ø:?�×%Ñ% d×&6Ñ&6Ñ7Ø× Ò  AÑ%Ö ð		&ð
 ˆr   c                ó  — t        |t        j                  «      r|j                  «       j	                  «       }| j
                  rt        j                  |«      S t        j                  |D �cg c]  }| j                  |   ‘Œ c}«      S c c}w )zÏTransform labels to encoded integer indices.

        Args:
            y (Sequence[Any] | np.ndarray): Input labels to transform.

        Returns:
            np.ndarray: Encoded integer indices.

        )r   r*   r+   r,   r-   r   Úarrayr   ©r!   r1   r   s      r   Ú	transformzLabelEncoder.transformc   sc   € ô �aœŸ™Ô$Ø—	‘	“×"Ñ"Ó$ˆAà×ÒÜ—8‘8˜A“;Ðä�x‰x¸1Ö=°%˜Ÿ™ uÓ-Ò=Ó>Ð>ùÒ=ó   Á-B
c                óF   — | j                  |«       | j                  |«      S )zæFit the encoder and transform the input labels in one step.

        Args:
            y (Sequence[Any] | np.ndarray): Input labels to fit and transform.

        Returns:
            np.ndarray: Encoded integer indices.

        )r3   r7   )r!   r1   s     r   Úfit_transformzLabelEncoder.fit_transformu   s   € ð 	�‰�ŒØ�~‰~˜aÓ Ð r   c                ó  — t        |t        j                  «      r|j                  «       j	                  «       }| j
                  rt        j                  |«      S t        j                  |D �cg c]  }| j                  |   ‘Œ c}«      S c c}w )zËTransform encoded indices back to original labels.

        Args:
            y (Sequence[Any] | np.ndarray): Encoded integer indices.

        Returns:
            np.ndarray: Original labels.

        )r   r*   r+   r,   r-   r   r5   r   r6   s      r   Úinverse_transformzLabelEncoder.inverse_transform‚   se   € ô �aœŸ™Ô$Ø—	‘	“×"Ñ"Ó$ˆAà×ÒÜ—8‘8˜A“;Ðä�x‰xÀ1ÖE¸%˜×.Ñ.¨uÓ5ÒEÓFÐFùÒEr8   c                óF  — | j                   r| S t        |t        j                  «      r|j	                  «       j                  «       }n3t        |t        «      rt        |t        «      st        |«      }n|€| S |g}t        | j                  j                  «       «      }t        |«      |z
  }|s| S t        |«      \  }}t        |«      t        |t        ¬«      z   }|D ]A  }| j                  }	|	| j                  |<   || j                  |	<   | xj                  dz  c_        ŒC | S )aÜ  Update the encoder with new labels encountered after initial fitting.

        This method identifies labels in the input sequence that are not already
        known to the encoder and adds them to the internal mapping. It does not
        change the encoding of previously seen labels.

        Args:
            y (Sequence[Any] | np.ndarray): A sequence or array of potentially new labels.

        Returns:
            LabelEncoder: The updated encoder instance.

        r(   r
   )r   r   r*   r+   r,   r-   r   r   Úlistr0   r   Úkeysr   r/   r   r   )
r!   r1   Úinput_labelsÚcurrent_labels_setÚnew_unique_labelsr   r   Úsorted_new_labelsr   Únew_ids
             r   ÚupdatezLabelEncoder.update”   s  € ð ×ÒàˆKô �aœŸ™Ô$ØŸ9™9›;×-Ñ-Ó/‰LÜ˜œ8Ô$¬Z¸¼3Ô-?Ü ›7‰LØˆYàˆKð ˜3ˆLô ! §¡×!3Ñ!3Ó!5Ó6ÐÜ Ó-Ð0BÑBÐá àˆKô );Ð;LÓ(MÑ%ˆ˜Ü" >Ó2´V¸MÌsÔ5SÑSÐà&ò 	"ˆEØ×%Ñ%ˆFØ#)ˆD�M‰M˜%Ñ Ø,1ˆD×!Ñ! &Ñ)Ø×Ò Ñ!Öð		"ð ˆr   N©ÚreturnÚNone)r1   úSequence[Any] | np.ndarrayrG   r   )r1   rI   rG   ú
np.ndarray)
Ú__name__Ú
__module__Ú__qualname__Ú__doc__r"   r3   r7   r:   r<   rE   © r   r   r   r   0   s&   „ ñó'óó>?ó$!óGô$0r   r   c                  óB   — e Zd ZU dZded<   ded<   dZded<   dZd	ed
<   y)ÚLabelMetadataz$Stores metadata about a label field.ÚtypeÚ
input_typeÚboolr   Nznp.dtype | NoneÚdtypeúLabelEncoder | NoneÚencoder)rK   rL   rM   rN   Ú__annotations__rU   rW   rO   r   r   rQ   rQ   Ç   s&   … á.àÓØÓØ!€Eˆ?Ó!Ø#'€GÐ Ô'r   rQ   c                  óX   — e Zd Z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y)ÚLabelManagera¦  Manages label encoding and decoding across multiple data fields.

    This class handles the encoding, decoding, and type management for label fields.
    It maintains metadata about each field to ensure proper conversion between
    original and encoded representations.

    Args:
        metadata (dict[str, dict[str, LabelMetadata]]): Dictionary mapping data types
            and label fields to their metadata.

    c                ó,   — t        t        «      | _        y r   )r   ÚdictÚmetadatar    s    r   r"   zLabelManager.__init__Þ   s   € Ü=HÌÓ=Nˆ�r   c                ó6  — || j                   v rW|| j                   |   v rF| j                   |   |   }|j                  sK|j                  r?|j                  j                  |«       n#| j	                  |«      }|| j                   |   |<   | j                  ||«      S )a   Process a label field, store metadata, and encode.

        If the field has been processed before (metadata exists), this will update
        the existing LabelEncoder with any new labels found in `field_data` before encoding.
        Otherwise, it analyzes the input, creates metadata, and fits the encoder.

        Args:
            data_name (str): The name of the main data type (e.g., 'bboxes', 'keypoints').
            label_field (str): The specific label field being processed (e.g., 'class_labels').
            field_data (Any): The actual label data for this field.

        Returns:
            np.ndarray: The encoded label data as a numpy array.

        )r]   r   rW   rE   Ú_analyze_inputÚ_encode_data)r!   Ú	data_nameÚlabel_fieldÚ
field_datar]   s        r   Úprocess_fieldzLabelManager.process_fieldá   s’   € ð  ˜Ÿ™Ñ%¨+¸¿¹ÀyÑ9QÑ*Qà—}‘} YÑ/°Ñ<ˆHØ×(Ò(¨X×-=Ò-=Ø× Ñ ×'Ñ'¨
Õ3ð ×*Ñ*¨:Ó6ˆHØ4<ˆD�M‰M˜)Ñ$ [Ñ1ð × Ñ  ¨XÓ6Ð6r   c                ón   — | j                   |   |   }| j                  ||«      }| j                  ||«      S )z-Restore a label field to its original format.)r]   Ú_decode_dataÚ_restore_type)r!   ra   rb   Úencoded_datar]   Údecoded_datas         r   Úrestore_fieldzLabelManager.restore_fieldþ   s:   € à—=‘= Ñ+¨KÑ8ˆØ×(Ñ(¨°xÓ@ˆØ×!Ñ! ,°Ó9Ð9r   c                óú  — t        |«      }t        |t        j                  «      r|j                  nd}t        |t        j                  «      r>|j
                  dkD  r/t        j                  |j                  t        j                  «      }nPt        |t        «      r%t        |t        «      s|rt        d„ |D «       «      }nt        |t        t        f«      rd}nd}t        |||¬«      }|st        «       |_        |S )z'Analyze input data and create metadata.Nr   c              3  óH   K  — | ]  }t        |t        t        f«      –— Œ y ­wr   )r   ÚintÚfloatr%   s     r   r'   z.LabelManager._analyze_input.<locals>.<genexpr>  s   è ø€ ÒWÀ5œz¨%´#´u°×>ÑWùs   ‚ "TF)rS   r   rU   )rR   r   r*   r+   rU   ÚsizeÚ
issubdtypeÚnumberr   r   r.   rm   rn   rQ   r   rW   )r!   rc   rS   rU   r   r]   s         r   r_   zLabelManager._analyze_input  sÂ   € ä˜*Ó%ˆ
Ü$.¨z¼2¿:¹:Ô$F�
× Ò ÈDˆô �j¤"§*¡*Ô-°*·/±/ÀAÒ2EÜŸ=™=¨×)9Ñ)9¼2¿9¹9ÓE‰LÜ˜
¤HÔ-´jÀÌSÔ6QÑV`ÜÑWÈJÔWÓW‰LÜ˜
¤S¬% LÔ1Ø‰Lð !ˆLä Ø!Ø%Øô
ˆñ Ü+›~ˆHÔàˆr   c                óš  — |j                   r~t        |t        j                  «      r/|j	                  dd«      j                  t        j                  «      S t        j                  |t        j                  ¬«      j	                  dd«      S |j                  €t        d«      ‚|j                  j                  |«      j	                  dd«      S )z!Encode field data for processing.éÿÿÿÿr
   )rU   z.Encoder not initialized for non-numerical data)r   r   r*   r+   ÚreshapeÚastypeÚfloat32r5   rW   Ú
ValueErrorr:   )r!   rc   r]   s      r   r`   zLabelManager._encode_data  s›   € à× Ò ä˜*¤b§j¡jÔ1Ø!×)Ñ)¨"¨aÓ0×7Ñ7¼¿
¹
ÓCÐCÜ—8‘8˜J¬b¯j©jÔ9×AÑAÀ"ÀaÓHÐHð ×ÑÐ#ÜÐMÓNÐNØ×Ñ×-Ñ-¨jÓ9×AÑAÀ"ÀaÓHÐHr   c                ó4  — |j                   r7|j                  �|j                  |j                  «      S |j                  «       S |j                  €t        d«      ‚|j                  j                  |j                  t        «      «      }|j                  d«      S )zDecode processed data.z(Encoder not found for non-numerical datars   )	r   rU   ru   r,   rW   rw   r<   rm   rt   )r!   rh   r]   Údecodeds       r   rf   zLabelManager._decode_data,  s�   € à× Ò Ø�~‰~Ð)Ø#×*Ñ*¨8¯>©>Ó:Ð:Ø×'Ñ'Ó)Ð)à×ÑÐ#ÜÐGÓHÐHà×"Ñ"×4Ñ4°\×5HÑ5HÌÓ5MÓNˆØ�‰˜rÓ"Ð"r   c                ó„  — t        |j                  t        «      r0t        |j                  t        t
        f«      r|j                  «       S t        |j                  t        «      rMt        |j                  t        j                  «      r)|j                  �|j                  |j                  «      S |S |j                  «       S )z"Restore data to its original type.)r   rS   rR   Ú
issubclassr>   r   r-   r*   r+   rU   ru   )r!   ri   r]   s      r   rg   zLabelManager._restore_type9  s—   € ô �h×)Ñ)¬4Ô0´ZÀ×@SÑ@SÔVZÔ\dÐUeÔ5fØ×&Ñ&Ó(Ð(ô �h×)Ñ)¬4Ô0´ZÀ×@SÑ@SÔUW×U_ÑU_Ô5`Ø�~‰~Ð)Ø#×*Ñ*¨8¯>©>Ó:Ð:ØÐð ×"Ñ"Ó$Ð$r   c                ó   — g S )zHandle empty data case.rO   r    s    r   Úhandle_empty_datazLabelManager.handle_empty_dataH  s   € àˆ	r   c                óž   — || j                   v r?|| j                   |   v r.| j                   |   |   j                  }t        |t        «      r|S y)zFRetrieves the fitted LabelEncoder for a specific data and label field.N)r]   rW   r   r   )r!   ra   rb   rW   s       r   Úget_encoderzLabelManager.get_encoderL  sI   € à˜Ÿ™Ñ%¨+¸¿¹ÀyÑ9QÑ*QØ—m‘m IÑ.¨{Ñ;×CÑCˆGä˜'¤<Ô0Ø�Ør   NrF   )ra   r   rb   r   rc   r   rG   rJ   )ra   r   rb   r   rh   rJ   rG   r   )rc   r   rG   rQ   )rc   r   r]   rQ   rG   rJ   )rh   rJ   r]   rQ   rG   rJ   )ri   rJ   r]   rQ   rG   r   )rG   z	list[Any])ra   r   rb   r   rG   rV   )rK   rL   rM   rN   r"   rd   rj   r_   r`   rf   rg   r}   r   rO   r   r   rZ   rZ   Ñ   s6   „ ñ
óOó7ó::óó6Ió#ó%óôr   rZ   )r   r   rG   ztuple[int, Real | str])r   zset[Any]rG   ztuple[list[Real], list[str]])rN   Ú
__future__r   Úcollectionsr   Úcollections.abcr   Údataclassesr   Únumbersr   Útypingr   Únumpyr*   r   r   r   rQ   rZ   rO   r   r   ú<module>r‡      s^   ðñõ #å #Ý $Ý !Ý Ý ã óCó$)÷Tñ Tðn ÷(ð (ó ð(÷Bò Br   