"""simple docstring"""






import colorsys
import io

import cva
import matplotlib as mpl
import matplotlib.colors as mplc
import matplotlib.figure as mplfigure
import numpy as np
import torch
from matplotlib.backends.backend_agg import FigureCanvasAgg

from utils import img_tensorize


__A         =				1_0_0_0


class 					UpperCAmelCase		:



    """simple docstring"""

    def __init__(     self					,    _UpperCAmelCase					,    _UpperCAmelCase=1.2					,    _UpperCAmelCase="g"					,    _UpperCAmelCase=0.5					,    _UpperCAmelCase="-"					,    _UpperCAmelCase="test_out.jpg"					,    _UpperCAmelCase=True					,    _UpperCAmelCase=False					,    _UpperCAmelCase=None					,    _UpperCAmelCase=None					,    _UpperCAmelCase=0.7					,    ):
       if isinstance(_UpperCAmelCase					,    torch.Tensor							):
          lowercase__:     Union[str, Any]      =   img.numpy().astype('''np.uint8'''							)
       if isinstance(_UpperCAmelCase					,    _UpperCAmelCase							):
          lowercase__:     Tuple      =   img_tensorize(_UpperCAmelCase							)
       assert isinstance(_UpperCAmelCase					,    np.ndarray							)

       lowercase__,				lowercase__:     Tuple      =   img.shape[1], img.shape[0]
       lowercase__:     Tuple      =   mplfigure.Figure(frameon=_UpperCAmelCase							)
       lowercase__:     Union[str, Any]      =   fig.get_dpi()
       lowercase__:     str      =   (width * scale + 1e-2) / dpi
       lowercase__:     List[str]      =   (height * scale + 1e-2) / dpi
       fig.set_size_inches(_UpperCAmelCase					,    _UpperCAmelCase							)
       lowercase__:     Tuple      =   fig.add_axes([0.0, 0.0, 1.0, 1.0]							)
       ax.axis('''off'''							)
       ax.set_xlim(0.0					,    _UpperCAmelCase							)
       ax.set_ylim(_UpperCAmelCase							)

       lowercase__:     Tuple      =   saveas
       lowercase__:     List[str]      =   rgb
       lowercase__:     List[str]      =   pynb
       lowercase__:     Any      =   img
       lowercase__:     Optional[Any]      =   edgecolor
       lowercase__:     Dict      =   0.5
       lowercase__:     List[str]      =   linestyle
       lowercase__:     int      =   int(np.sqrt(min(_UpperCAmelCase					,    _UpperCAmelCase							)							) * scale // 3							)
       lowercase__:     Union[str, Any]      =   width
       lowercase__:     Optional[Any]      =   height
       lowercase__:     List[str]      =   scale
       lowercase__:     Optional[int]      =   fig
       lowercase__:     Any      =   ax
       lowercase__:     Dict      =   pad
       lowercase__:     Optional[int]      =   idaobj
       lowercase__:     Union[str, Any]      =   idaattr
       lowercase__:     Dict      =   FigureCanvasAgg(_UpperCAmelCase							)






    def _snake_case    (     self					,    _UpperCAmelCase					,    _UpperCAmelCase=None							):
       if color is None:
          lowercase__:     str      =   self.edgecolor
       ((lowercase__),				(lowercase__),				(lowercase__),				(lowercase__)):     List[Any]      =   box
       lowercase__:     int      =   xa - xa
       lowercase__:     Any      =   ya - ya
       self.ax.add_patch(
           mpl.patches.Rectangle(
               (xa, ya)					,    _UpperCAmelCase					,    _UpperCAmelCase					,    fill=_UpperCAmelCase					,    edgecolor=_UpperCAmelCase					,    linewidth=self.font_size // 3					,    alpha=self.alpha					,    linestyle=self.linestyle					,    )							)






    def _snake_case    (     self					,    _UpperCAmelCase					,    _UpperCAmelCase=None					,    _UpperCAmelCase=None					,    _UpperCAmelCase=None					,    _UpperCAmelCase=None							):
       if len(boxes.shape							) > 2:
          lowercase__:     Union[str, Any]      =   boxes[0]
       if len(obj_ids.shape							) > 1:
          lowercase__:     Dict      =   obj_ids[0]
       if len(obj_scores.shape							) > 1:
          lowercase__:     Optional[Any]      =   obj_scores[0]
       if len(attr_ids.shape							) > 1:
          lowercase__:     Dict      =   attr_ids[0]
       if len(attr_scores.shape							) > 1:
          lowercase__:     int      =   attr_scores[0]
       if isinstance(_UpperCAmelCase					,    torch.Tensor							):
          lowercase__:     Tuple      =   boxes.numpy()
       if isinstance(_UpperCAmelCase					,    _UpperCAmelCase							):
          lowercase__:     Dict      =   np.array(_UpperCAmelCase							)
       assert isinstance(_UpperCAmelCase					,    np.ndarray							)
       lowercase__:     List[str]      =   np.prod(boxes[:, 2:] - boxes[:, :2]					,    axis=1							)
       lowercase__:     Union[str, Any]      =   np.argsort(-areas							).tolist()
       lowercase__:     Tuple      =   boxes[sorted_idxs] if boxes is not None else None
       lowercase__:     Optional[Any]      =   obj_ids[sorted_idxs] if obj_ids is not None else None
       lowercase__:     Optional[int]      =   obj_scores[sorted_idxs] if obj_scores is not None else None
       lowercase__:     List[Any]      =   attr_ids[sorted_idxs] if attr_ids is not None else None
       lowercase__:     Any      =   attr_scores[sorted_idxs] if attr_scores is not None else None

       lowercase__:     Optional[Any]      =   [self._random_color(maximum=1							) for _ in range(len(_UpperCAmelCase							)							)]
       lowercase__:     List[Any]      =   [assigned_colors[idx] for idx in sorted_idxs]
       if obj_ids is not None:
          lowercase__:     List[Any]      =   self._create_text_labels_attr(_UpperCAmelCase					,    _UpperCAmelCase					,    _UpperCAmelCase					,    _UpperCAmelCase							)
          for i in range(len(_UpperCAmelCase							)							):
             lowercase__:     str      =   assigned_colors[i]
             self.add_box(boxes[i]					,    _UpperCAmelCase							)
             self.draw_labels(labels[i]					,    boxes[i]					,    _UpperCAmelCase							)






    def _snake_case    (     self					,    _UpperCAmelCase					,    _UpperCAmelCase					,    _UpperCAmelCase							):
       lowercase__,				lowercase__,				lowercase__,				lowercase__:     Any      =   box
       lowercase__:     Any      =   (xa, ya)
       lowercase__:     int      =   (ya - ya) * (xa - xa)
       lowercase__:     Tuple      =   _SMALL_OBJ * self.scale
       if instance_area < small or ya - ya < 40 * self.scale:
          if ya >= self.height - 5:
             lowercase__:     List[str]      =   (xa, ya)
          else:
             lowercase__:     Optional[int]      =   (xa, ya)

       lowercase__:     Tuple      =   (ya - ya) / np.sqrt(self.height * self.width							)
       lowercase__:     List[str]      =   self._change_color_brightness(_UpperCAmelCase					,    brightness_factor=0.7							)
       lowercase__:     Optional[Any]      =   np.clip((height_ratio - 0.02) / 0.08 + 1					,    1.2					,    2							)
       font_size *= 0.75 * self.font_size

       self.draw_text(
           text=_UpperCAmelCase					,    position=_UpperCAmelCase					,    color=_UpperCAmelCase					,    )






    def _snake_case    (     self					,    _UpperCAmelCase					,    _UpperCAmelCase					,    _UpperCAmelCase="g"					,    _UpperCAmelCase="left"					,    ):
       lowercase__:     int      =   0
       lowercase__:     str      =   self.font_size
       lowercase__:     List[str]      =   np.maximum(list(mplc.to_rgb(_UpperCAmelCase							)							)					,    0.2							)
       lowercase__:     Optional[int]      =   max(0.8					,    np.max(_UpperCAmelCase							)							)
       lowercase__:     List[Any]      =   {
           '''facecolor''': '''black''',
           '''alpha''': self.alpha,
           '''pad''': self.pad,
           '''edgecolor''': '''none''',
       }
       lowercase__,				lowercase__:     Tuple      =   position
       self.ax.text(
           _UpperCAmelCase					,    _UpperCAmelCase					,    _UpperCAmelCase					,    size=font_size * self.scale					,    family='''sans-serif'''					,    bbox=_UpperCAmelCase					,    verticalalignment='''top'''					,    horizontalalignment=_UpperCAmelCase					,    color=_UpperCAmelCase					,    zorder=10					,    rotation=_UpperCAmelCase					,    )






    def _snake_case    (     self					,    _UpperCAmelCase=None							):
       if saveas is None:
          lowercase__:     Optional[int]      =   self.saveas
       if saveas.lower().endswith('''.jpg'''							) or saveas.lower().endswith('''.png'''							):
          cva.imwrite(
              _UpperCAmelCase					,    self._get_buffer()[:, :, ::-1]					,    )
       else:
          self.fig.savefig(_UpperCAmelCase							)






    def _snake_case    (     self					,    _UpperCAmelCase					,    _UpperCAmelCase					,    _UpperCAmelCase					,    _UpperCAmelCase							):
       lowercase__:     List[Any]      =   [self.idaobj[i] for i in classes]
       lowercase__:     Union[str, Any]      =   [self.idaattr[i] for i in attr_classes]
       lowercase__:     Any      =   [
           F"""{label} {score:.2f} {attr} {attr_score:.2f}"""
           for label, score, attr, attr_score in zip(_UpperCAmelCase					,    _UpperCAmelCase					,    _UpperCAmelCase					,    _UpperCAmelCase							)
       ]
       return labels






    def _snake_case    (     self					,    _UpperCAmelCase					,    _UpperCAmelCase							):
       lowercase__:     List[str]      =   [self.idaobj[i] for i in classes]
       if scores is not None:
          if labels is None:
             lowercase__:     Union[str, Any]      =   ['''{:.0f}%'''.format(s * 100							) for s in scores]
          else:
             lowercase__:     List[str]      =   ['''{} {:.0f}%'''.format(_UpperCAmelCase					,    s * 100							) for li, s in zip(_UpperCAmelCase					,    _UpperCAmelCase							)]
       return labels






    def _snake_case    (     self					,    _UpperCAmelCase=255							):
       lowercase__:     Optional[Any]      =   np.random.randint(0					,    len(_COLORS							)							)
       lowercase__:     int      =   _COLORS[idx] * maximum
       if not self.rgb:
          lowercase__:     Optional[int]      =   ret[::-1]
       return ret






    def _snake_case    (     self							):
       if not self.pynb:
          lowercase__,				lowercase__:     str      =   self.canvas.print_to_buffer()
          if (width, height) != (self.width, self.height):
             lowercase__:     Optional[int]      =   cva.resize(self.img					,    (width, height)							)
          else:
             lowercase__:     Any      =   self.img
       else:
          lowercase__:     List[Any]      =   io.BytesIO()  # works for cairo backend
          self.canvas.print_rgba(_UpperCAmelCase							)
          lowercase__,				lowercase__:     List[Any]      =   self.width, self.height
          lowercase__:     Union[str, Any]      =   buf.getvalue()
          lowercase__:     str      =   self.img

       lowercase__:     Tuple      =   np.frombuffer(_UpperCAmelCase					,    dtype='''uint8'''							)
       lowercase__:     List[Any]      =   buffer.reshape(_UpperCAmelCase					,    _UpperCAmelCase					,    4							)
       lowercase__,				lowercase__:     Union[str, Any]      =   np.split(_UpperCAmelCase					,    [3]					,    axis=2							)

       try:
          import numexpr as ne  # fuse them with numexpr

          lowercase__:     Any      =   ne.evaluate('''img * (1 - alpha / 255.0) + rgb * (alpha / 255.0)'''							)
       except ImportError:
          lowercase__:     Any      =   alpha.astype('''float32'''							) / 255.0
          lowercase__:     Union[str, Any]      =   img * (1 - alpha) + rgb * alpha

       return visualized_image.astype('''uint8'''							)






    def _snake_case    (     self					,    _UpperCAmelCase					,    _UpperCAmelCase							):
       assert brightness_factor >= -1.0 and brightness_factor <= 1.0
       lowercase__:     Optional[Any]      =   mplc.to_rgb(_UpperCAmelCase							)
       lowercase__:     Optional[int]      =   colorsys.rgb_to_hls(*mplc.to_rgb(_UpperCAmelCase							)							)
       lowercase__:     Union[str, Any]      =   polygon_color[1] + (brightness_factor * polygon_color[1])
       lowercase__:     int      =   0.0 if modified_lightness < 0.0 else modified_lightness
       lowercase__:     List[str]      =   1.0 if modified_lightness > 1.0 else modified_lightness
       lowercase__:     Union[str, Any]      =   colorsys.hls_to_rgb(polygon_color[0]					,    _UpperCAmelCase					,    polygon_color[2]							)
       return modified_color



__A         =				(
    np.array(
        [
            0.000,
            0.447,
            0.741,
            0.850,
            0.325,
            0.098,
            0.929,
            0.694,
            0.125,
            0.494,
            0.184,
            0.556,
            0.466,
            0.674,
            0.188,
            0.301,
            0.745,
            0.933,
            0.635,
            0.078,
            0.184,
            0.300,
            0.300,
            0.300,
            0.600,
            0.600,
            0.600,
            1.000,
            0.000,
            0.000,
            1.000,
            0.500,
            0.000,
            0.749,
            0.749,
            0.000,
            0.000,
            1.000,
            0.000,
            0.000,
            0.000,
            1.000,
            0.667,
            0.000,
            1.000,
            0.333,
            0.333,
            0.000,
            0.333,
            0.667,
            0.000,
            0.333,
            1.000,
            0.000,
            0.667,
            0.333,
            0.000,
            0.667,
            0.667,
            0.000,
            0.667,
            1.000,
            0.000,
            1.000,
            0.333,
            0.000,
            1.000,
            0.667,
            0.000,
            1.000,
            1.000,
            0.000,
            0.000,
            0.333,
            0.500,
            0.000,
            0.667,
            0.500,
            0.000,
            1.000,
            0.500,
            0.333,
            0.000,
            0.500,
            0.333,
            0.333,
            0.500,
            0.333,
            0.667,
            0.500,
            0.333,
            1.000,
            0.500,
            0.667,
            0.000,
            0.500,
            0.667,
            0.333,
            0.500,
            0.667,
            0.667,
            0.500,
            0.667,
            1.000,
            0.500,
            1.000,
            0.000,
            0.500,
            1.000,
            0.333,
            0.500,
            1.000,
            0.667,
            0.500,
            1.000,
            1.000,
            0.500,
            0.000,
            0.333,
            1.000,
            0.000,
            0.667,
            1.000,
            0.000,
            1.000,
            1.000,
            0.333,
            0.000,
            1.000,
            0.333,
            0.333,
            1.000,
            0.333,
            0.667,
            1.000,
            0.333,
            1.000,
            1.000,
            0.667,
            0.000,
            1.000,
            0.667,
            0.333,
            1.000,
            0.667,
            0.667,
            1.000,
            0.667,
            1.000,
            1.000,
            1.000,
            0.000,
            1.000,
            1.000,
            0.333,
            1.000,
            1.000,
            0.667,
            1.000,
            0.333,
            0.000,
            0.000,
            0.500,
            0.000,
            0.000,
            0.667,
            0.000,
            0.000,
            0.833,
            0.000,
            0.000,
            1.000,
            0.000,
            0.000,
            0.000,
            0.167,
            0.000,
            0.000,
            0.333,
            0.000,
            0.000,
            0.500,
            0.000,
            0.000,
            0.667,
            0.000,
            0.000,
            0.833,
            0.000,
            0.000,
            1.000,
            0.000,
            0.000,
            0.000,
            0.167,
            0.000,
            0.000,
            0.333,
            0.000,
            0.000,
            0.500,
            0.000,
            0.000,
            0.667,
            0.000,
            0.000,
            0.833,
            0.000,
            0.000,
            1.000,
            0.000,
            0.000,
            0.000,
            0.143,
            0.143,
            0.143,
            0.857,
            0.857,
            0.857,
            1.000,
            1.000,
            1.000,
        ]
    )
    .astype(np.floataa)
    .reshape(-1, 3)
)

"""simple docstring"""






def SCREAMING_SNAKE_CASE__    (     __UpperCAmelCase				)						->						int:
   if not isinstance(__UpperCAmelCase ,					__UpperCAmelCase				):
      lowercase__:     Optional[int]      =   F"""Input value of [number={number}] must be an integer"""
      raise TypeError(__UpperCAmelCase				)
   if number < 1:
      raise ValueError('''Input must be a positive integer'''				)
   return number * (2 * number - 1)


if __name__ == "__main__":
       import doctest

       doctest.testmod()
