Ë
    ¼Ó^jÇ}  ã                  óú  — d dl mZ d dl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Zd dlZd dlm
Z d dlmZmZ d dlmZ d dlmZ d d	lmZmZ d d
lmZmZ d dl m!Z! d dl"m#Z#m$Z$m%Z% d dl&m'Z'm(Z( ed   Z)dZ*e$	 	 	 	 	 	 d3d„«       Z+e$d4d„«       Z,e$	 d5	 	 	 	 	 	 	 d6d„«       Z-e$ej\                  f	 	 	 	 	 	 	 d7d„«       Z/ eej`                  dd¬«      	 	 	 	 	 	 	 	 d8d„«       Z1e$ej\                  df	 	 	 	 	 	 	 d9d„«       Z2e$d:d„«       Z3d;d„Z4 G d„ d«      Z5 eej`                  dd¬«      ddd ejl                  d«      d  ejl                  d!«      d"dd ejl                  d#«      dd$d ejn                   ejl                  d«      d%f	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d<d&„«       Z8d=d'„Z9	 	 	 	 	 	 d>d(„Z: e	e:ejv                  ¬)«       e	e:ejx                  ¬)«       e	e:ejz                  ¬)«      d*œZ>	 	 	 	 	 	 d?d+„Z?	 	 	 	 	 	 d@d,„Z@dAd-„ZA	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dBd.„ZB	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dCd/„ZC	 	 	 	 	 	 	 	 dDd0„ZD	 	 	 	 	 	 	 	 	 	 	 	 dEd1„ZE	 	 	 	 	 	 dFd2„ZFy)Gé    )ÚannotationsN)ÚCallable)Úpartial)ÚAnyÚLiteralÚcast)Ú
TargetModeÚ
deprecated)ÚImage)Ú	ImageType)ÚColorÚunify_to_bgr)Úcalculate_optimal_text_scaleÚ	draw_text)ÚPoint)Úcv2_to_pillowÚ(ensure_cv2_image_for_standalone_functionÚimages_to_cv2)Úcreate_batchesÚfill)ÚtopÚbottomé   c                ó¨  — t        |t        t        f«      rt        j                  |«      }t        j
                  |«      j                  t        «      }|j                  «       \  }}}}t        | t        j                  «      r| ||…||…f   S t        | t        j                  «      r| j                  ||||f«      S t        dt        | «      › �«      ‚)a(  
    Crop image based on bounding box coordinates.

    Args:
        image: The image to crop.
        xyxy:
            Bounding box coordinates in `(x_min, y_min, x_max, y_max)` format.

    Returns:
        Cropped image matching input
            type.

    Examples:
        ```pycon
        >>> import numpy as np
        >>> import supervision as sv
        >>> image = np.zeros((1080, 1920, 3), dtype=np.uint8)
        >>> image.shape
        (1080, 1920, 3)
        >>> xyxy = (400, 400, 800, 800)
        >>> cropped_image = sv.crop_image(image=image, xyxy=xyxy)
        >>> cropped_image.shape
        (400, 400, 3)

        ```

        ```pycon
        >>> image = np.zeros((1920, 1080), dtype=np.uint8)
        >>> image.shape
        (1920, 1080)
        >>> xyxy = (400, 400, 800, 800)
        >>> cropped_image = sv.crop_image(image=image, xyxy=xyxy)
        >>> cropped_image.shape
        (400, 400)

        ```

    ![crop-image](https://media.roboflow.com/supervision-docs/supervision-docs-crop-image-2.png){ align=center width="1000" }
    z=`image` must be a numpy.ndarray or PIL.Image.Image. Received )Ú
isinstanceÚlistÚtupleÚnpÚarrayÚroundÚastypeÚintÚflattenÚndarrayr   ÚcropÚ	TypeErrorÚtype)ÚimageÚxyxyÚx_minÚy_minÚx_maxÚy_maxs         úb/var/www/ramen.bs-engineer-server.com/venv/lib/python3.12/site-packages/supervision/utils/image.pyÚ
crop_imager/   !   s³   € ôX �$œœu˜Ô&Ü�x‰x˜‹~ˆä�8‰8�D‹>× Ñ ¤Ó%€DØ!%§¡£Ñ€Eˆ5�%˜ä�%œŸ™Ô$Ø�U˜5�[ %¨ +Ð-Ñ.Ð.ä�%œŸ™Ô%Ø�z‰z˜5 %¨°Ð6Ó7Ð7ä
Ø
GÌÈUËÀ}ÐUóð ó    c                ó  — t        | t        j                  «      sJ ‚|dk  rt        d«      ‚| j                  d   | j                  d   }}t        ||z  «      }t        ||z  «      }t        j                  | ||ft        j                  ¬«      S )a"  
    Scale image by given factor. Scale factor > 1.0 zooms in, < 1.0 zooms out.

    Args:
        image: The image to scale.
        scale_factor: Factor by which to scale the image.

    Returns:
        Scaled image matching input
            type.

    Raises:
        ValueError: If scale factor is non-positive.

    Examples:
        ```pycon
        >>> import numpy as np
        >>> import supervision as sv
        >>> image = np.zeros((1080, 1920, 3), dtype=np.uint8)
        >>> image.shape
        (1080, 1920, 3)
        >>> scaled_image = sv.scale_image(image=image, scale_factor=0.5)
        >>> scaled_image.shape
        (540, 960, 3)

        ```

        ```pycon
        >>> image = np.zeros((1920, 1080), dtype=np.uint8)
        >>> image.shape
        (1920, 1080)
        >>> scaled_image = sv.scale_image(image=image, scale_factor=0.5)
        >>> scaled_image.shape
        (960, 540)

        ```

    ![scale-image](https://media.roboflow.com/supervision-docs/supervision-docs-scale-image-2.png){ align=center width="1000" }
    r   zScale factor must be positive.é   ©Úinterpolation)	r   r   r$   Ú
