Ë
    ëÓ^j¤  ã                  ó   — d Z ddlmZ ddlmZ ddlmZ ddlZddlZddl	Z	ddl
mZ ddlmZ ddlmZmZmZ dd	lmZ dd
lmZmZ ddlmZ  e«       Zdd„Zdd„Zdd„Z	 	 	 d 	 	 	 	 	 	 	 	 	 d!d„Zd"d„Zd#d„Z G d„ de	j>                  j@                  «      Z  G d„ de!«      Z"ddœ	 	 	 	 	 	 	 d$d„Z#	 	 	 	 	 	 	 	 d%	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d&d„Z$	 	 	 	 	 	 	 	 d%	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d&d„Z%d'd„Z&d(d„Z'd'd„Z(y))zžCOCO dataset which returns image_id for evaluation.

Mostly copy-paste from https://github.com/pytorch/vision/blob/13b35ff/references/detection/coco_utils.py
é    )Úannotations)ÚPath)ÚAnyN)ÚImage)ÚTensor)ÚComposeÚToDtypeÚToImage)Ú
AUG_CONFIG)ÚAlbumentationsWrapperÚ	Normalize)Ú
get_loggerc                ó@   — t        | «      dz  dz  j                  «       S )NÚtrainú_annotations.coco.json)r   Úexists)Údataset_dirs    ú_/var/www/ramen.bs-engineer-server.com/venv/lib/python3.12/site-packages/rfdetr/datasets/coco.pyÚis_valid_coco_datasetr   '   s!   € Ü�Ó Ñ'Ð*BÑB×JÑJÓLÐLó    c                óÆ  — | j                   j                  «       D ��ch c]3  \  }}|j                  d«      s|j                  d«      sŒ)t        |«      ’Œ5 }}}|rt	        |«      S | j
                  j                  «       D ]O  }|j                  d«      st        |j                  dd«      «      dkD  sŒ3|j                  t        |d   «      «       ŒQ t	        |«      S c c}}w )zLReturn sorted COCO category ids that carry keypoint metadata or annotations.Ú	keypointsÚskeletonÚnum_keypointsr   Úcategory_id)ÚcatsÚitemsÚgetÚintÚsortedÚannsÚvaluesÚadd)ÚcocoÚcat_idÚcategoryÚcategory_idsÚ
annotations        r   Ú_category_ids_with_keypointsr)   +   sÅ   € ð -1¯I©I¯O©OÓ,=÷Ù(˜ ÀÇÁÈkÔAZÐ^f×^jÑ^jÐkuÕ^vŒˆF�ð€Lñ ñ Ü�lÓ#Ð#à—i‘i×&Ñ&Ó(ò =ˆ
Ø�>‰>˜+Ô&¬#¨j¯n©n¸_ÈaÓ.PÓ*QÐTUÓ*UØ×ÑœS ¨MÑ!:Ó;Õ<ð=ô �,ÓÐùós   ž*CÁ	Cc                ó$  — t        |xs g «      }t        |«      D ��cg c]  \  }}|dkD  sŒ|‘Œ }}}|st        d«      ‚t        | «      }|st        d«      ‚t	        |«      t	        |«      kD  r$t        dt	        |«      › dt	        |«      › d�«      ‚t        d„ | j                  j                  «       D «       «      }t        t	        |«      t        |«      dz   «      }t        «       }	i }
t        ||«      D ]>  \  }}||k\  rt        d	|› d
|› dt	        |«      › d�«      ‚||
|<   |	j                  |«       Œ@ t        |«      D �cg c]	  }||	vsŒ|‘Œ }}|D ],  }||
v rŒ|st        d|› d�«      ‚|j                  d«      |
|<   Œ. |
S c c}}w c c}w )aÂ  Map COCO category ids onto model label slots that have keypoint capacity.

    RF-DETR keypoint schemas are indexed by model label. The preview person-keypoint schema is ``[17]``: label slot
    ``0`` owns the 17 COCO person keypoints. Legacy checkpoints may still use a background-first ``[0, 17]`` schema
    where slot ``0`` is reserved (0 keypoints) and slot ``1`` is person. This helper maps keypoint-bearing categories
    onto slots with a non-zero keypoint count (``count > 0``), so both layouts keep supervision aligned. For multi-class
    keypoint training supply e.g. ``[17, 4]`` where each non-zero entry corresponds to a keypoint-bearing category in
    ascending COCO category ID order.
    r   z˜Keypoint COCO dataset requested, but num_keypoints_per_class has no active keypoint slots. Provide a schema such as [17] for the keypoint preview model.z·Keypoint COCO dataset has no keypoint category metadata and no keypoint annotations. Expected COCO categories with a 'keypoints' field or annotations with 'keypoints'/'num_keypoints'.z<Keypoint COCO dataset has more keypoint-bearing categories (z) than active schema slots (zR). Multi-class keypoint training needs an explicit num_keypoints_per_class schema.c              3  ó2   K  — | ]  }t        |«      –— Œ y ­w)N)r   )Ú.0r%   s     r   ú	<genexpr>z,_build_keypoint_cat2label.<locals>.<genexpr>X   s   è ø€ ÒG¨FœC ŸKÑGùs   ‚é   zKeypoint schema slot z for category_id z# exceeds the detected class count (zE). Pass num_classes large enough to include this keypoint label slot.z>No free model label slots remain for non-keypoint category_id ú.)ÚlistÚ	enumerateÚ
ValueErrorr)   Úlenr    r   ÚkeysÚmaxÚsetÚzipr#   ÚrangeÚpop)r$   Únum_keypoints_per_classÚschemaÚidxÚcountÚactive_slotsÚkeypoint_cat_idsÚsorted_cat_idsÚrequired_slotsÚassigned_slotsÚ	cat2labelr%   ÚslotÚ
free_slotss                 r   Ú_build_keypoint_cat2labelrF   9   sñ  € ô Ð)Ò/¨RÓ0€FÜ*3°FÓ*;×I™J˜C ¸uÀq»y’CÐI€LÑIÙÜðLó
ð 	
ô
 4°DÓ9ÐÙÜðqó
