
    h                       S r SSKJr  SSKrSSKrSSKJr  SSKJrJ	r	  SSK
JrJrJr  SSKrSSKrSSKJrJr  SS	KJr  SS
KJrJr  SSKJrJrJrJr  SSKJr  SSK J!r!J"r"J#r#  / SQr$Sr%Sr&\\S4   r'\(\'   r)Sr*Sr+SS1r,SS1r-1 Skr.S1r/S1r0SS1r1S1r2S1r3S1r4S1r5 " S S\5      r6 " S S\6\5      r7 " S  S!\65      r8 " S" S#\65      r9 " S$ S%\95      r: " S& S'\65      r; " S( S)\65      r< " S* S+\75      r= " S, S-\65      r>g).a  Module for composing multiple transforms into augmentation pipelines.

This module provides classes for combining multiple transformations into cohesive
augmentation pipelines. It includes various composition strategies such as sequential
application, random selection, and conditional application of transforms. These
composition classes handle the coordination between different transforms, ensuring
proper data flow and maintaining consistent behavior across the augmentation pipeline.
    )annotationsN)defaultdict)IteratorSequence)AnyUnioncast   )
BboxParamsBboxProcessor)HubMixin)KeypointParamsKeypointsProcessor)SERIALIZABLE_REGISTRYSerializableget_shortest_class_fullnameinstantiate_nonserializable)BasicTransform)DataProcessorformat_args	get_shape)BaseComposer   Composer   OneOf
OneOrOtherRandomOrderReplayComposeSelectiveChannelTransform
SequentialSomeOf   r   )	imagemaskmasksbboxes	keypointsvolumevolumesmask3dmasks3d)r#   r$   r)   r*   r"   imagesr#   >   r$   r+   r*   r(   r%   r&   r'   r(   r)   r*   c                  ~   \ rS rSr% SrSrS\S'   SrS\S'   SrS	\S
'      S"           S#S jjr	S$S jr
      S%S jrS&S jrS'S jrS(S jrS)S jrS*S jrS+S jrS,S jrS-S jr\S.S j5       r\S/S j5       r\4S0S jjr\S-S j5       r\S1S j5       rS2S jrS2S jrS3S jrS4S jrS5S6S jjr S7S  jr!S!r"g)8r   K   a  Base class for composing multiple transforms together.

This class serves as a foundation for creating compositions of transforms
in the Albumentations library. It provides basic functionality for
managing a sequence of transforms and applying them to data.

Attributes:
    transforms (List[TransformType]): A list of transforms to be applied.
    p (float): Probability of applying the compose. Should be in the range [0, 1].
    replay_mode (bool): If True, the compose is in replay mode.
    _additional_targets (Dict[str, str]): Additional targets for transforms.
    _available_keys (Set[str]): Set of available keys for data.
    processors (Dict[str, Union[BboxProcessor, KeypointsProcessor]]): Processors for specific data types.

Args:
    transforms (TransformsSeqType): A sequence of transforms to compose.
    p (float): Probability of applying the compose.

Raises:
    ValueError: If an invalid additional target is specified.

Note:
    - Subclasses should implement the __call__ method to define how
      the composition is applied to data.
    - The class supports serialization and deserialization of transforms.
    - It provides methods for adding targets, setting deterministic behavior,
      and checking data validity post-transform.