ValueErrorÚshaper"   Úcv2ÚresizeÚINTER_LINEAR)r(   Úscale_factorÚ	width_oldÚ
height_oldÚ	width_newÚ
height_news         r.   Úscale_imager?   ^   s‚   € ôR �eœRŸZ™ZÔ(Ð(Ð(Ø�qÒÜÐ9Ó:Ð:à!ŸK™K¨™N¨E¯K©K¸©Nˆz€IÜ�I Ñ,Ó-€IÜ�Z ,Ñ.Ó/€JÜ�:‰:�e˜i¨Ð4ÄC×DTÑDTÔUÐUr0   c                óR  — t        | t        j                  «      sJ ‚|r]| j                  d   | j                  d   z  }|d   |d   z  }||k\  r|d   }t	        |d   |z  «      }n|d   }t	        |d   |z  «      }n|\  }}t        j                  | ||ft
        j                  ¬«      S )aÖ  
    Resize image to specified resolution. Can optionally maintain aspect ratio.

    Args:
        image: The image to resize.
        resolution_wh: Target resolution as `(width, height)`.
        keep_aspect_ratio: Flag to maintain original aspect ratio.
            Defaults to `False`.

    Returns:
        Resized image matching input
            type.

    Examples:
        ```pycon
        >>> import numpy as np
        >>> import supervision as sv
        >>> image = np.zeros((1080, 1920, 3), dtype=np.uint8)
        >>> image.shape
        (1080, 1920, 3)
        >>> resized_image = sv.resize_image(
        ...     image=image, resolution_wh=(1000, 1000), keep_aspect_ratio=True
        ... )
        >>> resized_image.shape
        (562, 1000, 3)

        ```

        ```pycon
        >>> image = np.zeros((1920, 1080), dtype=np.uint8)
        >>> image.shape
        (1920, 1080)
        >>> resized_image = sv.resize_image(
        ...     image=image, resolution_wh=(1000, 1000), keep_aspect_ratio=True
        ... )
        >>> resized_image.shape
        (1000, 562)

        ```

    ![resize-image](https://media.roboflow.com/supervision-docs/supervision-docs-resize-image-2.png){ align=center width="1000" }
    r2   r   r3   )r   r   r$   r6   r"   r7   r8   r9   )r(   Úresolution_whÚkeep_aspect_ratioÚimage_ratioÚtarget_ratior=   r>   s          r.   Úresize_imagerE   ‘   s¶   € ô` �eœRŸZ™ZÔ(Ð(Ð(ÙØ—k‘k !‘n u§{¡{°1¡~Ñ5ˆØ$ QÑ'¨-¸Ñ*:Ñ:ˆØ˜,Ò&Ø% aÑ(ˆIÜ˜]¨1Ñ-°Ñ;Ó<‰Jà& qÑ)ˆJÜ˜M¨!Ñ,¨{Ñ:Ó;‰Ià -Ñˆ	�:ä�:‰:�e˜i¨Ð4ÄC×DTÑDTÔUÐUr0   c           	     óB  — t        | t        j                  «      sJ ‚t        |¬«      }t	        | |d¬«      }|j
                  dd \  }}|d   |z
  dz  }|d   |z
  |z
  }|d   |z
  dz  }|d   |z
  |z
  }	t        j                  |||||	t        j                  |¬«      }