ð 	
ô ÐÓœs <Ó0Ò0ÜðÜÐ$Ó%Ð&Ð&BÄ3À|ÓCTÐBUð V^ð^ó
ð 	
ô ÑG°d·i±i·n±nÓ6FÔGÓG€NÜœ˜^Ó,¬c°,Ó.?À!Ñ.CÓD€NÜ"›u€NØ "€IäÐ,¨lÓ;ò !‰ˆ�Ø�>Ò!ÜØ'¨ vÐ->¸v¸hð GÜ˜Ó'Ð(Ð(mðoóð ð !ˆ	�&ÑØ×Ñ˜4Õ ð!ô $)¨Ó#8ÖW˜4¸DÈÒ<V’$ÐW€JÐWØ ò .ˆØ�YÑØÙÜÐ]Ð^dÐ]eÐefÐgÓhÐhØ&ŸN™N¨1Ó-ˆ	�&Òð.ð ÐùóU JùòD Xs   žF¬FÅ	FÅFc                óÌ   — | ||z  z  }|sg d¢ng d¢}|D �cg c]  }||z   ‘Œ	 }}|D �cg c]
  }||z  |z  ‘Œ }	}|	D �cg c]  }|||z  dz  k\  sŒ|‘Œ }	}|	S c c}w c c}w c c}w )N)éýÿÿÿéþÿÿÿéÿÿÿÿr   r.   é   é   é   )éûÿÿÿéüÿÿÿrH   rI   rJ   r   r.   rK   rL   rM   é   rK   © )
Ú
resolutionÚexpanded_scalesÚ
patch_sizeÚnum_windowsÚbase_num_patches_per_windowÚoffsetsÚoffsetÚscalesÚscaleÚproposed_scaless
             r   Úcompute_multi_scale_scalesr\   q   s—   € ð #-°¸kÑ1IÑ"JÐÙ1@Ó)ÒFl€GØAHÖI°vÐ)¨FÓ2ÐI€FÐIØEKÖL¸E�u˜zÑ)¨KÓ7ÐL€OÐLà*öØ¨e°zÀKÑ7OÐRSÑ7SÓ.SŠð€Oð ð Ðùò JùÚLùòs   —A©A¾A!ÁA!c                ó:   — t        | t        «      xr
 d| v xr d| v S )u:  Check whether a COCO segmentation entry is in RLE format.

    RLE annotations are dicts with ``"counts"`` and ``"size"`` keys, as opposed to polygon annotations which are lists
    of coordinate arrays. This is a structural check only â€” it verifies key presence but does not validate value types.
    A dict with counts=None will pass this check but fail downstream in convert_coco_poly_to_mask.

    Args:
        segmentation: A single COCO segmentation annotation entry.

    Returns:
        ``True`` if the entry looks like an RLE dict, ``False`` otherwise.
    ÚcountsÚsize)Ú
isinstanceÚdict)Úsegmentations    r   Ú_is_rlerc   ‚   s&   € ô �l¤DÓ)Òa¨h¸,Ð.FÒaÈ6ÐUaÐKaÐar   c                óž  — ddl m} g }| D �]s  }|�t        |t        «      sEt	        |«      dk(  r7|j                  t        j                  ||ft        j                  ¬«      «       Œ[t        |«      rq|d   }t        |t        t        t        f«      s"t        dt        |«      j                  ›d�«      ‚t        |t        t        f«      r|g}n(|j!                  |||«      g}n|j!                  |||«      }|j#                  |«      }|j$                  dk  r|d   }t        j&                  |t        j                  ¬«      }|j)                  d	¬
«      j+                  t        j                  «      }|j                  |«       �Œv t	        |«      dk(  r(t        j                  d||ft        j                  ¬«      S t        j,                  |d¬
«      S )a¸  Convert COCO segmentation annotations to a binary mask tensor of shape ``[N, H, W]``.

    Supports both polygon and RLE (Run-Length Encoding) annotation formats. Polygon annotations (lists of coordinate
    arrays) are rasterised via ``pycocotools.mask.frPyObjects``.  RLE annotations (dicts with ``"counts"`` and
    ``"size"`` keys; ``counts`` may be str or bytes for compressed RLE, or list of ints for uncompressed RLE) are
    decoded directly, skipping the polygon-to-RLE conversion step.

    Args:
        segmentations: Per-instance segmentation annotations.  Each element is
            either a polygon list (``[[x1, y1, x2, y2, ...], ...]``), an RLE dict (``{"counts": ..., "size": [H, W]}``),
            or ``None`` / empty for instances without a mask. Dicts must be valid COCO RLE annotations with non-empty
            ``"counts"`` and ``"size"`` fields.
        height: Image height in pixels (used for polygon rasterisation).
        width: Image width in pixels (used for polygon rasterisation).

    Returns:
        A ``uint8`` tensor of shape ``(N, H, W)`` where each slice is a binary mask for one instance.  Returns a ``(0,
        H, W)`` tensor when *segmentations* is empty.
    r   N©Údtyper^   z-RLE segmentation has unsupported counts type z; expected str, bytes, or listrL   ).NrK   ©Údim)Úpycocotools.maskÚmaskr`   ra   r3   ÚappendÚtorchÚzerosÚuint8rc   ÚstrÚbytesr0   r2   ÚtypeÚ__name__ÚfrPyObjectsÚdecodeÚndimÚ	as_tensorÚanyÚtoÚstack)	ÚsegmentationsÚheightÚwidthÚ	coco_maskÚmasksrb   r^   Úrlesrj   s	            r   Úconvert_coco_poly_to_maskr€   ’   s†  € õ( )à€EØ%ó ˆØÐ¬
°<ÄÔ(FÌ3È|ÓK\Ð`aÒKaà�L‰LœŸ™ f¨e _¼E¿K¹KÔHÔIØÜ�<Ô Ø! (Ñ+ˆFÜ˜f¤s¬E´4Ð&8Ô9Ü ØCÄDÈÃL×DYÑDYÐC\ð ]3ð 3óð ô ˜&¤3¬ ,Ô/à$�~‘ð "×-Ñ-¨l¸FÀEÓJÐK‘à×(Ñ(¨°v¸uÓEˆDØ×Ñ Ó%ˆØ�9‰9�qŠ=Ø˜	‘?ˆDÜ�‰˜t¬5¯;©;Ô7ˆà�x‰x˜Aˆx‹×!Ñ!¤%§+¡+Ó.ˆØ�‰�TÖð5ô6 ˆ5ƒz�Q‚Ü�{‰{˜A˜v uÐ-´U·[±[ÔAÐAÜ�;‰;�u !Ô$Ð$r   c                  óX   ‡ — e Zd ZdZ	 	 	 	 d	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dˆ fd„Zdˆ fd„Zˆ xZS )ÚCocoDetectionu­	  COCO detection dataset with optional sparse-to-contiguous category ID remapping.

    Extends ``torchvision.datasets.CocoDetection`` with two additions:

    1. A pluggable transform pipeline (``transforms``) applied after the raw
       annotation conversion handled by :class:`ConvertCoco`.
    2. Optional remapping of sparse COCO category IDs to contiguous 0-based label
       indices via ``remap_category_ids``.

    COCO category IDs are sparse (1â€“90 with gaps such as 12, 26, 29 â€¦).  When a model has only *N* output slots the IDs
    cannot be used directly as tensor indices â€” doing so causes out-of-bounds errors in the matcher and loss. Setting
    ``remap_category_ids=True`` builds a ``cat2label`` mapping from the annotation file so that IDs are remapped to the
    range ``[0, N)``.  The reverse ``label2cat`` mapping is attached to the underlying COCO API object so that
    :class:`~rfdetr.datasets.coco_eval.CocoEvaluator` can convert predicted label indices back to the original category
    IDs required by pycocotools.

    ``remap_category_ids`` should be ``True`` for Roboflow / custom datasets (via :func:`build_roboflow_from_coco`) and
    ``False`` (the default) when evaluating pretrained models that were trained with the convention that model output
    slot *k* corresponds directly to COCO category ID *k*.

    Args:
        img_folder: Path to the directory containing the dataset images.
        ann_file: Path to the COCO-format JSON annotation file.
        transforms: Transform pipeline applied to ``(image, target)`` pairs after
            annotation conversion.  ``None`` means no additional transforms.
        include_masks: If ``True``, decode polygon segmentation masks into binary
            tensors and include them in the target dict under the ``"masks"`` key.
        include_keypoints: If ``True``, parse COCO keypoints and include them in
            the target dict under the ``"keypoints"`` key.
        num_keypoints_per_class: Optional keypoint schema describing the number of
            keypoints per class. When provided, keypoints are padded/truncated to ``max(num_keypoints_per_class)``.
        remap_category_ids: If ``True``, build a ``cat2label`` mapping from the
            annotation file that remaps sparse category IDs to contiguous 0-based label indices.  The reverse mapping is
            stored as ``label2cat`` on both this object and the underlying COCO API object.  Defaults to ``False``.
    c                óP  •— t         t        | �  ||«       || _        || _        || _        |rÂ|rt        | j                  |«      | _        nOt        t        | j                  j                  j                  «       «      «      D ��	ci c]  \  }}	|	|“Œ
 c}	}| _        | j                  j                  «       D �	�
ci c]  \  }	}
|
|	“Œ
 c}
}	| _        t        | j                  d| j                  «       nd | _        d | _        t!        ||| j                  |¬«      | _        y c c}	}w c c}
}	w )NÚ	label2cat)Úinclude_masksÚinclude_keypointsrC   r:   )Úsuperr‚   Ú__init__Ú_transformsr…   r†   rF   r$   rC   r1   r    r   r4   r   r„   ÚsetattrÚConvertCocoÚprepare)ÚselfÚ
img_folderÚann_fileÚ
transformsr…   r†   r:   Úremap_category_idsÚir%   ÚlabelÚ	__class__s              €r   rˆ   zCocoDetection.__init__î   sê   ø€ ô 	Œm˜TÑ+¨J¸ÔAØ%ˆÔØ*ˆÔØ!2ˆÔÙá Ü!:¸4¿9¹9ÐF]Ó!^�•ä=FÄvÈdÏiÉiÏnÉn×NaÑNaÓNcÓGdÓ=e×!f±	°°6 &¨!¡)Ó!f�”àAEÇÁ×AUÑAUÓAW×X±°¸˜e V™mÓXˆDŒNä�D—I‘I˜{¨D¯N©NÕ;à!ˆDŒNØ!ˆDŒNÜ"Ø'Ø/Ø—n‘nØ$;ô	
ˆ�ùó "gùãXs   ÂDÂ7D"c                óÌ   •— t         t        | �  |«      \  }}| j                  |   }||dœ}| j	                  ||«      \  }}| j
                  �| j                  ||«      \  }}||fS )N)Úimage_idr   )r‡   r‚   Ú__getitem__ÚidsrŒ   r‰   )r�   r<   ÚimgÚtargetr–   r”   s        €r   r—   zCocoDetection.__getitem__  sq   ø€ ÜœM¨4Ñ<¸SÓA‰ˆˆVØ—8‘8˜C‘=ˆØ&°vÑ>ˆØ—l‘l 3¨Ó/‰ˆˆVØ×ÑÐ'ð ×*Ñ*¨3°Ó7‰KˆC�Ø�Fˆ{Ðr   )FFNF)rŽ   ú
str | Pathr�   r›   r�   z
Any | Noner…   Úboolr†   rœ   r:   úlist[int] | Noner‘   rœ   ÚreturnÚNone)r<   r   rž   ztuple[Any, Any])rr   Ú
__module__Ú__qualname__Ú__doc__rˆ   r—   Ú__classcell__)r”   s   @r   r‚   r‚   É   su   ø„ ñ"ðR $Ø"'Ø48Ø#(ð 
àð 
ð ð 
ð ð	 
ð
 ð 