Nz dict[int, BasicTransform] | None_transforms_dictz tuple[DataProcessor, ...] | Nonecheck_each_transformTboolmain_composec                :   [        U[        [        45      (       a  [        R                  " SSS9  U/nXl        X l        SU l        0 U l        [        5       U l
        0 U l        U R                  5         U R                  U5        U R                  U5        XPl        g )Nz`transforms is single transform, but a sequence is expected! Transform will be wrapped into list.r!   
stacklevelF)
isinstancer   r   warningswarn
transformspreplay_mode_additional_targetsset_available_keys
processors	_set_keysset_mask_interpolationset_random_seedsave_applied_params)selfr8   r9   mask_interpolationseedrB   kwargss          Y/var/www/fran/franai/venv/lib/python3.13/site-packages/albumentations/core/composition.py__init__BaseCompose.__init__n   s     j;"?@@MMr %J$ 35 ),IK##$67T"#6     c                    SU;   ag  [        US5      (       aU  UR                  (       aC  US   R                  UR                  R                  UR                  R                  5       45        gggg)z2Track transform parameters if tracking is enabled.applied_transformsparamsN)hasattrrM   append	__class____name__copy)rC   	transformdatas      rG   _track_transform_params#BaseCompose._track_transform_params   s_    4'GIx,H,HYM]M]%&--y/B/B/K/KYM]M]MbMbMd.ef N^,H'rJ   c                    Xl         X l        U R                   H1  n[        U[        [
        45      (       d  M   UR                  X5        M3     g)zSet random state directly from generators.

Args:
    random_generator (np.random.Generator): numpy random generator to use
    py_random (random.Random): python random generator to use

N)random_generator	py_randomr8   r5   r   r   set_random_state)rC   rX   rY   rS   s       rG   rZ   BaseCompose.set_random_state   s@     !1" I)nk%BCC**+;G )rJ   c                   Xl         [        R                  R                  U5      U l        [        R
                  " U5      U l        U R                   H1  n[        U[        [        45      (       d  M   UR                  U5        M3     g)zNSet random state from seed.

Args:
    seed (int | None): Random seed to use

N)rE   nprandomdefault_rngrX   RandomrY   r8   r5   r   r   rA   )rC   rE   rS   s      rG   rA   BaseCompose.set_random_seed   s^     	 "		 5 5d ;t,I)nk%BCC))$/ )rJ   c                F    Xl         U R                  U R                  5        g)zSet interpolation mode for mask resizing operations.

Args:
    mask_interpolation (int | None): OpenCV interpolation flag to use for mask transforms.
        If None, default interpolation for masks will be used.

N)rD   !_set_mask_interpolation_recursiver8   )rC   rD   s     rG   r@   "BaseCompose.set_mask_interpolation   s     #5..t?rJ   c                   U H  n[        U[        5      (       a5  [        US5      (       a"  U R                  b  U R                  Ul        MI  MK  MM  [        U[        5      (       d  Md  UR                  U R                  5        M     g )NrD   )r5   r   rN   rD   r   r@   rC   r8   rS   s      rG   rc   -BaseCompose._set_mask_interpolation_recursive   sk    #I)^449&:;;@W@W@c373J3JI0 Ad;I{33001H1HI $rJ   c                ,    [        U R                  5      $ N)iterr8   rC   s    rG   __iter__BaseCompose.__iter__   s    DOO$$rJ   c                ,    [        U R                  5      $ ri   )lenr8   rk   s    rG   __len__BaseCompose.__len__   s    4??##rJ   c                    [         e)a  Apply transforms.

Args:
    *args (Any): Positional arguments are not supported.
    **data (Any): Named parameters with data to transform.

Returns:
    dict[str, Any]: Transformed data.

Raises:
    NotImplementedError: This method must be implemented by subclasses.

)NotImplementedError)rC   argsrT   s      rG   __call__BaseCompose.__call__   s
     "!rJ   c                     U R                   U   $ ri   r8   )rC   items     rG   __getitem__BaseCompose.__getitem__   s    t$$rJ   c                "    U R                  5       $ ri   )indented_reprrk   s    rG   __repr__BaseCompose.__repr__   s    !!##rJ   c                    U R                   $ )ztGet additional targets dictionary.

Returns:
    dict[str, str]: Dictionary containing additional targets mapping.

)r;   rk   s    rG   additional_targetsBaseCompose.additional_targets   s     '''rJ   c                    U R                   $ )zaGet set of available keys.

Returns:
    set[str]: Set of string keys available for transforms.

)r=   rk   s    rG   available_keysBaseCompose.available_keys   s     ###rJ   c                   U R                  5       R                  5        VVs0 s H'  u  p#UR                  S5      (       a  M  US:X  a  M%  X#_M)     nnnU R                  R                  S-   nU R
                   HJ  nUS-  n[        US5      (       a  UR                  U[        -   5      O
[        U5      nUSU-  U-   S-   -  nML     USSU[        -
  -  -   S[        U5       S	3-   -  nU$ s  snnf )
zGet an indented string representation of the composition.

Args:
    indent (int): Indentation level. Default: REPR_INDENT_STEP.

Returns:
    str: Formatted string representation with proper indentation.

__r8   z([
r}    ,z], ))to_dict_privateitems
startswithrP   rQ   r8   rN   r}   REPR_INDENT_STEPreprr   )rC   indentkvrt   repr_stringtt_reprs           rG   r}   BaseCompose.indented_repr   s     "&!5!5!7!=!=!?q!?UYHZ^_co^o!?qnn--4A4KCJ1oC^C^Q__V.>%>?dhijdkF3<&0366K ! 	tcV.>%>??CTXHYGZZ[B\\\ rs   C*C*
C*c                    [        U 5      $ )z[Get the full qualified name of the class.

Returns:
    str: The shortest class fullname.

)r   clss    rG   get_class_fullnameBaseCompose.get_class_fullname  s     +3//rJ   c                    g)zmCheck if the class is serializable.

Returns:
    bool: True if the class is serializable, False otherwise.

T r   s    rG   is_serializableBaseCompose.is_serializable  s     rJ   c                    U R                  5       U R                  U R                   Vs/ s H  oR                  5       PM     snS.$ s  snf )Convert the composition to a dictionary for serialization.

Returns:
    dict[str, Any]: Dictionary representation of the composition.

)__class_fullname__r9   r8   )r   r9   r8   r   rC   r   s     rG   r   BaseCompose.to_dict_private  sD     #'"9"9";8<H1,,.H
 	
 Is   Ac                    U R                  5       [        U 5      SU R                   Vs/ s H  oR                  5       PM     snS.$ s  snf )Get a dictionary representation with object IDs for replay mode.

Returns:
    dict[str, Any]: Dictionary with composition data and object IDs.

N)r   idrM   r8   )r   r   r8   get_dict_with_idr   s     rG   r   BaseCompose.get_dict_with_id)  sG     #'"9"9";T(9=IA--/I	
 	
 Js   A
c           	        U(       a  UR                  5        HI  u  p#X R                  ;   d  M  X0R                  U   :w  d  M*  [        SU SU R                  U    SU 35      e   U R                  R                  U5        U R                   H  nUR                  U5        M     U R                  R                  5        H  nUR                  U5        M     U R                  5         g)zAdd additional targets to all transforms.

Args:
    additional_targets (dict[str, str] | None): Dict of name -> type mapping for additional targets.
        If None, no additional targets will be added.

z4Trying to overwrite existed additional targets. Key=z Exists=z New value: N)	r   r;   
ValueErrorupdater8   add_targetsr>   valuesr?   )rC   r   r   r   r   procs         rG   r   BaseCompose.add_targets7  s     *002000Q:R:RST:U5U$ c$*B*B1*E)FlSTRUW  3 $$++,>?__01 %..0  !34 1rJ   c                D   U R                   R                  U R                  R                  5       5        U R                   H`  nU R                   R                  UR
                  5        [        US5      (       d  M;  U R                   R                  UR                  5        Mb     U R                  (       a  U R                   R                  S/5        U R                  R                  5        H  nUR                  U R                   ;  a#  [        R                  " SUR                   S3SS9  U R                   R                  UR                  5        UR                  R                  (       d  M  U R                   R                  UR                  R                  5        M     gg)zSet _available_keystargets_as_paramslabelszGot processor for z!, but no transform to process it.r!   r3   N)r=   r   r;   keysr8   r   rN   r   r>   r   default_data_namer6   r7   data_fieldsrM   label_fields)rC   r   r   s      rG   r?   BaseCompose._set_keysM  s1   ##D$<$<$A$A$CDA  ''(8(89q-..$$++A,?,?@ ! ??  ''
3..0))1E1EEMM,T-C-C,DDef#$ $$++D,<,<=;;+++((//0H0HI 1 rJ   c                L    U R                    H  nUR                  X5        M     g)zSet deterministic mode for all transforms.

Args:
    flag (bool): Whether to enable deterministic mode.
    save_key (str): Key to save replay parameters. Default: "replay".

N)r8   set_deterministic)rC   flagsave_keyr   s       rG   r   BaseCompose.set_deterministic`  s      A/ !rJ   c                :   U R                   (       a  [        U5      nU R                    Hn  nUR                  5        HW  u  pEXCR                  ;   d0  X@R                  ;   d  M%  U R                  U   UR                  ;   d  MD  UR                  XR5      X'   MY     Mp     U$ )zCheck and filter data after transformation.

Args:
    data (dict[str, Any]): Dictionary containing transformed data

Returns:
    dict[str, Any]: Filtered data dictionary

)r/   r   r   r   r;   filter)rC   rT   shaper   	data_name
data_values         rG   check_data_post_transform%BaseCompose.check_data_post_transformk  s     $$dOE11-1ZZ\)I $4$44!%=%== 44Y?4CSCSS*.++j*H .: 2 rJ   )r;   r=   rD   r9   r>   rY   rX   r:   rB   rE   r8   )NNF)r8   TransformsSeqTyper9   floatrD   
int | NonerE   r   rB   r0   rF   r   )rS   TransformTyperT   dict[str, Any]returnNone)rX   znp.random.GeneratorrY   zrandom.Randomr   r   )rE   r   r   r   )rD   r   r   r   r8   r   r   r   )r   zIterator[TransformType])r   int)rt   r   rT   r   r   r   )ry   r   r   r   )r   str)r   zdict[str, str])r   zset[str])r   r   r   r   r   r0   r   r   )r   dict[str, str] | Noner   r   r   r   )replay)r   r0   r   r   r   r   rT   r   r   r   )#rQ   
__module____qualname____firstlineno____doc__r.   __annotations__r/   r1   rH   rU   rZ   rA   r@   rc   rl   rp   ru   rz   r~   propertyr   r   r   r}   classmethodr   r   r   r   r   r?   r   r   __static_attributes__r   rJ   rG   r   r   K   sC   < :>6==A:AL$ *.$)7%7 7 '	7
 7 "7 78g
H-H !H 
	H(0	@J%$" %$ ( ( $ $ +; & 0 0  

,J&	0rJ   c                  8  ^  \ rS rSrSr         S&                   S'U 4S jjjr\S(S j5       r\R                  S)S j5       rS*S jr	S+S jr
S+S	 jrS*S
 jrSS.S,S jjrS-S jrS.S jrS/S jrS.S jrS.S jrS.S jrS.S jrS0S jrS1U 4S jjrS1U 4S jjr\S2S j5       r\S3S j5       r\S2S j5       r\S4S j5       r\S5S j5       rS6S jrS7S jrS8S jr S7S jr!S9S  jr"\S:S! j5       r#\S:S" j5       r$\S:S# j5       r%\S:S$ j5       r&S%r'U =r($ );r   i  a  Compose multiple transforms together and apply them sequentially to input data.

This class allows you to chain multiple image augmentation transforms and apply them
in a specified order. It also handles bounding box and keypoint transformations if
the appropriate parameters are provided.

Args:
    transforms (list[BasicTransform | BaseCompose]): A list of transforms to apply.
    bbox_params (dict[str, Any] | BboxParams | None): Parameters for bounding box transforms.
        Can be a dict of params or a BboxParams object. Default is None.
    keypoint_params (dict[str, Any] | KeypointParams | None): Parameters for keypoint transforms.
        Can be a dict of params or a KeypointParams object. Default is None.
    additional_targets (dict[str, str] | None): A dictionary mapping additional target names
        to their types. For example, {'image2': 'image'}. Default is None.
    p (float): Probability of applying all transforms. Should be in range [0, 1]. Default is 1.0.
    is_check_shapes (bool): If True, checks consistency of shapes for image/mask/masks on each call.
        Disable only if you are sure about your data consistency. Default is True.
    strict (bool): If True, enables strict mode which:
        1. Validates that all input keys are known/expected
        2. Validates that no transforms have invalid arguments
        3. Raises ValueError if any validation fails
        If False, these validations are skipped. Default is False.
    mask_interpolation (int | None): Interpolation method for mask transforms. When defined,
        it overrides the interpolation method specified in individual transforms. Default is None.
    seed (int | None): Controls reproducibility of random augmentations. Compose uses
        its own internal random state, completely independent from global random seeds.

        When seed is set (int):
        - Creates a fixed internal random state
        - Two Compose instances with the same seed and transforms will produce identical
          sequences of augmentations
        - Each call to the same Compose instance still produces random augmentations,
          but these sequences are reproducible between different Compose instances
        - Example: transform1 = A.Compose([...], seed=137) and
                  transform2 = A.Compose([...], seed=137) will produce identical sequences

        When seed is None (default):
        - Generates a new internal random state on each Compose creation
        - Different Compose instances will produce different sequences of augmentations
        - Example: transform = A.Compose([...])  # random results

        Important: Setting random seeds outside of Compose (like np.random.seed() or
        random.seed()) has no effect on augmentations as Compose uses its own internal
        random state.
    save_applied_params (bool): If True, saves the applied parameters of each transform. Default is False.
        You will need to use the `applied_transforms` key in the output dictionary to access the parameters.

Example:
    >>> import albumentations as A
    >>> transform = A.Compose([
    ...     A.RandomCrop(width=256, height=256),
    ...     A.HorizontalFlip(p=0.5),
    ...     A.RandomBrightnessContrast(p=0.2),
    ... ], seed=137)
    >>> transformed = transform(image=image)

Note:
    - The class checks the validity of input data and shapes if is_check_args and is_check_shapes are True.
    - When bbox_params or keypoint_params are provided, it sets up the corresponding processors.
    - The transform can handle additional targets specified in the additional_targets dictionary.
    - When strict mode is enabled, it performs additional validation to ensure data and transform
      configuration correctness.

Fc                  > [         TU ]  UUUU	U
S9  U(       a^  [        U[        5      (       a  [	        S	0 UD6nO%[        U[        5      (       a  UnOSn[        U5      e[        U5      U R                  S'   U(       a^  [        U[        5      (       a  [        S	0 UD6nO%[        U[        5      (       a  UnOSn[        U5      e[        U5      U R                  S'   U R                  R                  5        H  nUR                  U R                  5        M      U R                  U5        U R                  (       d  U R                  R                  [         5        SU l        Xpl        X`l        [)        S U R                  R                  5        5       5      U l        U R-                  U R                  5        U R/                  U R                  5        Xl        SU l        SU l        g )
N)r8   r9   rD   rE   rB   z@unknown format of bbox_params, please use `dict` or `BboxParams`r%   zHunknown format of keypoint_params, please use `dict` or `KeypointParams`r&   Tc              3  b   #    U  H%  n[        UR                  S S5      (       d  M!  Uv   M'     g7f)r/   FN)getattrrM   ).0r   s     rG   	<genexpr>#Compose.__init__.<locals>.<genexpr>  s'      *
5TNdfk9lDD5s    /	/Fr   )superrH   r5   dictr   r   r   r>   r   r   r   ensure_transforms_validr8   r   r=   r   AVAILABLE_KEYSis_check_argsstrictis_check_shapestupler/   _set_check_args_for_transforms_set_processors_for_transformsrB   _images_was_list_masks_was_list)rC   r8   bbox_paramskeypoint_paramsr   r9   r   r   rD   rE   rB   b_paramsmsgk_paramsr   rP   s                  rG   rH   Compose.__init__  s    	!1 3 	 	
 +t,,%44K44&X o%(5h(?DOOH%/400)<O<O^<<*` o%+=h+GDOOK(OO**,D((9 - 	+,  ''7!.$) *
!__335*
 %
! 	++DOO<++DOO<#6  %$rJ   c                    U R                   $ )zkGet the current strict mode setting.

Returns:
    bool: True if strict mode is enabled, False otherwise.

)_strictrk   s    rG   r   Compose.strict  s     ||rJ   c                >    U(       a  U R                  5         Xl        g ri   )_validate_strictr   )rC   values     rG   r   r     s     !!#rJ   c                L   ^ SU4S jjmU R                    H  nT" U5        M     g)zOValidate that no transforms have invalid arguments when strict mode is enabled.c                ,  > [        U S5      (       aQ  U R                  (       a@  SSR                  U R                  5       SU R                  R                   3n[        U5      e[        U [        5      (       a  U R                   H  nT" U5        M     g g )Ninvalid_argszArgument(s) 'z, z' are not valid for transform )	rN   r   joinrP   rQ   r   r5   r   r8   )rS   messager   check_transforms      rG   r  1Compose._validate_strict.<locals>.check_transform  s    y.11i6L6L#DIIi.D.D$E#F G33<3F3F3O3O2PR  !)))[11"--A#A& . 2rJ   N)rS   r   r   r   rx   )rC   rS   r  s     @rG   r   Compose._validate_strict  s     		' II& )rJ   c                   U Hz  n[        U[        5      (       a0  [        US5      (       a  UR                  U R                  5        MF  MH  [        U[
        5      (       d  M_  U R                  UR                  5        M|     g )Nset_processors)r5   r   rN   r  r>   r   r   r8   rf   s      rG   r   &Compose._set_processors_for_transforms&  s_    #I)^449&677,,T__= 8I{3333I4H4HI $rJ   c                   U H|  n[        U[        5      (       a=  U R                  UR                  5        U R                  Ul        U R
                  Ul        [        U[        5      (       d  Ml  UR                  5         M~     g ri   )r5   r   r   r8   r/   r>   r   disable_check_args_privaterf   s      rG   r   &Compose._set_check_args_for_transforms.  s`    #I)[1133I4H4HI151J1J	.'+	$)W--446 $rJ   c                .    SU l         SU l        SU l        g)zDisable argument checking for transforms.

This method disables strict mode and argument checking for all transforms in the composition.
FN)r   r   r1   rk   s    rG   r	  "Compose.disable_check_args_private7  s    
 #!rJ   force_applyc                  U(       a  Sn[        U5      e[        U[        [        45      (       d  Sn[	        U5      eU R
                  (       a  U R                  (       a  / US'   U=(       d'    U R                  R                  5       U R                  :  nU(       d  U$ U R                  U5        U R                   H-  nU" S0 UD6nU R                  Xc5        U R                  U5      nM/     U R                  U5      $ )ak  Apply transformations to data.

Args:
    *args (Any): Positional arguments are not supported.
    force_apply (bool): Whether to apply transforms regardless of probability. Default: False.
    **data (Any): Dict with data to transform.

Returns:
    dict[str, Any]: Dictionary with transformed data.

Raises:
    KeyError: If positional arguments are provided.

zXYou have to pass data to augmentations as named arguments, for example: aug(image=image)z&force_apply must have bool or int typerL   r   )KeyErrorr5   r0   r   	TypeErrorrB   r1   rY   r^   r9   
preprocessr8   rU   r   postprocess)rC   r  rt   rT   r   need_to_runr   s          rG   ru   Compose.__call__@  s     lC3-+c{33:CC.  ##(9(9)+D%&!ET^^%:%:%<tvv%EKA9t9D((111$7D !
 %%rJ   c                v   U R                   (       a  / n/ nUR                  5        H  u  pEU R                  R                  XD5      nUc  M%  U R	                  XFU5      nUc  M<  U[
        [        -  ;   a*  UR                  USS 5        UR                  USS 5        Mw  US;   a*  UR                  USS 5        UR                  USS 5        M  UR                  USS 5        M     U R                  X#5        U R                  (       a  U R                  U5        U R                  U5        U R                  U5        g)z1Preprocess input data before applying transforms.Nr
      >   r*   r(   r!      )r   r   r;   get_get_data_shapeCHECKED_VOLUMECHECKED_MASK3DrO   _check_shape_consistencyr   _validate_data_preprocess_processors_preprocess_arrays)rC   rT   shapesvolume_shapesr   r   internal_namer   s           rG   r  Compose.preprocessh  s    FM)-%	 $ 8 8 < <Y R %,,YzR$$(GGeAaj1%,,U2AY7&*@@eAaj1%,,U1QZ8eBQi0! *6$ ))&@ ;;%##D)%rJ   c                    U R                   (       d  gU H(  nU R                  U5      (       a  M  [        SU S35      e   U R                  (       a  U R                  " S0 UD6  gg)z'Validate input data keys and arguments.NzKey z is not in available keys.r   )r   _is_valid_keyr   r   _check_args)rC   rT   r   s      rG   r  Compose._validate_data  s]    {{I%%i00 4	{2L!MNN  $t$ rJ   c                v    XR                   ;   =(       d%    U[        ;   =(       d    U[        ;   =(       d    US:H  $ )z)Check if the key is valid for processing.rL   )r=   	MASK_KEYS
IMAGE_KEYS)rC   keys     rG   r&  Compose._is_valid_key  s1    ***rcY.>r#BSrWZ^rWrrrJ   c                    U R                   (       d  gU R                  R                  5        H  nUR                  U5        M     U R                  R                  5        H  nUR	                  U5        M     g)z.Run preprocessors if this is the main compose.N)r1   r>   r   ensure_data_validr  )rC   rT   	processors      rG   r  Compose._preprocess_processors  sX      //1I''- 2//1I  & 2rJ   c                H    U R                  U5        U R                  U5        g)zJConvert lists to numpy arrays for images and masks, and ensure contiguity.N)_preprocess_images_preprocess_masksrC   rT   s     rG   r   Compose._preprocess_arrays  s    %t$rJ   c                    SU;  a  g[        US   [        [        45      (       a/  SU l        US   (       d  g[        R
                  " US   5      US'   gSU l        g)z$Convert image lists to numpy arrays.r+   NTF)r5   listr   r   r]   stackr5  s     rG   r3  Compose._preprocess_images  sR    4d8ntUm44$(D!>XXd8n5DN$)D!rJ   c                    SU;  a  g[        US   [        [        45      (       a/  SU l        US   (       d  g[        R
                  " US   5      US'   gSU l        g)z#Convert mask lists to numpy arrays.r$   NTF)r5   r8  r   r   r]   r9  r5  s     rG   r4  Compose._preprocess_masks  sR    $d7mdE]33#'D =HHT']3DM#(D rJ   c                ,   U R                   (       a  U R                  R                  5        H  nUR                  U5        M     SU;   a"  U R                  (       a  [        US   5      US'   SU;   a"  U R                  (       a  [        US   5      US'   U$ )zApply post-processing to data after all transforms have been applied.

Args:
    data (dict[str, Any]): Data after transformation.

Returns:
    dict[str, Any]: Post-processed data.

r+   r$   )r1   r>   r   r  r   r8  r   )rC   rT   r9   s      rG   r  Compose.postprocess  sz     __++-d# . 4D$9$9!%d8n!5X$4#7#7 $T'] 3WrJ   c                h  > [         TU ]  5       nU R                  R                  S5      nU R                  R                  S5      nUR	                  U(       a  UR
                  R                  5       OSU(       a  UR
                  R                  5       OSU R                  U R                  S.5        U$ )r   r%   r&   N)r   r   r   r   )r   r   r>   r  r   rM   r   r   rC   