|
S )	a‹  
    Resize image and pad with color to achieve desired resolution while
    maintaining aspect ratio.

    Args:
        image: The image to resize and pad. Accepts BGR arrays of shape
            ``(H, W, 3)``, BGRA arrays of shape ``(H, W, 4)``, grayscale
            arrays of shape ``(H, W)``, or a PIL ``Image``.
        resolution_wh: Target resolution as `(width, height)`.
        color: Padding color. If tuple, should be in BGR format.
            Defaults to `Color.BLACK`.

    Returns:
        Letterboxed image matching input type.

    Note:
        For BGRA inputs, the alpha channel in the padding region is set to
        0 (fully transparent). Grayscale inputs receive scalar padding
        from ``color[0]``.

    Examples:
        ```pycon
        >>> import numpy as np
        >>> import supervision as sv
        >>> image = np.zeros((1080, 1920, 3), dtype=np.uint8)
        >>> image.shape
        (1080, 1920, 3)
        >>> letterboxed_image = sv.letterbox_image(
        ...     image=image, resolution_wh=(1000, 1000)
        ... )
        >>> letterboxed_image.shape
        (1000, 1000, 3)
        >>> gray = np.zeros((4, 6), dtype=np.uint8)
        >>> sv.letterbox_image(image=gray, resolution_wh=(10, 10)).shape
        (10, 10)

        ```

    ![letterbox-image](https://media.roboflow.com/supervision-docs/supervision-docs-letterbox-image-2.png){ align=center width="1000" }
    ©ÚcolorT)r(   rA   rB   Né   r2   r   )Úvalue)	r   r   r$   r   rE   r6   r7   ÚcopyMakeBorderÚBORDER_CONSTANT)r(   rA   rH   Úresized_imager>   r=   Úpadding_topÚpadding_bottomÚpadding_leftÚpadding_rightÚimage_with_borderss              r.   Úletterbox_imagerS   Ñ   sÑ   € ô\ �eœRŸZ™ZÔ(Ð(Ð(Ü˜uÔ%€EÜ Ø =ÀDô€Mð *×/Ñ/°°Ð3Ñ€J�	Ø  Ñ# jÑ0°QÑ6€KØ" 1Ñ%¨
Ñ2°[Ñ@€NØ! !Ñ$ yÑ0°QÑ6€LØ! !Ñ$ yÑ0°<Ñ?€MÜ×+Ñ+ØØØØØÜ×ÑØôÐð Ðr0   z0.27.0z0.31.0)ÚtargetÚdeprecated_inÚ	remove_inc                óÆ  — | j                   dd \  }}|j                   dd \  }}|\  }}||z   dk  xs ||k\  }	||z   dk  xs ||k\  }
|	s|
r| S t        |d«      }t        |d«      }t        |||z   «      }t        |||z   «      }t        | d«      }t        | d«      }|t        ||z   |z
  d«      z
  }|t        ||z   |z
  d«      z
  }|j                   d   dk(  rst        j                  |||…||…f   «      \  }}}}|dd…dd…df   dz  }t        j
                  |||f«      }| ||…||…f   }|d|z
  z  ||z  z   |dd || ||…||…f<   | S |||…||…f   | ||…||…f<   | S )aÏ  
    Overlay image onto scene at specified anchor point. Handles cases where
    overlay position is partially or completely outside scene bounds.

    Args:
        image: Background scene with shape `(height, width, 3)`.
        overlay: Image to overlay with shape
            `(height, width, 3)` or `(height, width, 4)`.
        anchor: Coordinates `(x, y)` where top-left corner
            of overlay will be placed.

    Returns:
        Scene with overlay applied, shape `(height, width, 3)`.

    Examples:
        ```pycon
        >>> import numpy as np
        >>> import supervision as sv
        >>> image = np.zeros((1000, 1000, 3), dtype=np.uint8)
        >>> overlay = np.zeros((400, 400, 3), dtype=np.uint8)
        >>> overlay[:] = (0, 255, 0)  # Green overlay
        >>> result_image = sv.overlay_image(
        ...     image=image, overlay=overlay, anchor=(200, 400)
        ... )
        >>> result_image.shape
        (1000, 1000, 3)

        ```
    NrI   r   é   g     ào@r2   )r6   ÚmaxÚminr7   ÚsplitÚmerge)r(   ÚoverlayÚanchorÚscene_heightÚscene_widthÚimage_heightÚimage_widthÚanchor_xÚanchor_yÚis_out_horizontallyÚis_out_verticallyr*   r+   r,   r-   Ú
crop_x_minÚ
crop_y_minÚ
crop_x_maxÚ
crop_y_maxÚbÚgÚrÚalphaÚoverlay_colorÚrois                            r.   Úoverlay_imagerq     sô  € ðN !&§¡¨B¨Q Ñ€L�+Ø '§¡¨b¨qÐ 1Ñ€L�+ØÑ€Hˆhà" [Ñ0°AÑ5ÒP¸À[Ñ9PÐØ  <Ñ/°1Ñ4ÒP¸ÀLÑ8PÐáÑ/Øˆä�˜!Ó€EÜ�˜!Ó€EÜ�˜X¨Ñ3Ó4€EÜ�˜h¨Ñ5Ó6€Eä�h�Y Ó"€JÜ�h�Y Ó"€JØœs H¨{Ñ$:¸kÑ#IÈ1ÓMÑM€JØ¤ X°Ñ%<ÀÑ$LÈaÓ PÑP€Jà‡}�}�QÑ˜1ÒÜŸ™Ø�J˜zÐ)¨:°jÐ+@Ð@ÑAó
‰ˆˆ1ˆa�ð ’aš˜D�jÑ! EÑ)ˆÜŸ	™	 1 a¨ )Ó,ˆà�E˜%�K  u Ð,Ñ-ˆØ˜˜E™	Ñ" ]°UÑ%:Ñ:ˆ‰AˆØ*-ˆˆe�Eˆk˜5 ˜;Ð&Ñ'ð €Lð	 +2Ø�zÐ! :¨jÐ#8Ð8ñ+
ˆˆe�Eˆk˜5 ˜;Ð&Ñ'ð €Lr0   g      à?c                ó  — t        | t        j                  «      sJ ‚d|cxk  rdk  st        d«      ‚ t        d«      ‚t        j                  | |j                  «       | j                  ¬«      }t        j                  ||| d|z
  d| ¬«       | S )aw  
    Tint image with solid color overlay at specified opacity.

    Args:
        image: The image to tint.
        color: Overlay tint color. Defaults to `Color.BLACK`.
        opacity: Blend ratio between overlay and image (0.0-1.0).
            Defaults to `0.5`.

    Returns:
        Tinted image matching input
            type.

    Raises:
        ValueError: If opacity is outside range [0.0, 1.0].

    Examples:
        ```pycon
        >>> import numpy as np
        >>> import supervision as sv
        >>> image = np.zeros((100, 100, 3), dtype=np.uint8)
        >>> tinted_image = sv.tint_image(
        ...     image=image, color=sv.Color.ROBOFLOW, opacity=0.5
        ... )
        >>> tinted_image.shape
        (100, 100, 3)

        ```

    ![tint-image](https://media.roboflow.com/supervision-docs/supervision-docs-tint-image-2.png){ align=center width="1000" }
    g        g      ð?z#opacity must be between 0.0 and 1.0)Ú
fill_valueÚdtyper2   r   )Úsrc1rn   Úsrc2ÚbetaÚgammaÚdst)	r   r   r$   r5   Ú	full_likeÚas_bgrrt   r7   ÚaddWeighted)r(   rH   Úopacityr]   s       r.   Ú
tint_imager~   c  s„   € ôJ �eœRŸZ™ZÔ(Ð(Ð(Ø�'Ô ˜SÒ ÜÐ>Ó?Ð?ð !ÜÐ>Ó?Ð?ä�l‰l˜5¨U¯\©\«^À5Ç;Á;ÔO€GÜ‡O�OØ˜G¨%°a¸'±kÈÐPUõð €Lr0   c                ó’   — t        j                  | t         j                  «      }t        j                  |t         j                  «      S )aç  
    Convert image to 3-channel grayscale. Luminance channel is broadcast to
    all three channels for compatibility with color-based drawing helpers.

    Args:
        image: The image to convert to
            grayscale.

    Returns:
        3-channel grayscale image
            matching input type.

    Examples:
        ```pycon
        >>> import numpy as np
        >>> import supervision as sv
        >>> image = np.ones((100, 100, 3), dtype=np.uint8) * 128
        >>> grayscale_image = sv.grayscale_image(image=image)
        >>> grayscale_image.shape
        (100, 100, 3)

        ```

    ![grayscale-image](https://media.roboflow.com/supervision-docs/supervision-docs-grayscale-image-2.png){ align=center width="1000" }
    )r7   ÚcvtColorÚCOLOR_BGR2GRAYÚCOLOR_GRAY2BGR)r(   Ú
grayscaleds     r.   Úgrayscale_imager„   “  s1   € ô6 —‘˜e¤S×%7Ñ%7Ó8€JÜ�<‰<˜
¤C×$6Ñ$6Ó7Ð7r0   c                ó€  — t        | t        j                  «      rO| j                  dk  rt	        d| j
                  › �«      ‚| j
                  dd \  }}t        |«      t        |«      fS t        | t        j                  «      r%| j                  \  }}t        |«      t        |«      fS t        dt        | «      › �«      ‚)aÜ  
    Get image width and height as a tuple `(width, height)` for various image formats.

    Supports both `numpy.ndarray` images (with shape `(H, W, ...)`) and
    `PIL.Image.Image` inputs.

    Args:
        image: Input image.

    Returns:
        Image resolution as `(width, height)`.

    Raises:
        ValueError: If a `numpy.ndarray` image has fewer than 2 dimensions.
        TypeError: If `image` is not a supported type (`numpy.ndarray` or
            `PIL.Image.Image`).

    Examples:
        ```pycon
        >>> import numpy as np
        >>> import supervision as sv
        >>> image = np.zeros((1080, 1920, 3), dtype=np.uint8)
        >>> sv.get_image_resolution_wh(image)
        (1920, 1080)

        ```
    rI   zINumPy image must have at least 2 dimensions (H, W, ...). Received shape: NzC`image` must be a numpy.ndarray or PIL.Image.Image. Received type: )r   r   r$   Úndimr5   r6   r"   r   Úsizer&   r'   )r(   ÚheightÚwidths      r.   Úget_image_resolution_whrŠ   ²  s³   € ô8 �%œŸ™Ô$Ø�:‰:˜Š>Üð#Ø#(§;¡; -ð1óð ð Ÿ™ B Q˜‰ˆ�Ü�5‹zœ3˜v›;Ð&Ð&ä�%œŸ™Ô%ØŸ