ð  ð 
ð "2ð 
ð !ð 
ð 
õ 
÷D	ñ 	r   r‚   c                  ó<   — e Zd ZdZ	 	 	 	 d	 	 	 	 	 	 	 	 	 dd„Zdd„Zy)r‹   uð  Convert a raw COCO annotation dict into model-ready tensors.

    Accepts the ``(image, target)`` pair produced by ``torchvision.datasets.CocoDetection`` and returns the same image
    alongside a target dict containing:

    - ``"boxes"`` â€“ ``(N, 4)`` float32 tensor in absolute ``[x_min, y_min, x_max, y_max]`` format.
    - ``"labels"`` â€“ ``(N,)`` int64 tensor of class indices.
    - ``"image_id"`` â€“ scalar int64 tensor.
    - ``"area"`` â€“ ``(N,)`` float32 tensor of annotation areas (used by COCO eval).
    - ``"iscrowd"`` â€“ ``(N,)`` int64 tensor (0 = instance, 1 = crowd).
    - ``"masks"`` â€“ ``(N, H, W)`` bool tensor of binary segmentation masks, only
      present when ``include_masks=True``.
    - ``"keypoints"`` â€“ ``(N, K, 3)`` float32 tensor in COCO keypoint format,
      only present when ``include_keypoints=True``.

    Crowd annotations (``iscrowd=1``) and degenerate boxes (zero width or height after clamping to image boundaries) are
    filtered out.

    Args:
        include_masks: If ``True``, decode segmentation annotations (polygon or
            RLE format) into binary masks and include them in the returned target dict.
        cat2label: Optional mapping from COCO ``category_id`` values to contiguous
            0-based label indices.  When ``None`` (default) the raw ``category_id`` values are used as labels directly,
            which is correct for datasets whose IDs are already 0-indexed.  Pass a non-``None`` mapping for sparse
            COCO-style datasets (e.g. IDs 1â€“90 with gaps) so that labels stay within the model's output range.
        num_keypoints_per_class: Optional keypoint schema. When provided, keypoints
            are padded/truncated to ``max(num_keypoints_per_class)`` in each annotation.
    Nc                óf   — || _         || _        || _        |�t        |d¬«      | _        y d| _        y )Nr   )Údefault)r…   r†   rC   r5   r   )r�   r…   r†   rC   r:   s        r   rˆ   zConvertCoco.__init__:  s8   € ð +ˆÔØ!2ˆÔØ"ˆŒØH_ÐHkœSÐ!8À!ÔDˆÕÐqrˆÕr   c           	     ó:
  — |j                   \  }}|d   }t        j                  |g«      }|d   }|D �cg c]  }d|vs	|d   dk(  sŒ|‘Œ }}|D �cg c]  }|d   ‘Œ	 }}t        j                  |t        j                  ¬«      j	                  dd«      }|d d …d	d …fxx   |d d …d d	…f   z  cc<   |d d …dd d	…f   j                  d|¬
«       |d d …dd d	…f   j                  d|¬
«       g }	|D ]s  }|d   }
t        | dd «      �N|
| j                  vr!t        d|
› d|j                  d«      › d�«      ‚|	j                  | j                  |
   «       Œc|	j                  |
«       Œu t        j                  |	t        j                  ¬«      }	|d d …df   |d d …df   kD  |d d …d	f   |d d …df   kD  z  }||   }|	|   }	i }||d<   |	|d<   ||d<   t        j                  |D �cg c]  }|d   ‘Œ	 c}«      }t        j                  |D �cg c]  }d|v r|d   nd‘Œ c}«      }||   |d<   ||   |d<   d }| j                  �rŠ| j                  }|dk(  r*|D ]%  }|j                  d«      }|€Œt        |«      dz  } n g }|D ]ò  }|j                  d«      }|€7|j                  t        j                  |dft        j                  ¬«      «       ŒMt        j                  |t        j                  ¬«      j	                  dd«      }|j                   d   |k  rKt        j                  |dft        j                  ¬«      }||d |j                   d    |j                  |«       Œß|j                  |d | «       Œô t        |«      dkD  rt        j"                  |d¬«      }n(t        j                  d|dft        j                  ¬«      }||   |d<   | j$                  r×t        |«      dkD  r{d|d   v rt|D �cg c]  }|j                  dg «      ‘Œ }}t'        |||«      }|j)                  «       dkD  r	||   |d<   nWt        j                  d||ft        j*                  ¬«      |d<   n+t        j                  d||ft        j*                  ¬«      |d<   |d   j-                  «       |d<   |�|d   |   |d<   t        j                  t/        |«      t/        |«      g«      |d<   t        j                  t/        |«      t/        |«      g«      |d<   ||fS c c}w c c}w c c}w c c}w c c}w )Nr–   r   Úiscrowdr   Úbboxre   rJ   rM   rK   )Úminr5   r.   r   rC   zUnknown category_id z for image_id zR encountered in annotations. Check that your category mapping matches the dataset.rL   ÚboxesÚlabelsÚarear   rg   rb   r~   Ú	orig_sizer_   )r_   rl   rv   Úfloat32ÚreshapeÚclamp_ÚgetattrrC   ÚKeyErrorr   rk   Úint64r†   r   r3   rm   Úshapery   r…   r€   Únumelrn   rœ   r   )r�   Úimagerš   ÚwÚhr–   ÚannoÚobjr«   Úclassesr   Úkeepr­   r¨   Úkeypoint_keepr   r   Úkeypoint_tensorsÚraw_keypointsÚkeypoint_tensorÚpaddedÚkeypoints_outrz   r~   s                           r   Ú__call__zConvertCoco.__call__F  s  € Ø�z‰z‰ˆˆ1à˜*Ñ%ˆÜ—?‘? H :Ó.ˆà�mÑ$ˆà#ÖS˜ y¸Ñ';¸sÀ9¹~ÐQRÓ?R’ÐSˆÐSà(,Ö- ��V“Ð-ˆÐ-ä—‘ ¬U¯]©]Ô;×CÑCÀBÈÓJˆØŠa�‘ˆe‹˜ša  ! ˜e™Ñ$‹ØŠa���A�ˆg‰×Ñ !¨ÐÔ+ØŠa���A�ˆg‰×Ñ !¨ÐÔ+àˆØò 
	,ˆCØ˜mÑ,ˆKÜ�t˜[¨$Ó/Ð;Ø d§n¡nÑ4Ü"Ø.¨{¨m¸>È&Ï*É*ÐU_ÓJ`ÐIað blð lóð ð —‘˜tŸ~™~¨kÑ:Õ;à—‘˜{Õ+ð
	,ô —/‘/ '´·±Ô=ˆà’a˜�d‘˜e¢A q D™kÑ)¨e²A°q°D©k¸EÂ!ÀQÀ$¹KÑ.GÑHˆØ�d‘ˆØ˜$‘-ˆàˆØˆˆw‰Ø"ˆˆxÑØ%ˆˆzÑô �‰°tÖ<°  F£Ò<Ó=ˆÜ—/‘/ÐX\Ö"]ÐQT°YÀ#Ñ5E 3 y¢>È1Ñ#LÒ"]Ó^ˆØ˜d™ˆˆv‰Ø# D™MˆˆyÑà'+ˆØ×!Ó!Ø ×.Ñ.ˆMØ Ò!Øò �CØ #§¡¨Ó 4�IØ Ñ,Ü(+¨I«¸!Ñ(;˜Ùð	ð .0ÐØò I�Ø #§¡¨Ó 4�Ø Ð(Ø$×+Ñ+¬E¯K©K¸ÈÐ8JÔRW×R_ÑR_Ô,`ÔaØä"'§/¡/°-ÄuÇ}Á}Ô"U×"]Ñ"]Ð^`ÐbcÓ"d�Ø"×(Ñ(¨Ñ+¨mÒ;Ü"Ÿ[™[¨-¸Ð);Ä5Ç=Á=ÔQ�FØ9H�FÐ5˜_×2Ñ2°1Ñ5Ð6Ø$×+Ñ+¨FÔ3ØØ ×'Ñ'¨¸¸Ð(GÕHðIô Ð#Ó$ qÒ(Ü %§¡Ð,<À!Ô D‘ä %§¡¨Q°¸qÐ,AÌÏÉÔ W�Ø"/°Ñ"5ˆF�;Ñð ×ÒÜ�4‹y˜1Š} °4¸±7Ñ!:ØHLÖ MÀ §¡¨¸Õ!<Ð M�Ð MÜ1°-ÀÀAÓF�Ø—;‘;“= 1Ò$Ø&+¨D¡k�F˜7’Oä&+§k¡k°1°a¸°)Ä5Ç;Á;Ô&O�F˜7’Oä"'§+¡+¨q°!°Q¨i¼u¿{¹{Ô"K��w‘à$ W™o×2Ñ2Ó4ˆF�7‰OØÐ(Ø"(¨¡/°-Ñ"@��w‘ä#Ÿo™o¬s°1«v´s¸1³vÐ.>Ó?ˆˆ{ÑÜŸ™¬#¨a«&´#°a³&Ð)9Ó:ˆˆv‰à�fˆ}Ðùòy Tùâ-ùò>  =ùÚ"]ùòT !Ns#   ´TÁTÁT	ÇTÈTÏ*T)FFNN)
r…   rœ   r†   rœ   rC   zdict[int, int] | Noner:   r�   rž   rŸ   )r·   zImage.Imagerš   zdict[str, Any]rž   z"tuple[Image.Image, dict[str, Any]])rr   r    r¡   r¢   rˆ   rÄ   rQ   r   r   r‹   r‹     sV   „ ñð> $Ø"'Ø+/Ø48ð
sàð
sð  ð
sð )ð	
sð
 "2ð