dictionarybbox_processorkeypoints_processorrP   s       rG   r   Compose.to_dict_private  s     W,.
,,X6"oo11+>JX~44DDF^bTg$7$>$>$N$N$Pmq&*&=&=#'#7#7		
 rJ   c                j  > [         TU ]  5       nU R                  R                  S5      nU R                  R                  S5      nUR	                  U(       a  UR
                  R                  5       OSU(       a  UR
                  R                  5       OSU R                  SU R                  S.5        U$ )r   r%   r&   N)r   r   r   rM   r   )	r   r   r>   r  r   rM   r   r   r   r@  s       rG   r   Compose.get_dict_with_id  s     W-/
,,X6"oo11+>JX~44DDF^bTg$7$>$>$N$N$Pmq&*&=&=#'#7#7	
 rJ   c                z    [        U[        R                  5      (       d  [        U  S35      eUR                  S S $ )N must be numpy array typer!   r5   r]   ndarrayr  r   r   rT   s     rG   _check_single_dataCompose._check_single_data  s6    $

++yk)BCDDzz"1~rJ   c                   [        U[        R                  5      (       a-  UR                  S;  a  [	        U  S35      eUR
                  SS $ [        U[        [        45      (       af  U(       d  g[        S U 5       5      (       d  [	        SU  S35      e[        S	 U 5       5      (       a  [	        S
U  S35      eUS   R
                  SS $ [	        U  S35      e)a  Check masks data format and return shape.

Args:
    data_name (str): Name of the data field being checked
    data (Any): Input data in one of these formats:
        - List of numpy arrays, each of shape (H, W) or (H, W, C)
        - Numpy array of shape (N, H, W) or (N, H, W, C)
        - Empty list for cases where no masks are present

Returns:
    tuple[int, int] | None: (height, width) of the first mask, or None if masks list is empty
Raises:
    TypeError: If data format is invalid

)r  r    as numpy array must be 3D or 4Dr
   r  Nc              3  V   #    U  H  n[        U[        R                  5      v   M!     g 7fri   )r5   r]   rJ  r   ms     rG   r   ,Compose._check_masks_data.<locals>.<genexpr>%  s     ?$Qz!RZZ00$s   ')zAll elements in z must be numpy arraysc              3  >   #    U  H  oR                   S ;  v   M     g7f)>   r!   r  N)ndimrQ  s     rG   r   rS  '  s     6A66's   zAll masks in z must be 2D or 3D numpy arraysr   r!   z; must be either a numpy array or a sequence of numpy arrays)
r5   r]   rJ  rU  r  r   r8  r   allanyrK  s     rG   _check_masks_dataCompose._check_masks_data  s    " dBJJ''yy&9+-M NOO::a?"dT5M**?$???"29+=R STT6666-	{:X YZZ7==!$$9+%`abbrJ   c                H   [        U[        R                  5      (       a-  UR                  S;  a  [	        U  S35      eUR
                  SS $ [        U[        5      (       a"  [        US   [        R                  5      (       d  [	        U  S35      eUS   R
                  SS $ )	av  Check multi-image data format and return shape.

Args:
    data_name (str): Name of the data field being checked
    data (Any): Input data in one of these formats:
        - List-like of numpy arrays
        - Numpy array of shape (N, H, W, C) or (N, H, W)

Returns:
    tuple[int, int]: (height, width) of the first image
Raises:
    TypeError: If data format is invalid

   r  r  rO  r
   r  r   z7 must be either a numpy array or a list of numpy arraysNr!   )r5   r]   rJ  rU  r  r   r   rK  s     rG   _check_multi_dataCompose._check_multi_data-  s      dBJJ''yy&9+-M NOO::a?"$))DGRZZ1P1Pyk)`abbAw}}Ra  rJ   c                    U [         ;   a  UR                  S5      c  [        S5      eU [        ;   a  UR                  S5      c  [        S5      eg g )Nr%   z6bbox_params must be specified for bbox transformationsr&   z?keypoints_params must be specified for keypoint transformations)CHECK_BBOX_PARAMr  r   CHECK_KEYPOINTS_PARAM)internal_data_namer>   s     rG   _check_bbox_keypoint_params#Compose._check_bbox_keypoint_paramsF  sQ    !11jnnX6N6VUVV!66:>>+;V;^^__ <_6rJ   c                |    U(       a5  U (       a-  U R                  U S   5      [        U 5      :w  a  [        S5      eg g g )Nr   zHeight and Width of image, mask or masks should be equal. You can disable shapes check by setting a parameter is_check_shapes=False of Compose class (do it only if you are sure about your data consistency).)countro   r   )r!  r   s     rG   _check_shapesCompose._check_shapesM  s;    v&,,vay*AS[*P0  +Qv?rJ   c                   / n/ nUR                  5        GHW  u  pEU R                  R                  XD5      nU[        ;   aM  [	        U[
        R                  5      (       d  [        U S35      eUR                  UR                  S S 5        Mx  Uc  M}  [	        U[
        R                  [        45      (       d  M  U R                  X`R                  5        U R                  XFU5      nUc  M  U[        [        -  ;   a+  UR                  USS 5        UR                  US S 5        GM  US;   a+  UR                  USS 5        UR                  USS 5        GMC  UR                  US S 5        GMZ     U R!                  X#5        g )NrH  r!   r
   r  >   r*   r(   r  )r   r;   r  CHECKED_SINGLEr5   r]   rJ  r  rO   r   r8  rb  r>   r  r  r  r  )rC   rF   r!  r"  r   rT   r#  r   s           rG   r'  Compose._check_argsV  sQ   %||~OI 4488NM .!$

33#yk1J$KLLdjj!n- |dRZZ$677,,]OOL((4HE}  ??eAaj)$$U2AY/"88eAaj)$$U1QZ0eBQi(=  .@ 	%%f<rJ   c                    U[         ;   a  U R                  X5      $ U[        ;   a  U R                  X5      $ U[        ;   a  U R                  X5      $ U[        ;   a  U R                  XU5      $ g)z$Get shape of data based on its type.N)ri  _get_single_data_shaper  _check_volume_datar  _check_mask3d_dataCHECKED_MULTI_get_multi_data_shape)rC   r   r#  rT   s       rG   r  Compose._get_data_shape|  ss     N*..y?? N***9;; N***9;; M)--iMMrJ   c                t    [        U[        R                  5      (       d  [        U S35      eUR                  $ )z"Get shape of single image or mask.rH  rI  )rC   r   rT   s      rG   rl  Compose._get_single_data_shape  s0    $

++yk)BCDDzzrJ   c                   US:X  a  U R                  X5      nUc  S$ U$ US;   aW  [        U[        R                  5      (       d  [	        U S35      eUR
                  S;  a  [	        U S35      eUR                  $ U R                  X5      $ )z6Get shape of multi-item data (masks, images, volumes).r$   N>   r*   r(   rH     r      must be 4D or 5D array)rX  r5   r]   rJ  r  rU  r   r\  )rC   r   r#  rT   r   s        rG   rp  Compose._get_multi_data_shape  s    G#**9;E =43e322dBJJ//9+-F GHHyy&9+-D EFF::%%i66rJ   c                    U R                  XR                  5        U R                  (       a5  U(       a-  UR                  US   5      [        U5      :w  a  [	        S5      eggg)zCheck consistency of shapes.r   zDepth, Height and Width of volume, mask3d, volumes and masks3d should be equal. You can disable shapes check by setting is_check_shapes=False.N)rf  r   re  ro   r   )rC   r!  r"  s      rG   r   Compose._check_shape_consistency  sb     	6#7#78 Mm6I6I-XYJZ6[_bcp_q6qQ  7rMrJ   c                \    UR                   S;  a  [        U  S35      eUR                  S S $ )Nr[   must be 3D or 4D arrayr  rU  r  r   rK  s     rG   rm  Compose._check_volume_data  s1    99F"yk)@ABBzz"1~rJ   c                \    UR                   S;  a  [        U  S35      eUR                  SS $ )Nru  rw  r
   r  r}  rK  s     rG   _check_volumes_dataCompose._check_volumes_data  s1    99F"yk)@ABBzz!ArJ   c                \    UR                   S;  a  [        U  S35      eUR                  SS $ )z:Check single volumetric mask data format and return shape.r[  r|  Nr  r}  rK  s     rG   rn  Compose._check_mask3d_data  s3     99F"yk)@ABBzz"1~rJ   c                \    UR                   S;  a  [        U  S35      eUR                  SS $ )z=Check multiple volumetric masks data format and return shape.)r  rv  rw  r
   r  r}  rK  s     rG   _check_masks3d_dataCompose._check_masks3d_data  s3     99F"yk)@ABBzz!ArJ   )	r   r   r   r/   r   r   r1   rB   r   )	NNN      ?TFNNF)r8   r   r   "dict[str, Any] | BboxParams | Noner   &dict[str, Any] | KeypointParams | Noner   r   r9   r   r   r0   r   r0   rD   r   rE   r   rB   r0   r   )r   r0   r   r   r   r   rt   r   r  r0   rT   r   r   r   )rT   r   r   r   )rT   r   r   r   )r,  r   r   r0   r   r   )r   r   rT   r   r   ztuple[int, int])r   r   rT   r   r   ztuple[int, int] | None)ra  r   r>   r   r   r   )r!  list[tuple[int, ...]]r   r0   r   r   )rF   r   r   r   )r   r   r#  r   rT   r   r   ztuple[int, ...] | None)r   r   rT   
np.ndarrayr   ztuple[int, ...])r!  r  r"  r  r   r   )r   r   rT   r  r   ztuple[int, int, int]))rQ   r   r   r   r   rH   r   r   setterr   r   r   r	  ru   r  r  r&  r  r   r3  r4  r  r   r   staticmethodrL  rX  r\  rb  rf  r'  r  rl  rp  r  rm  r  rn  r  r   __classcell__rP   s   @rG   r   r     s   ?H ;?BF48 $)-$)=%%=% 8=% @	=%
 2=% =% =% =% '=% =% "=% =%~   ]] '"J7" 8= &&P &D
%s'%
*).(*  
 c cB ! !0 ` `  $=L(7 
  
  
    rJ   r   c                  F   ^  \ rS rSrSrSS	U 4S jjjrSS.S
S jjrSrU =r$ )r   i  a[  Select one of transforms to apply. Selected transform will be called with `force_apply=True`.
Transforms probabilities will be normalized to one 1, so in this case transforms probabilities works as weights.

Args:
    transforms (list): list of transformations to compose.
    p (float): probability of applying selected transform. Default: 0.5.

c                   > [         TU ]  XS9  U R                   Vs/ s H  o3R                  PM     nn[	        U5      nU Vs/ s H  o3U-  PM	     snU l        g s  snf s  snf N)r8   r9   )r   rH   r8   r9   sumtransforms_ps)rC   r8   r9   r   r  srP   s         rG   rH   OneOf.__init__  sX    J4&*oo6oo6-:;]!e]; 7;s   AAFr  c                  U R                   (       a  U R                   H  nU" S0 UD6nM     U$ U R                  (       a  U(       d(  U R                  R	                  5       U R
                  :  aa  U R                  R                  [        U R                  5      U R                  S9nU R                  U   nU" SSS0UD6nU R                  XC5        U$ )a{  Apply the OneOf composition to the input data.

Args:
    *args (Any): Positional arguments are not supported.
    force_apply (bool): Whether to apply transforms regardless of probability. Default: False.
    **data (Any): Dict with data to transform.

Returns:
    dict[str, Any]: Dictionary with transformed data.

Raises:
    KeyError: If positional arguments are provided.

)r9   r  Tr   )
r:   r8   r  rY   r^   r9   rX   choicero   rU   )rC   r  rt   rT   r   idxs         rG   ru   OneOf.__call__  s     __y4y %K;$..2G2G2IDFF2R,,33C4HDL^L^3_C$A...D((1rJ   )r        ?r8   r   r9   r   r  	rQ   r   r   r   r   rH   ru   r   r  r  s   @rG   r   r     s!    < < 8=  rJ   r   c                  `   ^  \ rS rSrSrS
SU 4S jjjrSS.SS jjrSS jrSU 4S jjrS	r	U =r
$ )r    i  a  Selects exactly `n` transforms from the given list and applies them.

The selection of which `n` transforms to apply is done **uniformly at random**
from the provided list. Each transform in the list has an equal chance of being selected.

Once the `n` transforms are selected, each one is applied **based on its
individual probability** `p`.

Args:
    transforms (list[BasicTransform | BaseCompose]): A list of transforms to choose from.
    n (int): The exact number of transforms to select and potentially apply.
             If `replace=False` and `n` is greater than the number of available transforms,
             `n` will be capped at the number of transforms.
    replace (bool): Whether to sample transforms with replacement. If True, the same
                    transform can be selected multiple times (up to `n` times).
                    Default is False.
    p (float): The probability that this `SomeOf` composition will be applied.
               If applied, it will select `n` transforms and attempt to apply them.
               Default is 1.0.

Note:
    - The overall probability `p` of the `SomeOf` block determines if *any* selection
      and application occurs.
    - The individual probability `p` of each transform inside the list determines if
      that specific transform runs *if it is selected*.
    - If `replace` is True, the same transform might be selected multiple times, and
      its individual probability `p` will be checked each time it's encountered.

Example:
    >>> import albumentations as A
    >>> transform = A.SomeOf([
    ...     A.HorizontalFlip(p=0.5),  # 50% chance to apply if selected
    ...     A.VerticalFlip(p=0.8),    # 80% chance to apply if selected
    ...     A.RandomRotate90(p=1.0), # 100% chance to apply if selected
    ... ], n=2, replace=False, p=1.0) # Always select 2 transforms uniformly

    # In each call, 2 transforms out of 3 are chosen uniformly.
    # For example, if HFlip and VFlip are chosen:
    # - HFlip runs if random() < 0.5
    # - VFlip runs if random() < 0.8
    # If VFlip and Rotate90 are chosen:
    # - VFlip runs if random() < 0.8
    # - Rotate90 runs if random() < 1.0 (always)

Fc                   > [         TU ]  X5        X l        U(       d[  U[        U R                  5      :  aB  [        U R                  5      U l        [
        R                  " SU R                   S3[        SS9  X0l        g )Nz=`n` is greater than number of transforms. `n` will be set to .r!   r3   )	r   rH   nro   r8   r6   r7   UserWarningreplacerC   r8   r  r  r9   rP   s        rG   rH   SomeOf.__init__(  se    '1s4??33)DFMMOPTPVPVxWXY
 rJ   r  c               x   U R                   (       a.  U R                   H  nU" S0 UD6nU R                  U5      nM     U$ U R                  R	                  5       U R
                  :  aR  U R                  5       nU H<  nU R                  U   nU" S0 UD6nU R                  XC5        U R                  U5      nM>     U$ )aP  Apply n randomly selected transforms from the list of transforms.

Args:
    *arg (Any): Positional arguments are not supported.
    force_apply (bool): Whether to apply transforms regardless of probability. Default: False.
    **data (Any): Dict with data to transform.

Returns:
    dict[str, Any]: Dictionary with transformed data.

r   )r:   r8   r   rY   r^   r9   _get_idxrU   )rC   r  argrT   r   indices_to_consideris          rG   ru   SomeOf.__call__4  s     __y4y55d; % K>>  "TVV+"&--/(OOA&y4y,,Q555d; ) rJ   c                    U R                   R                  [        U R                  5      U R                  U R
                  S9nUR                  5         U$ N)sizer  )rX   r  ro   r8   r  r  sort)rC   r  s     rG   r  SomeOf._get_idxQ  sG    ##** LL + 

 	

rJ   c                t   > [         TU ]  5       nUR                  U R                  U R                  S.5        U$ )zConvert the SomeOf composition to a dictionary for serialization.

Returns:
    dict[str, Any]: Dictionary representation of the composition.

r  r  )r   r   r   r  r  rC   rA  rP   s     rG   r   SomeOf.to_dict_private[  s3     W,.
4<<@ArJ   r  r
   Fr
   r8   r   r  r   r  r0   r9   r   )r  r   r  r0   rT   r   r   r   r   znp.ndarray[np.int_]r   )rQ   r   r   r   r   rH   ru   r  r   r   r  r  s   @rG   r    r      s,    ,\
 
 7< :	 	rJ   r    c                  >   ^  \ rS rSrSrSSU 4S jjjrSS jrSrU =r$ )	r   ig  a  Apply a random subset of transforms from the given list in a random order.

Selects exactly `n` transforms uniformly at random from the list, and then applies
the selected transforms in a random order. Each selected transform is applied
based on its individual probability `p`.

Attributes:
    transforms (TransformsSeqType): A list of transformations to choose from.
    n (int): The number of transforms to apply. If `n` is greater than the number of available transforms
             and `replace` is False, `n` will be set to the number of available transforms.
    replace (bool): Whether to sample transforms with replacement. If True, the same transform can be
                    selected multiple times. Default is False.
    p (float): Probability of applying the selected transforms. Should be in the range [0, 1]. Default is 1.0.

Example:
    >>> import albumentations as A
    >>> transform = A.RandomOrder([
    ...     A.HorizontalFlip(p=0.5),
    ...     A.VerticalFlip(p=1.0),
    ...     A.RandomBrightnessContrast(p=0.8),
    ... ], n=2, replace=False, p=1.0)
    >>> # This will uniformly select 2 transforms and apply them in a random order,
    >>> # respecting their individual probabilities (0.5, 1.0, 0.8).

Note:
    - Inherits from SomeOf, but overrides `_get_idx` to ensure random order without sorting.
    - Selection is uniform; application depends on individual transform probabilities.

c                "   > [         TU ]  XX4S9  g )N)r8   r  r  r9   r   rH   r  s        rG   rH   RandomOrder.__init__  s    JWJrJ   c                    U R                   R                  [        U R                  5      U R                  U R
                  S9$ r  )rX   r  ro   r8   r  r  rk   s    rG   r  RandomOrder._get_idx  s<     $$++ LL , 
 	
rJ   r   r  r  r  )	rQ   r   r   r   r   rH   r  r   r  r  s   @rG   r   r   g  s    <K K
 
rJ   r   c                  \   ^  \ rS rSrSr    S       S	U 4S jjjrSS.S
S jjrSrU =r$ )r   i  zdSelect one or another transform to apply. Selected transform will be called with `force_apply=True`.c                   > Uc  Ub  Uc  Sn[        U5      eX/n[        TU ]	  X45        [        U R                  5      [
        :w  a  [        R                  " SSS9  g g )Nz>You must set both first and second or set transforms argument.z'Length of transforms is not equal to 2.r!   r3   )r   r   rH   ro   r8   NUM_ONEOF_TRANSFORMSr6   r7   )rC   firstsecondr8   r9   r   rP   s         rG   rH   OneOrOther.__init__  s^     }V o%J't#77MMCPQR 8rJ   Fr  c               ,   U R                   (       a.  U R                   H  nU" S0 UD6nU R                  XC5        M     U$ U R                  R	                  5       U R
                  :  a  U R                  S   " SSS0UD6$ U R                  S   " SSS0UD6$ )aA  Apply one or another transform to the input data.

Args:
    *args (Any): Positional arguments are not supported.
    force_apply (bool): Whether to apply transforms regardless of probability. Default: False.
    **data (Any): Dict with data to transform.

Returns:
    dict[str, Any]: Dictionary with transformed data.

r   r  Tr   )r:   r8   rU   rY   r^   r9   rC   r  rt   rT   r   s        rG   ru   OneOrOther.__call__  s     __y4y,,Q5 % K>>  "TVV+??1%?$?$??r"<t<t<<rJ   r   )NNNr  )r  TransformType | Noner  r  r8   zTransformsSeqType | Noner9   r   r  r  r  s   @rG   r   r     sY    n '+'+/3S#S %S -	S
 S S  8= = =rJ   r   c                  X   ^  \ rS rSrSr  S       S	U 4S jjjrSS.S
S jjrSrU =r$ )r   i  aP  A transformation class to apply specified transforms to selected channels of an image.

This class extends BaseCompose to allow selective application of transformations to
specified image channels. It extracts the selected channels, applies the transformations,
and then reinserts the transformed channels back into their original positions in the image.

Args:
    transforms (TransformsSeqType):
        A sequence of transformations (from Albumentations) to be applied to the specified channels.
    channels (Sequence[int]):
        A sequence of integers specifying the indices of the channels to which the transforms should be applied.
    p (float): Probability that the transform will be applied; the default is 1.0 (always apply).

Returns:
    dict[str, Any]: The transformed data dictionary, which includes the transformed 'image' key.

c                0   > [         TU ]  X5        X l        g ri   )r   rH   channels)rC   r8   r  r9   rP   s       rG   rH   "SelectiveChannelTransform.__init__  s     	' rJ   Fr  c                  U(       d(  U R                   R                  5       U R                  :  a  US   nUSS2SS2U R                  4   n[        R
                  " U5      nU R                   H  nU" US9S   nU R                  Xv5        M     [        R                  " U5      nUR                  5       n	[        U R                  U5       H  u  pXSS2SS2U
4'   M     [        R
                  " U	5      US'   U$ )aC  Apply transforms to specific channels of the image.

Args:
    *args (Any): Positional arguments are not supported.
    force_apply (bool): Whether to apply transforms regardless of probability. Default: False.
    **data (Any): Dict with data to transform.

Returns:
    dict[str, Any]: Dictionary with transformed data.

r"   N)r"   )rY   r^   r9   r  r]   ascontiguousarrayr8   rU   cv2splitrR   zip)rC   r  rt   rT   r"   selected_channels	sub_imager   transformed_channels
output_imgr  channels               rG   ru   "SelectiveChannelTransform.__call__  s     $..//1DFF:ME %aDMM&9 :,,->?I__I.w7	,,Q: % $'99Y#7 J #DMM3G H(/1a9% !I 00<DMrJ   )r  ))r   r
   r!   r  )r8   r   r  zSequence[int]r9   r   r   r   r  r  r  s   @rG   r   r     sO    * #,	!%!  ! 	!
 
! ! 8=  rJ   r   c                     ^  \ rS rSrSr      S             SU 4S jjjrSS.SU 4S jjjr\SS j5       r\ S     SS jj5       r	SS	 jr
SS
 jrSU 4S jjrSrU =r$ )r   i  a  Composition class that enables transform replay functionality.

This class extends the Compose class with the ability to record and replay
transformations. This is useful for applying the same sequence of random
transformations to different data.

Args:
    transforms (TransformsSeqType): List of transformations to compose.
    bbox_params (dict[str, Any] | BboxParams | None): Parameters for bounding box transforms.
    keypoint_params (dict[str, Any] | KeypointParams | None): Parameters for keypoint transforms.
    additional_targets (dict[str, str] | None): Dictionary of additional targets.
    p (float): Probability of applying the compose.
    is_check_shapes (bool): Whether to check shapes of different targets.
    save_key (str): Key for storing the applied transformations.

c                   > [         TU ]  XX4XV5        U R                  SUS9  Xpl        U R                  R                  U5        g )NTr   )r   rH   r   r   r=   add)	rC   r8   r   r   r   r9   r   r   rP   s	           rG   rH   ReplayCompose.__init__  sC     	/WXjth7   *rJ   Fr  c                  > [        [        5      X0R                  '   [        TU ]  " SSU0UD6nU R                  5       nU R                  XTU R                     5        U R                  U5        XTU R                  '   U$ )ab  Apply transforms and record parameters for future replay.

Args:
    *args (Any): Positional arguments are not supported.
    force_apply (bool): Whether to apply transforms regardless of probability. Default: False.
    **kwargs (Any): Dict with data to transform.

Returns:
    dict[str, Any]: Dictionary with transformed data and replay information.

r  r   )r   r   r   r   ru   r   fill_with_paramsfill_applied)rC   r  rt   rF   result
serializedrP   s         rG   ru   ReplayCompose.__call__  sq     !,D 1}}!DkDVD**,
j*?@*% *t}}rJ   c                @    [         R                  U 5      nU" SSS0UD6$ )a  Replay previously saved augmentations.

Args:
    saved_augmentations (dict[str, Any]): Previously saved augmentation parameters.
    **kwargs (Any): Dict with data to transform.

Returns:
    dict[str, Any]: Dictionary with transformed data using saved parameters.

r  Tr   )r   _restore_for_replay)saved_augmentationsrF   augss      rG   r   ReplayCompose.replay1  s(     001DE////rJ   c                   U S   nU S   n[        X5      nU(       a  UnOrU S   nU R                  5        VVs0 s H  u  pxUS;  d  M  Xx_M     n	nn[        U   n
SU	;   a*  U	S    Vs/ s H  n[        R	                  XS9PM     snU	S'   U
" S	0 U	D6n[        SU5      n[        U[        5      (       a  X5l        SUl	        X%l
        U$ s  snnf s  snf )
a  Args:
transform_dict (dict[str, Any]): A dictionary that contains transform data.
lambda_transforms (dict): A dictionary that contains lambda transforms, that
    is instances of the Lambda class.
This dictionary is required when you are restoring a pipeline that contains lambda transforms.
Keys in that dictionary should be named same as `name` arguments in respective lambda transforms
from a serialized pipeline.

appliedrM   r   )r   r  rM   r8   )lambda_transformsr   Tr   )r   r   r   r   r  r	   r5   r   rM   r:   applied_in_replay)transform_dictr  r  rM   lmbdrS   namer   r   rt   r   r   s               rG   r  !ReplayCompose._restore_for_replay@  s     !+)*>MI!"67D%3%9%9%;t%;TQqHs?sDAD%;Dt'-Ct# ",/&/ "55a5]/&\" dI)95	i00% $	&-# u&s   CC'Cc                    UR                  UR                  S5      5      nX1S'   US	 UR                  S/ 5       H  nU R                  XB5        M     g)zFill serialized transform data with parameters for replay.