™
‰ˆˆvÜ�5‹zœ3˜v›;Ð&Ð&ä
ð	Ü˜u›+˜ð	(óð r0   c                  óZ   — e Zd Z	 	 d	 	 	 	 	 dd„Zdd„Z	 d		 	 	 	 	 d
d„Z	 	 	 	 	 	 	 	 dd„Zy)Ú	ImageSinkc                ó<   — || _         || _        || _        d| _        y)aû  
        Initialize context manager for saving images to directory.

        Args:
            target_dir_path: Target directory path where images will be
                saved.
            overwrite: Whether to overwrite existing directory.
                Defaults to `False`.
            image_name_pattern: File name pattern for saved images.
                Defaults to `"image_{:05d}.png"`.

        Examples:
            ```pycon
            >>> import numpy as np
            >>> import supervision as sv
            >>> import tempfile
            >>> import os
            >>> with tempfile.TemporaryDirectory() as tmpdir:
            ...     image = np.zeros((100, 100, 3), dtype=np.uint8)
            ...     with sv.ImageSink(target_dir_path=tmpdir, overwrite=True) as sink:
            ...         sink.save_image(image=image)
            ...         sink.save_image(image=image)
            ...     files = sorted(os.listdir(tmpdir))
            ...     len(files)
            2

            ```
        r   N)Útarget_dir_pathÚ	overwriteÚimage_name_patternÚimage_count)ÚselfrŽ   r�   r�   s       r.   Ú__init__zImageSink.__init__â  s$   € ðD  /ˆÔØ"ˆŒØ"4ˆÔØˆÕr0   c                ó.  — t         j                  j                  | j                  «      rL| j                  r>t        j                  | j                  «       t        j                  | j                  «       | S t        j                  | j                  «       | S ©N)ÚosÚpathÚexistsrŽ   r�   ÚshutilÚrmtreeÚmakedirs)r’   s    r.   Ú	__enter__zImageSink.__enter__	  sc   € Ü�7‰7�>‰>˜$×.Ñ.Ô/Ø�~Š~Ü—‘˜d×2Ñ2Ô3Ü—‘˜D×0Ñ0Ô1ð ˆô �K‰K˜×,Ñ,Ô-àˆr0   Nc                óü   — |€%| j                   j                  | j                  «      }t        j                  j                  | j                  |«      }t        j                  ||«       | xj                  dz  c_        y)aa  
        Save image to target directory with optional custom filename.

        Args:
            image: Image to save with shape `(height, width, 3)`
                in BGR format.
            image_name: Custom filename for saved image. If
                `None`, generates name using `image_name_pattern`. Defaults to
                `None`.
        Nr2   )	r�   Úformatr‘   r–   r—   ÚjoinrŽ   r7   Úimwrite)r’   r(   Ú
image_nameÚ
image_paths       r.   Ú
save_imagezImageSink.save_image  s_   € ð ÐØ×0Ñ0×7Ñ7¸×8HÑ8HÓIˆJä—W‘W—\‘\ $×"6Ñ"6¸
ÓCˆ
Ü�‰�J Ô&Ø×Ò˜AÑÖr0   c                 ó   — y r•   © )r’   Úexc_typeÚ	exc_valueÚexc_tracebacks       r.   Ú__exit__zImageSink.__exit__'  s   € ð 	r0   )Fzimage_{:05d}.png)rŽ   Ústrr�   Úboolr�   rª   )ÚreturnrŒ   r•   )r(   únpt.NDArray[np.uint8]r¡   z
str | Noner¬   ÚNone)r¦   ztype[BaseException] | Noner§   zBaseException | Noner¨   r   r¬   r®   )Ú__name__Ú
__module__Ú__qualname__r“   rœ   r£   r©   r¥   r0   r.   rŒ   rŒ   á  s€   „ ð  Ø"4ð	%àð%ð ð%ð  ó	%óNð FJðØ*ðØ8Bðà	óð(à,ðð (ðð ð	ð
 