sð 
ó
sôdr   r‹   )Úmax_sizec               óF  — |rBdd| D �cg c]	  }d||dœi‘Œ c}ii}ddddg d¢iidd| D �cg c]  }d	d
dg||dœi‘Œ c}iigii}nK|xs d}t        | «      dk(  r| d   n| }dddd|iidd|iigii}ddddg d¢iid	d
dgd
d
dœidd|iidd|iigii}dd||giigS c c}w c c}w )u­  Build the training resize pipeline as an Albumentations config list.

    Expresses the ``RandomSelect(resize_a, Compose([resize_b1, crop, resize_b2]))`` pattern as a config-driven
    ``OneOf``/``Sequential`` for use with :meth:`AlbumentationsWrapper.from_config`.

    Two branches are selected with equal probability:

    - **Option A** â€“ direct resize to the target scale(s).
    - **Option B** â€“ resize to an intermediate scale (400/500/600 px), crop,
      then resize to the target scale.

    Divisibility padding (rounding ``H``/``W`` up to a multiple of ``patch_size * num_windows``) is handled by the batch
    collator via :func:`~rfdetr.utilities.tensors.make_collate_fn`, not here.

    Args:
        scales: Target resize scales in pixels.
        square: If ``True``, produce square output using ``A.Resize``
            (one random scale from *scales*).  If ``False``, preserve aspect ratio using ``A.SmallestMaxSize`` with an
            optional long-side cap.
        max_size: Maximum long-side size for non-square resizes.  Defaults to
            ``1333`` when *square* is ``False``.

    Returns:
        A single-element list containing a ``OneOf`` config entry.
    ÚOneOfr�   ÚResize©r{   r|   Ú
SequentialÚSmallestMaxSizerÅ   )i�  iô  éX  ÚRandomSizedCropi€  rÌ   )Úmin_max_heightr{   r|   é5  r.   r   ÚLongestMaxSize)r3   )rY   ÚsquarerÅ   ÚsÚoption_aÚoption_bÚcapÚ
size_params           r   Ú_build_train_resize_configr×   ­  s\  € ñ> àØÈfÖUÈ °QÀÑ*CÒDÒUðð$
ˆð ØØ&¨²_Ð(EÐFàØ(à)/ö+à$%ð "3ÈÈSÀzÐ]^ÐijÑ4kÒ lò+ð"ðð
ðð$
‰ð  Ò˜$ˆä'*¨6£{°aÒ'7˜& š)¸Vˆ
àØØ&¨°ZÐ(@ÐAØ%¨
°CÐ'8Ð9ððð
ˆð ØØ&¨²_Ð(EÐFØ&¸CÀ¸:ÐQTÐ_bÑ(cÐdØ&¨°ZÐ(@ÐAØ%¨
°CÐ'8Ð9ð	ðð	
ˆð �| h°Ð%9Ð:Ð;Ð<Ð<ùòS Vùò+s
   ‰B«Bc
                ó�  — t        «       }
t        t        j                  d¬«      }t	        «       }|g}|r.t        ||||«      }|r|d   g}t        j                  d|› �«       | dk(  ri|�|nt        }t        j                  t        |dd¬«      «      }g |¢}|st        j                  ||	¬	«      }|g |¢z  }||
|gz  }|s||gz  }t        |«      S | d
v r2t        j                  dd|iidddiig«      }t        g |¢|
‘|‘|‘«      S | dk(  r.t        j                  d||dœig«      }t        g |¢|
‘|‘|‘«      S t        d| › �«      ‚)u  Build the standard COCO transform pipeline for a given dataset split.

    Returns a composed transform that resizes images to the target ``resolution`` (with optional multi-scale jitter),
    applies Albumentations-based augmentations during training, and normalises pixel values with ImageNet statistics.

    For the ``"train"`` split the pipeline uses a two-branch ``OneOf`` between a direct resize and a resize â†’
    random-crop â†’ resize sequence (built via :func:`_build_train_resize_config`), followed by the augmentation stack and
    normalisation.  For ``"val"``, ``"test"``, and ``"val_speed"`` only resize and normalisation are applied â€” no
    augmentation.

    When *gpu_postprocess* is ``True``, both the Albumentations augmentation wrappers and the ``Normalize`` step are
    omitted from the ``"train"`` pipeline. The ``RFDETRDataModule`` then applies augmentation and normalization on the
    device in ``on_after_batch_transfer`` instead.

    Args:
        image_set: Dataset split identifier â€” ``"train"``, ``"val"``, ``"test"``,
            or ``"val_speed"``.
        resolution: Target short-side resolution in pixels.  During validation the
            longest side is capped at 1333 px to preserve aspect ratio.
        multi_scale: If ``True``, sample the resize target from a range of scales
            computed by :func:`compute_multi_scale_scales` instead of using a single fixed size.
        expanded_scales: Passed to :func:`compute_multi_scale_scales`; broadens the
            scale range when ``multi_scale=True``.
        skip_random_resize: When ``multi_scale=True``, use only the largest scale
            and skip random selection among multiple scales.
        patch_size: Model patch size used by :func:`compute_multi_scale_scales` to
            ensure all candidate resolutions are compatible with the backbone.
        num_windows: Number of attention windows; used by
            :func:`compute_multi_scale_scales` to derive candidate resolutions.
        aug_config: Albumentations augmentation config dict passed to
            :class:`~rfdetr.datasets.transforms.AlbumentationsWrapper`.  Falls back to the default
            :data:`~rfdetr.datasets.aug_configs.AUG_CONFIG` when ``None``.
        gpu_postprocess: When ``True``, skip Albumentations augmentation wrappers and
            ``Normalize`` from the CPU pipeline.  The ``RFDETRDataModule`` then applies both augmentation and
            normalization on the GPU in ``on_after_batch_transfer``.  Has no effect on val/test splits.

    Returns:
        A :class:`torchvision.transforms.v2.Compose` pipeline ready to be passed to :class:`CocoDetection`.

        .. note::
            This pipeline does **not** guarantee that output ``H`` and ``W`` are divisible by ``patch_size *
            num_windows``.  Divisibility is enforced at the batch level by the DataLoader collate function.  If you
            apply these transforms outside of :class:`~rfdetr.training.module_data.RFDETRDataModule`, pass the result
            through :func:`~rfdetr.utilities.tensors.nested_tensor_from_tensor_list` with ``block_size=patch_size *
            num_windows``, or use :func:`~rfdetr.utilities.tensors.make_collate_fn` with that value.

    Raises:
        ValueError: If ``image_set`` is not one of the recognised split names.
    T©rZ   rJ   z(Using multi-scale training with scales: r   FrÏ   )rÑ   rÅ   ©Úkeypoint_flip_pairs)ÚvalÚtestrË   rÅ   rÐ   Ú	val_speedrÈ   rÉ   úunknown ©r
   r	   rl   r¯   r   r\   ÚloggerÚinfor   r   Úfrom_configr×   r   r2   ©Ú	image_setrR   Úmulti_scalerS   Úskip_random_resizerT   rU   Ú