Args:
    serialized (dict[str, Any]): Serialized transform data.
    all_params (Any): Parameters to fill in.

r   rM   r8   N)r  r  )rC   r  
all_paramsrM   rS   s        rG   r  ReplayCompose.fill_with_paramse  sN     
t 45%8t#b9I!!)8 :rJ   c                    SU;   a6  US    Vs/ s H  o R                  U5      PM     nn[        U5      US'   US   $ UR                  S5      SLUS'   US   $ s  snf )zSet 'applied' flag for transforms based on parameters.

Args:
    serialized (dict[str, Any]): Serialized transform data.

Returns:
    bool: True if any transform was applied, False otherwise.

r8   r  rM   N)r  rW  r  )rC   r  r   r  s       rG   r  ReplayCompose.fill_applieds  sv     :%5?5MN5M((+5MGN$'LJy! )$$ %/NN8$<D$HJy!)$$	 Os   Ac                ^   > [         TU ]  5       nUR                  SU R                  05        U$ )zConvert the ReplayCompose to a dictionary for serialization.

Returns:
    dict[str, Any]: Dictionary representation of the composition.

r   )r   r   r   r   r  s     rG   r   ReplayCompose.to_dict_private  s/     W,.
:t}}56rJ   r  )NNNr  Tr   )r8   r   r   r  r   r  r   r   r9   r   r   r0   r   r   )rt   r   r  r0   rF   r   r   r   )r  r   rF   r   r   r   ri   )r  r   r  zdict[str, Any] | Noner   r   )r  r   r  r   r   r   )r  r   r   r0   r   )rQ   r   r   r   r   rH   ru   r  r   r  r  r  r   r   r  r  s   @rG   r   r     s    ( ;?BF48 $ +%+ 8+ @	+
 2+ + + + + 8=  ( 0 0  48"&"0" 
" "H9%"	 	rJ   r   c                  F   ^  \ rS rSrSrSS	U 4S jjjrSS.S
S jjrSrU =r$ )r   i  a  Sequentially applies all transforms to targets.

Note:
    This transform is not intended to be a replacement for `Compose`. Instead, it should be used inside `Compose`
    the same way `OneOf` or `OneOrOther` are used. For instance, you can combine `OneOf` with `Sequential` to
    create an augmentation pipeline that contains multiple sequences of augmentations and applies one randomly
    chose sequence to input data (see the `Example` section for an example definition of such pipeline).

Example:
    >>> import albumentations as A
    >>> transform = A.Compose([
    >>>    A.OneOf([
    >>>        A.Sequential([
    >>>            A.HorizontalFlip(p=0.5),
    >>>            A.ShiftScaleRotate(p=0.5),
    >>>        ]),
    >>>        A.Sequential([
    >>>            A.VerticalFlip(p=0.5),
    >>>            A.RandomBrightnessContrast(p=0.5),
    >>>        ]),
    >>>    ], p=1)
    >>> ])

c                    > [         TU ]  XS9  g r  r  )rC   r8   r9   rP   s      rG   rH   Sequential.__init__  s    J4rJ   Fr  c                   U R                   (       d/  U(       d(  U R                  R                  5       U R                  :  a=  U R                   H-  nU" S0 UD6nU R                  XC5        U R                  U5      nM/     U$ )a9  Apply all transforms in sequential order.

Args:
    *args (Any): Positional arguments are not supported.
    force_apply (bool): Whether to apply transforms regardless of probability. Default: False.
    **data (Any): Dict with data to transform.

Returns:
    dict[str, Any]: Dictionary with transformed data.

r   )r:   rY   r^   r9   r8   rU   r   r  s        rG   ru   Sequential.__call__  se     {dnn.C.C.E.N__y4y,,Q555d; % rJ   r   r  r  r  r  r  s   @rG   r   r     s!    25 5 8=  rJ   r   )?r   
__future__r   r^   r6   collectionsr   collections.abcr   r   typingr   r   r	   r  numpyr]   
bbox_utilsr   r   	hub_mixinr   keypoints_utilsr   r   serializationr   r   r   r   transforms_interfacer   utilsr   r   r   __all__r  r   r   r8  r   r   r*  r+  ri  ro  r_  r`  VOLUME_KEYSr  CHECKED_VOLUMESr  CHECKED_MASKS3Dr   r   r   r    r   r   r   r   r   r   rJ   rG   <module>r     sO   #   # . # # 
  1  ?  1 8 8   nm34' l	 x 
6"9: $ #++t, tn	H	k8 H	V)K )Xk[ k\*
& *
Z(= (=V: :zQG Qh. .rJ   