ôr0   rŒ   Úavgz#D9D9D9é
   z#BFBEBDÚautoz#262523r2   r   c                ó¬  — t        | «      dk(  rt        d«      ‚|dk(  rt        | ¬«      }t        |¬«      }t        |¬«      }t	        | ¬«      } |€t        | |¬«      }| D �cg c]  }t        |||¬«      ‘Œ }}t        | |¬	«      }t        | «      |d   |d
   z  kD  rt        dt        | «      › d|› d�«      ‚|�t        |t        | «      d¬«      }t        |	t        «      r|	}n|	g}t        |t        | «      d¬«      }	t        |
¬«      }
t        |¬«      }t        ||||||||	|
||||||¬«      }|dk(  rt        |¬«      }t        t        |«      S c c}w )aç  
    Creates tiles mosaic from input images, automating grid placement and
    converting images to common resolution maintaining aspect ratio. It is
    also possible to render text titles on tiles, using optional set of
    parameters specifying text drawing (see parameters description).

    Automated grid placement will try to maintain square shape of grid
    (with size being the nearest integer square root of #images), up to two exceptions:
    * if there are up to 3 images - images will be displayed in single row
    * if square-grid placement causes last row to be empty - number of rows is trimmed
        until last row has at least one image

    Args:
        images: Images to create tiles. Elements can be either np.ndarray or
            PIL.Image, and a common representation will be agreed by the
            function.
        grid_size: Expected grid size in format (n_rows, n_cols). If not
            given, automated grid placement will be applied. One may also
            provide only one out of two elements of the tuple - then grid
            will be created with either n_rows or n_cols fixed, leaving the
            other dimension to be adjusted by the number of images.
        single_tile_size: Size of a single tile element provided in
            (width, height) format. If not given, size of tile will be
            automatically calculated based on `tile_scaling`.
        tile_scaling: Strategy used to calculate tile size when
            `single_tile_size` is not given, using the min / max / avg size
            of images provided in `images`.
        tile_padding_color: Color to be used in the image letterbox procedure
            while standardizing tile sizes. If a tuple is provided, it should
            be in BGR order.
        tile_margin: Size of margin between tiles, in pixels.
        tile_margin_color: Color of the tile margin. If a tuple is provided,
            it should be in BGR order.
        return_type: Format of the returned image. One may choose a specific
            format ("cv2" or "pillow") to enforce conversion. "auto" mode
            takes a majority vote between types of elements in `images`,
            resolving draws in favour of OpenCV format. "auto" can be safely
            used when all input images are of the same type.
        titles: Optional titles to be added to tiles. Elements of that list
            may be empty - then a specific tile, in the order presented in
            `images`, will not be filled with a title. It is possible to
            provide a list of titles shorter than `images` - then remaining
            titles will be assumed empty.
        titles_anchors: Anchor points for titles. It is possible to specify
            an anchor either globally or for specific tiles, following the
            order of `images`. If not given, either globally or for a
            specific element of the list, it will be calculated
            automatically based on `default_title_placement`.
        titles_color: Color of the title text. If a tuple is provided, it
            should be in BGR order.
        titles_scale: Scale of titles. If not provided, the value will be
            calculated using `calculate_optimal_text_scale(...)`.
        titles_thickness: Thickness of title text.
        titles_padding: Size of title padding.
        titles_text_font: Font used to render titles. Must be an integer
            constant representing an OpenCV font.
            (See docs: https://docs.opencv.org/4.x/d6/d6e/group__imgproc__draw.html)
        titles_background_color: Color of the title text padding.
        default_title_placement: Title anchor placement used when an explicit
            anchor is not provided.

    Returns:
        ImageType: Image with all input images located in tiles grid. The output type is
            determined by `return_type` parameter.

    Raises:
        ValueError: In case when input images list is empty, provided `grid_size` is too
            small to fit all images, `tile_scaling` mode is invalid.
    r   z7Could not create image tiles from empty list of images.r´   ©ÚimagesrG   N©r·   Úmode)r(   rA   rH   )r·   Ú	grid_sizer2   zCould not place z in grid with size: ú.)ÚsequenceÚdesired_sizeÚcontent)r·   rº   Úsingle_tile_sizeÚtile_padding_colorÚtile_marginÚtile_margin_colorÚtitlesÚtitles_anchorsÚtitles_colorÚtitles_scaleÚtitles_thicknessÚtitles_paddingÚtitles_text_fontÚtitles_background_colorÚdefault_title_placementÚpillow)r(   )Úlenr5   Ú_negotiate_tiles_formatr   r   Ú_aggregate_images_shaperS   Ú_establish_grid_sizer   r   r   Ú_generate_tilesr   r   r   )r·   rº   r¿   Útile_scalingrÀ   rÁ   rÂ   Úreturn_typerÃ   rÄ   rÅ   rÆ   rÇ   rÈ   rÉ   rÊ   rË   ÚiÚresized_imagesÚtitles_anchors_sequenceÚtiless                        r.   Úcreate_tilesrØ   0  sœ  € ôz ˆ6ƒ{�aÒÜÐRÓSÐSØ�fÒÜ-°VÔ<ˆÜ%Ð,>Ô?ÐÜ$Ð+<Ô=ÐÜ &Ô)€FØÐÜ2¸&À|ÔTÐð
 ö	ð ô 	ØÐ#3Ð;Mö	