aug_configÚgpu_postprocessrÛ   Úto_imageÚto_floatÚ	normalizerY   Úresolved_aug_configÚresize_wrappersÚpipelineÚaug_wrapperss                     r   Úmake_coco_transformsrñ   û  s¡  € ôz ‹y€HÜ”u—}‘}¨DÔ1€HÜ“€Iàˆ\€FÙä+¨J¸ÈÐU`ÓaˆÙØ˜R‘j�\ˆFÜ�‰Ð>¸v¸hÐGÔHà�GÒØ,6Ð,B™jÌ
ÐÜ/×;Ñ;Ü& v°eÀdÔKó
ˆð &�_Ð%ˆÙÜ0×<Ñ<Ø#Ð9LôˆLð ˜˜,˜Ñ'ˆHØ�X˜xÐ(Ñ(ˆÙØ˜˜Ñ#ˆHÜ�xÓ Ð à�OÑ#Ü/×;Ñ;à" Z°Ð$<Ð=Ø! J°Ð#5Ð6ðó
ˆô ÐH˜ÐH¨(ÐH°HÐH¸iÐHÓIÐIØ�KÒÜ/×;Ñ;¸hÐS]ÐhrÑHsÐ=tÐ<uÓvˆÜÐH˜ÐH¨(ÐH°HÐH¸iÐHÓIÐIä
�x 	˜{Ð+Ó
,Ð,r   c
                ó   — t        «       }
t        t        j                  d¬«      }t	        «       }|g}|r.t        ||||«      }|r|d   g}t        j                  d|› �«       | dk(  rh|�|nt        }t        j                  t        |d¬«      «      }g |¢}|st        j                  ||	¬«      }|g |¢z  }||
|gz  }|s||gz  }t        |«      S | dv r.t        j                  d	||d
œig«      }t        g |¢|
‘|‘|‘«      S t        d| › �«      ‚)aµ	  Create COCO transforms with square resizing where the output size is divisible by 64.

    This function builds a torchvision-style transform pipeline for COCO images that resizes them to square shapes
    suitable for models that require spatial dimensions divisible by 64. It supports multi-scale training and optional
    random resizing and cropping for the training split.

    When *gpu_postprocess* is ``True``, both the Albumentations augmentation wrappers and the ``Normalize`` step are
    omitted from the ``"train"`` pipeline. The ``RFDETRDataModule`` then applies augmentation and normalization on the
    device in ``on_after_batch_transfer`` instead.

    Args:
        image_set: Dataset split identifier. Expected values are "train", "val",
            "test", or "val_speed". Each split uses a slightly different transform pipeline suited for training or
            evaluation.
        resolution: Base square resolution (in pixels) to which images are resized.
        multi_scale: If True, enable multi-scale training by sampling from a set of
            square resolutions instead of a single fixed size.
        expanded_scales: If True, expand the range of scales used during
            multi-scale training. Passed through to ``compute_multi_scale_scales``.
        skip_random_resize: If True and ``multi_scale`` is enabled, use only the
            largest scale returned by ``compute_multi_scale_scales`` and skip random selection among multiple scales.
        patch_size: Patch size used by ``compute_multi_scale_scales`` when
            determining valid square resolutions (typically related to the model's patch embedding or stride).
        num_windows: Number of windows used by ``compute_multi_scale_scales`` to
            derive the list of candidate square resolutions.
        aug_config: Augmentation configuration dictionary compatible with
            :class:`~rfdetr.datasets.transforms.AlbumentationsWrapper`. If ``None``, the default
            :data:`~rfdetr.datasets.aug_configs.AUG_CONFIG` is used.
        gpu_postprocess: When ``True``, skip Albumentations augmentation wrappers and
            ``Normalize`` from the CPU pipeline.  The ``RFDETRDataModule`` then applies both augmentation and
            normalization on the GPU in ``on_after_batch_transfer``.  Has no effect on val/test splits.

    Returns:
        A ``Compose`` object containing the composed image transforms appropriate for the specified ``image_set``.
    TrÙ   rJ   z:Using multi-scale training with square resize and scales: r   )rÑ   rÚ   )rÜ   rÝ   rÞ   rÈ   rÉ   rß   rà   rä   s                     r   Ú"make_coco_transforms_square_div_64ró   c  sG  € ô^ ‹y€HÜ”u—}‘}¨DÔ1€HÜ“€Iàˆ\€FÙä+¨J¸ÈÐU`ÓaˆÙØ˜R‘j�\ˆFÜ�‰ÐPÐQWÐPXÐYÔZà�GÒØ,6Ð,B™jÌ