ð€Nð ô %¨F¸iÔH€IÜ
ˆ6ƒ{�Y˜q‘\ I¨a¡LÑ0Ò0ÜØœs 6›{˜mÐ+?À	¸{È!ÐLó
ð 	
ð ÐÜ˜v´C¸³KÈÔNˆÜ�.¤$Ô'Ø"0Ñà#1Ð"2ÐÜØ(´s¸6³{ÈDô€Nô   lÔ3€LÜ*Ð1HÔIÐÜØØØ)Ø-ØØ+ØØ%Ø!Ø!Ø)Ø%Ø)Ø 7Ø 7ô€Eð" �hÒÜ EÔ*ˆÜ”	˜5Ó!Ð!ùòSs   Á"Ec                óL   — t        d„ | D «       «      }|dz  t        | «      k\  ryy)Nc              3  ób   K  — | ]'  }t        t        |«      t        j                  «      –— Œ) y ­wr•   )Ú
issubclassr'   r   r$   )Ú.0rÔ   s     r.   ú	<genexpr>z*_negotiate_tiles_format.<locals>.<genexpr>Ã  s   è ø€ ÒNÀ!œj¬¨a«´"·*±*×=ÑNùs   ‚-/rI   r7   rÌ   )ÚsumrÍ   )r·   Únumber_of_np_arrayss     r.   rÎ   rÎ   Â  s*   € ÜÑNÀvÔNÓNÐØ˜QÑ¤# f£+Ò-ØØr0   c           	     óÎ   — t         || D �cg c]  }|j                  d   ‘Œ c}«      «      }t         || D �cg c]  }|j                  d   ‘Œ c}«      «      }||fS c c}w c c}w )Nr   r2   )r    r6   )r·   Ú
aggregatorrÔ   rˆ   r‰   s        r.   Ú"_calculate_aggregated_images_shaperâ   É  sZ   € ô ‘:°6Ö:¨a˜qŸw™w q›zÒ:Ó;Ó<€FÜ‘*°&Ö9¨Q˜aŸg™g a›jÒ9Ó:Ó;€EØ�&ˆ=Ðùò ;ùÚ9s
   ŒA¸A")rá   )rZ   rY   r²   c           	     óˆ   — |t         vr-t        d|› dt        t         j                  «       «      › d�«      ‚t        |   | «      S )Nz:Could not aggregate images shape - provided unknown mode: z. Supported modes: r»   )ÚSHAPE_AGGREGATION_FUNr5   r   Úkeysr¸   s     r.   rÏ   rÏ   Ø  sV   € ð Ô(Ñ(ÜØHÈÈð O Ü $Ô%:×%?Ñ%?Ó%AÓ BÐCÀ1ðFó
ð 	
ô ! Ñ& vÓ.Ð.r0   c                ó@  — |�t        d„ |D «       «      rt        | ¬«      S |d   €,|d   }|€J ‚t        j                  t	        | «      |z  «      |fS |d   €,|d   }|€J ‚|t        j                  t	        | «      |z  «      fS t        t        t        t        f   |«      S )Nc              3  ó$   K  — | ]  }|d u –— Œ
 y ­wr•   r¥   )rÜ   Úes     r.   rÝ   z'_establish_grid_size.<locals>.<genexpr>ç  s   è ø€ Ò=¨a  T¤	Ñ=ùs   ‚r¶   r   r2   )ÚallÚ_negotiate_grid_sizeÚmathÚceilrÍ   r   r   r"   )r·   rº   ÚcolumnsÚrowss       r.   rÐ   rÐ   ã  s¯   € ð ÐœCÑ=°9Ô=Ô=Ü#¨6Ô2Ð2Ø��|ÐØ˜A‘,ˆØÐ"Ð"Ð"Ü�y‰yœ˜V› wÑ.Ó/°Ð8Ð8Ø��|ÐØ˜‰|ˆØÐÐÐØ”T—Y‘Yœs 6›{¨TÑ1Ó2Ð2Ð2Ü””cœ3�h‘ Ó+Ð+r0   c                ó  — t        | «      t        k  rdt        | «      fS t        j                  t	        j
                  t        | «      «      «      }|}|}||dz
  z  t        | «      k\  r|dz  }||dz
  z  t        | «      k\  rŒ||fS )Nr2   )rÍ   ÚMAX_COLUMNS_FOR_SINGLE_ROW_GRIDrë   rì   r   Úsqrt)r·   Únearest_sqrtÚproposed_columnsÚproposed_rowss       r.   rê   rê   ô  s‡   € Ü
ˆ6ƒ{Ô5Ò5Ø”#�f“+ˆ~ÐÜ—9‘9œRŸW™W¤S¨£[Ó1Ó2€LØ#ÐØ €MØ
˜m¨aÑ/Ñ
0´C¸³KÒ
?Ø˜Ñˆð ˜m¨aÑ/Ñ
0´C¸³KÓ
?àÐ*Ð*Ð*r0   c                ó€  — t        | ||||	|
||||¬«
      } |\  }}t        t        | |¬«      «      }t        |d   «      |k  r1|d   j	                  t        ||¬«      «       t        |d   «      |k  rŒ1t        |«      |k  r/|j	                  t        ||¬«      g|z  «       t        |«      |k  rŒ/t        |||||¬«      S )N)