ÐÜ/×;Ñ;Ô<VÐW]ÐfjÔ<kÓlˆØ%�_Ð%ˆÙÜ0×<Ñ<Ø#Ð9LôˆLð ˜˜,˜Ñ'ˆHØ�X˜xÐ(Ñ(ˆÙØ˜˜Ñ#ˆHÜ�xÓ Ð àÐ0Ñ0Ü/×;Ñ;¸hÐS]ÐhrÑHsÐ=tÐ<uÓvˆÜÐH˜ÐH¨(ÐH°HÐH¸iÐHÓIÐIä
�x 	˜{Ð+Ó
,Ð,r   c                óL  — t        t        |dd «      xs |j                  «      }|j                  «       s(t        j                  d|› d�«       t        d|› d�«      ‚t        |dd«      }|rdnd}|dz  |d	z  |› d
�z  f|dz  |d	z  |› d�z  f|dz  |d	z  dz  fdœ}|| j                  d«      d      \  }}t        |dd«      }	t        |dd«      }
|}t        |dg «      }t        |dd «      }t        |dg «      xs g }t        |dd«      }t        |«      }||k7  r|dk(  rt        j                  d«       |dk7  }|	rut        j                  d| › d|› �«       t        ||t        | ||j                  |j                  |j                   |j                   |j"                  |||¬«
      |
|||¬«      }|S t        j                  d| › d|› �«       t        ||t%        | ||j                  |j                  |j                   |j                   |j"                  |||¬«
      |
|||¬«      }|S )Nr   z
COCO path ú does not existÚuse_grouppose_keypointsFÚperson_keypointsÚ	instancesÚ	train2017r   z_train2017.jsonÚval2017z_val2017.jsonÚtest2017zimage_info_test-dev2017.json©r   rÜ   rÝ   Ú_r   Úsquare_resize_div_64Úsegmentation_headr:   rè   rÛ   Úaugmentation_backendÚcpuzšaugmentation_backend='auto' resolved to 'cpu' because CUDA or kornia is unavailable; disabling GPU postprocess transforms and retaining CPU normalization.zBuilding COCO ú* dataset with square resize at resolution ©ræ   rS   rç   rT   rU   rè   ré   rÛ   ©r�   r…   r†   r:   r‘   ú dataset at resolution )r   r²   Ú	coco_pathr   rá   ÚerrorÚFileNotFoundErrorÚsplitÚ%_resolve_runtime_augmentation_backendÚwarningrâ   r‚   ró   ræ   rS   Údo_random_resize_via_paddingrT   rU   rñ   )rå   ÚargsrR   ÚrootÚhas_keypointsÚmodeÚPATHSrŽ   r�   rþ   r…   r†   r:   rè   rÛ   r   Úresolved_augmentation_backendré   Údatasets                      r   Ú
build_cocor  ³  sž  € Ü”˜˜m¨TÓ2ÒD°d·n±nÓE€DØ�;‰;Œ=Ü�‰�z $  Ð7Ô8Ü *¨T¨F°/Ð BÓCÐCô ˜DÐ";¸UÓC€MÙ!.Ñ°K€Dà˜Ñ$ d¨]Ñ&:À¸vÀ_Ð=UÑ&UÐVØ�yÑ  $¨Ñ"6¸D¸6ÀÐ9OÑ"OÐPØ˜
Ñ" D¨=Ñ$8Ð;YÑ$YÐZñ€Eð ! §¡°Ó!5°aÑ!8Ñ9Ñ€J�ä" 4Ð)?ÀÓGÐÜ˜DÐ"5°uÓ=€MØ%ÐÜ% dÐ,EÀrÓJÐÜ˜˜|¨TÓ2€JÜ%,¨TÐ3HÈ"Ó%MÒ%SÐQSÐÜ" 4Ð)?ÀÓGÐÜ$IÐJ^Ó$_Ð!Ø$Ð(<Ò<ÐA^ÐbgÒAgÜ�‰ðTô	
ð 4°uÑ<€OáÜ�‰�n Y KÐ/YÐZdÐYeÐfÔgÜØØÜ9ØØØ ×,Ñ,Ø $× 4Ñ 4Ø'+×'HÑ'HÐ#HØŸ?™?Ø ×,Ñ,Ø%Ø /Ø$7ôð (Ø/Ø$;ð  1ô+
ˆð` €Nô1 	�‰�n Y KÐ/FÀzÀlÐSÔTÜØØÜ+ØØØ ×,Ñ,Ø $× 4Ñ 4Ø'+×'HÑ'HÐ#HØŸ?™?Ø ×,Ñ,Ø%Ø /Ø$7ôð (Ø/Ø$;ð  1ô+
ˆð. €Nr   c                ó   — ddl m}  || «      S )a‚  Resolve ``augmentation_backend`` at runtime for dataset builders.

    Thin wrapper around :func:`rfdetr.datasets.kornia_transforms.resolve_augmentation_backend` kept for
    backward-compatibility with callers in ``yolo.py``.

    ``"auto"`` becomes ``"gpu"`` only when CUDA and Kornia are both available, otherwise ``"cpu"``. Explicit
    ``"cpu"``/``"gpu"`` values pass through.
    r   )Úresolve_augmentation_backend)Ú!rfdetr.datasets.kornia_transformsr  )Úbackendr  s     r   r
  r
    s   € õ Oá'¨Ó0Ð0r   c                óŠ  — t        |j                  «      }|j                  «       s(t        j	                  d|› d�«       t        d|› d�«      ‚|dz  |dz  dz  f|dz  |dz  dz  f|dz  |dz  dz  fdœ}|| j                  d«      d	      \  }}t        |d
d«      }t        |dd«      }t        |dd«      }	t        |dd«      }
t        |dd«      }t        |dd«      }t        |dd«      }t        |dd«      }t        |dg «      }t        |dg «      xs g }t        |dd«      }t        t        |dd«      «      }|dk7  }|rCt        j                  d| › d|› �«       t        ||t        | ||	|
| |||||¬«
      |||d¬«      }|S t        j                  d| › d |› �«       t        ||t        | ||	|
| |||||¬«
      |||d¬«      }|S )!z™Build a Roboflow COCO-format dataset.

    This uses Roboflow's standard directory structure (train/valid/test folders with _annotations.coco.json).
    zRoboflow dataset path rõ   r   r   ÚvalidrÝ   rü   rý   r   rþ   Frÿ   ræ   rS   r  rT   é   rU   rM   rö   r:   rÛ   rè   Nr   r  zBuilding Roboflow r  r  Tr  r  )r   r   r   rá   r  r  r	  r²   r
  râ   r‚   ró   rñ   )rå   r  rR   r  r  rŽ   r�   rþ   r…   ræ   rS   r  rT   rU   r†   r:   rÛ   rè   r  ré   r  s                        r   Úbuild_roboflow_from_cocor    sZ  € ô
 �× Ñ Ó!€DØ�;‰;Œ=Ü�‰Ð-¨d¨V°?ÐCÔDÜÐ"8¸¸¸oÐ NÓOÐOð ˜‘. $¨¡.Ð3KÑ"KÐLØ�w‘  w¡Ð1IÑ IÐJØ˜‘  v¡Ð0HÑ HÐIñ€Eð ! §¡°Ó!5°aÑ!8Ñ9Ñ€J�Ü" 4Ð)?ÀÓGÐÜ˜DÐ"5°uÓ=€MÜ˜$ ¨uÓ5€KÜ˜dÐ$5°uÓ=€OÜ#*¨4Ð1OÐQVÓ#WÐ Ü˜˜|¨RÓ0€JÜ˜$ ¨qÓ1€Kä Ð&?ÀÓGÐÜ% dÐ,EÀrÓJÐÜ%,¨TÐ3HÈ"Ó%MÒ%SÐQSÐÜ˜˜|¨TÓ2€JÜ$IÌ'ÐRVÐXnÐpuÓJvÓ$wÐ!Ø3°uÑ<€OáÜ�‰Ð(¨¨Ð3]Ð^hÐ]iÐjÔkÜØØÜ9ØØØ'Ø /Ø'CÐ#CØ%Ø'Ø%Ø /Ø$7ôð (Ø/Ø$;Ø#ô%
ˆðT €Nô+ 	�‰Ð(¨¨Ð3JÈ:È,ÐWÔXÜØØÜ+ØØØ'Ø /Ø'CÐ#CØ%Ø'Ø%Ø /Ø$7ôð (Ø/Ø$;Ø#ô%
ˆð( €Nr   )r   ro   rž   rœ   )r$   r   rž   ú	list[int])r$   r   r:   r�   rž   zdict[int, int])Fr  rM   )
rR   r   rS   rœ   rT   r   rU   r   rž   r  )rb   r   rž   rœ   )rz   z	list[Any]r{   r   r|   r   rž   r   )rY   r  rÑ   rœ   rÅ   z
int | Nonerž   zlist[dict[str, Any]])FFFr  rM   NFN)rå   ro   rR   r   ræ   rœ   rS   rœ   rç   rœ   rT   r   rU   r   rè   z dict[str, dict[str, Any]] | Noneré   rœ   rÛ   r�   rž   r   )rå   ro   r  r   rR   r   rž   r‚   )r  ro   rž   ro   ))r¢   Ú
__future__r   Úpathlibr   Útypingr   rl   Útorch.utils.dataÚtorchvisionÚPILr   r   Útorchvision.transforms.v2r   r	   r
   Úrfdetr.datasets.aug_configsr   Úrfdetr.datasets.transformsr   r   Úrfdetr.utilities.loggerr   rá   r   r)   rF   r\   rc   r€   Údatasetsr‚   Úobjectr‹   r×   rñ   ró   r  r
  r  rQ   r   r   ú<module>r*     s3  ðñõ
 #å Ý ã Û Û Ý Ý ß ?Ñ ?å 2ß GÝ .á	‹€óMó ó5ðt "ØØð	Øðàðð ðð ð	ð
 óó"bó 4%ônP�K×(Ñ(×6Ñ6ô PôfN�&ô Nðj  ñ	K=ØðK=ð ðK=ð ð	K=ð
 óK=ðb Ø!Ø$ØØØ37Ø!Ø,0ðe-Øðe-àðe-ð ðe-ð ð	e-ð
 ðe-ð ðe-ð ðe-ð 1ðe-ð ðe-ð *ðe-ð óe-ðV Ø!Ø$ØØØ37Ø!Ø,0ðM-ØðM-àðM-ð ðM-ð ð	M-ð
 ðM-ð ðM-ð ðM-ð 1ðM-ð ðM-ð *ðM-ð óM-ó`Rój1ôLr   