r·   rÃ   rÄ   rÅ   rÆ   rÇ   rÈ   rÉ   rÊ   rË   )r¼   Ú
batch_sizeéÿÿÿÿ©r6   rH   )Útiles_elementsrº   r¿   rÁ   rÂ   )Ú_draw_textsr   r   rÍ   ÚappendÚ_generate_color_imageÚ_merge_tiles_elements)r·   rº   r¿   rÀ   rÁ   rÂ   rÃ   rÄ   rÅ   rÆ   rÇ   rÈ   rÉ   rÊ   rË   rî   rí   rù   s                     r.   rÑ   rÑ   ÿ  sî   € ô" ØØØ%Ø!Ø!Ø)Ø%Ø)Ø 7Ø 7ô€Fð �M€Dˆ'Üœ.°&ÀWÔMÓN€NÜ
ˆn˜RÑ Ó
! GÒ
+Ø�rÑ×!Ñ!Ü!Ð(8Ð@RÔSô	
ô ˆn˜RÑ Ó
! GÓ
+ô ˆnÓ
 Ò
$Ø×ÑÜ"Ð)9ÐASÔTÐUØñô	
ô ˆnÓ
 Ó
$ô
 !Ø%ØØ)ØØ+ôð r0   c
                ób  — |€| S t        | ||	¬«      }
|€#| d   j                  d d \  }}t        ||f¬«      }g }t        | ||
«      D ]e  \  }}}|€|j	                  |«       Œt        |||t        j                  |«      ||||t        j                  |«      ¬«	      }|j	                  |«       Œg |S )N)r·   rÄ   rË   r   rI   )rA   )	ÚsceneÚtextÚtext_anchorÚ
text_colorÚ
text_scaleÚtext_thicknessÚtext_paddingÚ	text_fontÚbackground_color)Ú_prepare_default_titles_anchorsr6   r   Úziprû   r   r   Úfrom_bgr_tuple)r·   rÃ   rÄ   rÅ   rÆ   rÇ   rÈ   rÉ   rÊ   rË   Úprepared_titles_anchorsra   rb   Úresultr(   r   r^   Úprocessed_images                     r.   rú   rú   0  sá   € ð €~ØˆÜ=ØØ%Ø 7ôÐð
 ÐØ$*¨1¡I§O¡O°B°QÐ$7Ñ!ˆ�kÜ3Ø&¨Ð5ô
ˆð €FÜ" 6¨6Ð3JÓKò 'Ñˆˆt�VØˆ<Ø�M‰M˜%Ô ØÜ#ØØØÜ×+Ñ+¨LÓ9Ø#Ø+Ø'Ø&Ü"×1Ñ1Ð2IÓJô

ˆð 	�‰�oÕ&ð'ð  €Mr0   c                óø   — g }t        | |«      D ]h  \  }}|�|j                  |«       Œ|j                  d d \  }}|dk(  rt        |dz  |dz  ¬«      }nt        |dz  |dz  ¬«      }|j                  |«       Œj |S )NrI   r   gš™™™™™¹?)ÚxÚygÍÌÌÌÌÌì?)r	  rû   r6   r   )	r·   rÄ   rË   r  r(   r^   ra   rb   Údefault_anchors	            r.   r  r  \  s‘   € ð
 €FÜ˜V ^Ó4ò 	&‰ˆˆvØÐØ�M‰M˜&Ô!ØØ$)§K¡K°° OÑ!ˆ�kØ" eÒ+Ü" [°1¡_¸ÀsÑ8JÔK‰Nä" [°1¡_¸ÀsÑ8JÔKˆNØ�‰�nÕ%ð	&ð €Mr0   c                ó´  — t        j                  |d   |dft         j                  ¬«      |z  }| D �cg c]S  }t        j                  t	        t
        j                  j                  t        ||g|d   z  «      «      «      d d d¬«      ‘ŒU }}|d   j                  d   }t        j                  ||dft         j                  ¬«      |z  }	g }
|D ]$  }|
j                  |«       |
j                  |	«       Œ& t        t        j                  t         j                     t        j                  |
d d d¬«      j                  t         j                  «      «      S c c}w )Nr2   r   ©rt   r÷   )Úaxisr   )r   ÚonesÚuint8Úconcatenater   Ú	itertoolsÚchainÚfrom_iterabler	  r6   rû   r   ÚnptÚNDArrayr!   )rù   rº   r¿   rÁ   rÂ   Úvertical_paddingÚrowÚmerged_rowsÚ	row_widthÚhorizontal_paddingÚrows_with_paddingss              r.   rý   rý   o  sW  € ô 	�‰Ð! !Ñ$ k°1Ð5¼R¿X¹XÔFØ
ñ	ð ð "ö
ð ô 	�‰ÜÜ—‘×-Ñ-Ü˜Ð.Ð/°)¸A±,Ñ>Ó?óóð ˆrð	ð
 ö	
ð
€Kð 
ð ˜A‘×$Ñ$ QÑ'€Iä
�‰�˜i¨Ð+´2·8±8Ô<Ð?PÑPð ð ÐØò 6ˆØ×!Ñ! #Ô&Ø×!Ñ!Ð"4Õ5ð6ô Ü�‰”B—H‘HÑÜ
�‰Ø˜s Ð#Øô	
÷ ‰&”—‘Ó
óð ùò'
s   ³AEc           
     óº   — t        t        j                  t        j                     t        j
                  g | d d d…   ¢d‘­t        j                  ¬«      |z  «      S )Nr÷   r   r  )r   r  r  r   r  r  rø   s     r.   rü   rü   –  sK   € ô Ü�‰”B—H‘HÑÜ
�‰Ð!�%™˜"˜‘+Ð!˜qÑ!¬¯©Ô2°UÑ:óð r0   )r(   r   r)   z8npt.NDArray[int] | list[int] | tuple[int, int, int, int]r¬   r   )r(   r   r:   Úfloatr¬   r   )F)r(   r   rA   útuple[int, int]rB   r«   r¬   r   )r(   r   rA   r%  rH   útuple[int, int, int] | Colorr¬   r   )r(   r­   r]   r­   r^   r%  r¬   r­   )r(   r   rH   r   r}   r$  r¬   r   )r(   r   r¬   r   )r(   r   r¬   r%  )$r·   úlist[ImageType]rº   ú$tuple[int | None, int | None] | Noner¿   ztuple[int, int] | NonerÒ   úLiteral['min', 'max', 'avg']rÀ   r&  rÁ   r"   rÂ   r&  rÓ   z Literal['auto', 'cv2', 'pillow']rÃ   úlist[str | None] | NonerÄ   z!Point | list[Point | None] | NonerÅ   r&  rÆ   úfloat | NonerÇ   r"   rÈ   r"   rÉ   r"   rÊ   r&  rË   ÚRelativePositionr¬   r   )r·   r'  r¬   zLiteral['cv2', 'pillow'])r·   úlist[npt.NDArray[np.uint8]]rá   zCallable[[list[int]], float]r¬   r%  )r·   r-  r¹   r)  r¬   r%  )r·   r-  rº   r(  r¬   r%  )r·   r-  r¬   r%  ) r·   r-  rº   r%  r¿   r%  rÀ   útuple[int, int, int]rÁ   r"   rÂ   r.  rÃ   r*  rÄ   úlist[Point | None]rÅ   r.  rÆ   r+  rÇ   r"   rÈ   r"   rÉ   r"   rÊ   r.  rË   r,  r¬   r­   )r·   r-  rÃ   r*  rÄ   r/  rÅ   r.  rÆ   r+  rÇ   r"   rÈ   r"   rÉ   r"   rÊ   r.  rË   r,  r¬   r-  )r·   r-  rÄ   r/  rË   r,  r¬   zlist[Point])rù   z!list[list[npt.NDArray[np.uint8]]]rº   r%  r¿   r%  rÁ   r"   rÂ   r.  r¬   r­   )r6   r%  rH   r.  r¬   r­   )GÚ
__future__r   r  rë   r–   r™   Úcollections.abcr   Ú	functoolsr   Útypingr   r   r   r7   Únumpyr   Únumpy.typingr  Ú	deprecater	   r
   ÚPILr   Úsupervision.draw.baser   Úsupervision.draw.colorr   r   Úsupervision.draw.utilsr   r   Úsupervision.geometry.corer   Úsupervision.utils.conversionr   r   r   Úsupervision.utils.iterablesr   r   r,  rð   r/   r?   rE   ÚBLACKrS   ÚNOTIFYrq   r~   r„   rŠ   rŒ   Úfrom_hexÚFONT_HERSHEY_SIMPLEXrØ   rÎ   râ   rZ   rY   Úaveragerä   rÏ   rÐ   rê   rÑ   rú   r  rý   rü   r¥   r0   r.   ú<module>rC     sm  ðÝ "ã Û Û 	Û Ý $Ý ß %Ñ %ã 
Û Ý ß ,Ý å +ß 6ß JÝ +÷ñ ÷
 =à˜?Ñ+Ð à"#Ð ð *ð9Øð9à
Bð9ð ò9ó *ð9ðx *ò/Vó *ð/Vðd *ð $ð<VØð<Và"ð<Vð ð<Vð ò	<Vó *ð<Vð~ *ð +0¯+©+ðAØðAà"ðAð (ðAð ò	Aó *ðAñH Ø×ÑØØôð
EØ ðEà"ðEð ðEð ò	Eóð
EðP *ð —;‘;Øð,Øð,àð,ð ð,ð ò	,ó *ð,ð^ *ò8ó *ð8ó<,÷^Lñ Lñ^ Ø×ÑØØôð 7;Ø/3Ø16Ø7E°u·~±~ÀiÓ7PØØ6D°e·n±nÀYÓ6OØ4:Ø&*Ø8<Ø1?°·±À	Ó1JØ!%ØØØ×4Ñ4Ø<J¸E¿N¹NÈ9Ó<UØ05ð#J"ØðJ"à3ðJ"ð -ðJ"ð /ð	J"ð
 5ðJ"ð ðJ"ð 4ðJ"ð 2ðJ"ð $ðJ"ð 6ðJ"ð /ðJ"ð ðJ"ð ðJ"ð ðJ"ð ðJ"ð  :ð!J"ð" .ð#J"ð$ ò%J"óð
J"óZðØ'ðØ5Qðàóñ Ð5À"Ç&Á&ÔIÙÐ5À"Ç&Á&ÔIÙÐ5À"Ç*Á*ÔMñÐ ð/Ø'ð/Ø/Kð/àó/ð,Ø'ð,à3ð,ð ó,ó"+ð.Ø'ð.àð.ð &ð.ð -ð	.ð
 ð.ð ,ð.ð $ð.ð 'ð.ð 'ð.ð ð.ð ð.ð ð.ð ð.ð 2ð.ð .ð.ð  ó!.ðb)Ø'ð)à#ð)ð 'ð)ð 'ð	)ð
 ð)ð ð)ð ð)ð ð)ð 2ð)ð .ð)ð !ó)ðXØ'ðà&ðð .ðð ó	ð&$Ø5ð$àð$ð &ð$ð ð	$ð
 ,ð$ð ó$ðNØðØ#7ðàôr0   