






"""simple docstring"""






from copy import deepcopy
from typing import Optional, Union

import numpy as np

from ...processing_utils import ProcessorMixin
from ...tokenization_utils_base import BatchEncoding
from ...utils import TensorType, is_tf_available, is_torch_available


if is_torch_available():
  import torch

if is_tf_available():
  import tensorflow as tf




class 							lowerCAmelCase__				(			UpperCAmelCase__ ):






      '''simple docstring'''

      __UpperCamelCase	 =  ["image_processor"]
      __UpperCamelCase	 =  "SamImageProcessor"
      def __init__(						self     :  List[str]						,	lowercase_     :  Tuple):




          '''simple docstring'''


          super().__init__(lowercase_)
          SCREAMING_SNAKE_CASE_      :  Optional[Any]    						=		self.image_processor
          SCREAMING_SNAKE_CASE_      :  Optional[Any]    						=		-10
          SCREAMING_SNAKE_CASE_      :  int    						=		self.image_processor.size['''longest_edge''']
      def __call__(						self     :  Tuple						,	lowercase_     :  Optional[Any]=None						,	lowercase_     :  Optional[Any]=None						,	lowercase_     :  Any=None						,	lowercase_     :  Optional[Any]=None						,	lowercase_     :  Optional[Union[str, TensorType]] = None						,	**lowercase_     :  List[str]						,	):




          '''simple docstring'''


          SCREAMING_SNAKE_CASE_      :  List[str]    						=		self.image_processor(
              lowercase_						,	return_tensors=lowercase_						,	**lowercase_						,	)

          # pop arguments that are not used in the foward but used nevertheless
          SCREAMING_SNAKE_CASE_      :  Optional[Any]    						=		encoding_image_processor['''original_sizes''']

          if hasattr(lowercase_						,	'''numpy'''):  # Checks if Torch or TF tensor
              SCREAMING_SNAKE_CASE_      :  List[Any]    						=		original_sizes.numpy()

          SCREAMING_SNAKE_CASE_						,			SCREAMING_SNAKE_CASE_						,			SCREAMING_SNAKE_CASE_      :  Dict    						=		self._check_and_preprocess_points(
              input_points=lowercase_						,	input_labels=lowercase_						,	input_boxes=lowercase_						,	)

          SCREAMING_SNAKE_CASE_      :  Any    						=		self._normalize_and_convert(
              lowercase_						,	lowercase_						,	input_points=lowercase_						,	input_labels=lowercase_						,	input_boxes=lowercase_						,	return_tensors=lowercase_						,	)

          return encoding_image_processor
      def _SCREAMING_SNAKE_CASE (						self     :  Tuple						,	lowercase_     :  Optional[Any]						,	lowercase_     :  int						,	lowercase_     :  Tuple=None						,	lowercase_     :  List[str]=None						,	lowercase_     :  Union[str, Any]=None						,	lowercase_     :  str="pt"						,	):




          '''simple docstring'''


          if input_points is not None:
              if len(lowercase_) != len(lowercase_):
                  SCREAMING_SNAKE_CASE_      :  List[str]    						=		[
                      self._normalize_coordinates(self.target_size						,	lowercase_						,	original_sizes[0]) for point in input_points
                  ]
              else:
                  SCREAMING_SNAKE_CASE_      :  Any    						=		[
                      self._normalize_coordinates(self.target_size						,	lowercase_						,	lowercase_)
                      for point, original_size in zip(lowercase_						,	lowercase_)
                  ]
              # check that all arrays have the same shape
              if not all(point.shape == input_points[0].shape for point in input_points):
                  if input_labels is not None:
                      SCREAMING_SNAKE_CASE_						,			SCREAMING_SNAKE_CASE_      :  List[Any]    						=		self._pad_points_and_labels(lowercase_						,	lowercase_)

              SCREAMING_SNAKE_CASE_      :  Tuple    						=		np.array(lowercase_)

          if input_labels is not None:
              SCREAMING_SNAKE_CASE_      :  int    						=		np.array(lowercase_)

          if input_boxes is not None:
              if len(lowercase_) != len(lowercase_):
                  SCREAMING_SNAKE_CASE_      :  Any    						=		[
                      self._normalize_coordinates(self.target_size						,	lowercase_						,	original_sizes[0]						,	is_bounding_box=lowercase_)
                      for box in input_boxes
                  ]
              else:
                  SCREAMING_SNAKE_CASE_      :  Optional[Any]    						=		[
                      self._normalize_coordinates(self.target_size						,	lowercase_						,	lowercase_						,	is_bounding_box=lowercase_)
                      for box, original_size in zip(lowercase_						,	lowercase_)
                  ]
              SCREAMING_SNAKE_CASE_      :  Any    						=		np.array(lowercase_)

          if input_boxes is not None:
              if return_tensors == "pt":
                  SCREAMING_SNAKE_CASE_      :  int    						=		torch.from_numpy(lowercase_)
                  # boxes batch size of 1 by default
                  SCREAMING_SNAKE_CASE_      :  List[Any]    						=		input_boxes.unsqueeze(1) if len(input_boxes.shape) != 3 else input_boxes
              elif return_tensors == "tf":
                  SCREAMING_SNAKE_CASE_      :  str    						=		tf.convert_to_tensor(lowercase_)
                  # boxes batch size of 1 by default
                  SCREAMING_SNAKE_CASE_      :  List[str]    						=		tf.expand_dims(lowercase_						,	1) if len(input_boxes.shape) != 3 else input_boxes
              encoding_image_processor.update({'''input_boxes''': input_boxes})
          if input_points is not None:
              if return_tensors == "pt":
                  SCREAMING_SNAKE_CASE_      :  int    						=		torch.from_numpy(lowercase_)
                  # point batch size of 1 by default
                  SCREAMING_SNAKE_CASE_      :  Dict    						=		input_points.unsqueeze(1) if len(input_points.shape) != 4 else input_points
              elif return_tensors == "tf":
                  SCREAMING_SNAKE_CASE_      :  Union[str, Any]    						=		tf.convert_to_tensor(lowercase_)
                  # point batch size of 1 by default
                  SCREAMING_SNAKE_CASE_      :  Any    						=		tf.expand_dims(lowercase_						,	1) if len(input_points.shape) != 4 else input_points
              encoding_image_processor.update({'''input_points''': input_points})
          if input_labels is not None:
              if return_tensors == "pt":
                  SCREAMING_SNAKE_CASE_      :  Tuple    						=		torch.from_numpy(lowercase_)
                  # point batch size of 1 by default
                  SCREAMING_SNAKE_CASE_      :  Optional[int]    						=		input_labels.unsqueeze(1) if len(input_labels.shape) != 3 else input_labels
              elif return_tensors == "tf":
                  SCREAMING_SNAKE_CASE_      :  Union[str, Any]    						=		tf.convert_to_tensor(lowercase_)
                  # point batch size of 1 by default
                  SCREAMING_SNAKE_CASE_      :  Optional[int]    						=		tf.expand_dims(lowercase_						,	1) if len(input_labels.shape) != 3 else input_labels
              encoding_image_processor.update({'''input_labels''': input_labels})

          return encoding_image_processor
      def _SCREAMING_SNAKE_CASE (						self     :  Dict						,	lowercase_     :  Optional[Any]						,	lowercase_     :  List[str]):




          '''simple docstring'''


          SCREAMING_SNAKE_CASE_      :  int    						=		max([point.shape[0] for point in input_points])
          SCREAMING_SNAKE_CASE_      :  Any    						=		[]
          for i, point in enumerate(lowercase_):
              if point.shape[0] != expected_nb_points:
                  SCREAMING_SNAKE_CASE_      :  Optional[Any]    						=		np.concatenate(
                      [point, np.zeros((expected_nb_points - point.shape[0], 2)) + self.point_pad_value]						,	axis=0)
                  SCREAMING_SNAKE_CASE_      :  Optional[Any]    						=		np.append(input_labels[i]						,	[self.point_pad_value])
              processed_input_points.append(lowercase_)
          SCREAMING_SNAKE_CASE_      :  Tuple    						=		processed_input_points
          return input_points, input_labels
      def _SCREAMING_SNAKE_CASE (						self     :  str						,	lowercase_     :  int						,	lowercase_     :  np.ndarray						,	lowercase_     :  Union[str, Any]						,	lowercase_     :  Any=False):




          '''simple docstring'''


          SCREAMING_SNAKE_CASE_						,			SCREAMING_SNAKE_CASE_      :  int    						=		original_size
          SCREAMING_SNAKE_CASE_						,			SCREAMING_SNAKE_CASE_      :  int    						=		self.image_processor._get_preprocess_shape(lowercase_						,	longest_edge=lowercase_)
          SCREAMING_SNAKE_CASE_      :  Tuple    						=		deepcopy(lowercase_).astype(lowercase_)

          if is_bounding_box:
              SCREAMING_SNAKE_CASE_      :  Dict    						=		coords.reshape(-1						,	2						,	2)

          SCREAMING_SNAKE_CASE_      :  Tuple    						=		coords[..., 0] * (new_w / old_w)
          SCREAMING_SNAKE_CASE_      :  Tuple    						=		coords[..., 1] * (new_h / old_h)

          if is_bounding_box:
              SCREAMING_SNAKE_CASE_      :  Dict    						=		coords.reshape(-1						,	4)

          return coords
      def _SCREAMING_SNAKE_CASE (						self     :  List[str]						,	lowercase_     :  Union[str, Any]=None						,	lowercase_     :  Tuple=None						,	lowercase_     :  Union[str, Any]=None						,	):




          '''simple docstring'''


          if input_points is not None:
              if hasattr(lowercase_						,	'''numpy'''):  # Checks for TF or Torch tensor
                  SCREAMING_SNAKE_CASE_      :  str    						=		input_points.numpy().tolist()

              if not isinstance(lowercase_						,	lowercase_) or not isinstance(input_points[0]						,	lowercase_):
                  raise ValueError('''Input points must be a list of list of floating points.''')
              SCREAMING_SNAKE_CASE_      :  Tuple    						=		[np.array(lowercase_) for input_point in input_points]
          else:
              SCREAMING_SNAKE_CASE_      :  Any    						=		None

          if input_labels is not None:
              if hasattr(lowercase_						,	'''numpy'''):
                  SCREAMING_SNAKE_CASE_      :  int    						=		input_labels.numpy().tolist()

              if not isinstance(lowercase_						,	lowercase_) or not isinstance(input_labels[0]						,	lowercase_):
                  raise ValueError('''Input labels must be a list of list integers.''')
              SCREAMING_SNAKE_CASE_      :  Any    						=		[np.array(lowercase_) for label in input_labels]
          else:
              SCREAMING_SNAKE_CASE_      :  Optional[Any]    						=		None

          if input_boxes is not None:
              if hasattr(lowercase_						,	'''numpy'''):
                  SCREAMING_SNAKE_CASE_      :  Any    						=		input_boxes.numpy().tolist()

              if (
                  not isinstance(lowercase_						,	lowercase_)
                  or not isinstance(input_boxes[0]						,	lowercase_)
                  or not isinstance(input_boxes[0][0]						,	lowercase_)
              ):
                  raise ValueError('''Input boxes must be a list of list of list of floating points.''')
              SCREAMING_SNAKE_CASE_      :  List[Any]    						=		[np.array(lowercase_).astype(np.floataa) for box in input_boxes]
          else:
              SCREAMING_SNAKE_CASE_      :  List[Any]    						=		None

          return input_points, input_labels, input_boxes
      @property
      def _SCREAMING_SNAKE_CASE (						self     :  int):




          '''simple docstring'''


          SCREAMING_SNAKE_CASE_      :  List[str]    						=		self.image_processor.model_input_names
          return list(dict.fromkeys(lowercase_))



      def _SCREAMING_SNAKE_CASE (						self     :  Tuple						,	*lowercase_     :  Dict						,	**lowercase_     :  Union[str, Any]):




          '''simple docstring'''


          return self.image_processor.post_process_masks(*lowercase_						,	**lowercase_)






'''simple docstring'''

from __future__ import annotations

from typing import Generic, TypeVar

a_  :				List[str]						= TypeVar("""T""")





class      snake_case    (    Generic[T]			):





  """simple docstring"""




  def __init__(    self			,  UpperCamelCase     ):







   """simple docstring"""
   lowerCamelCase_      =  data
   lowerCamelCase_      =  self
   lowerCamelCase_      =  0





class      snake_case    (    Generic[T]			):





  """simple docstring"""




  def __init__(    self     ):







   """simple docstring"""
   # map from node name to the node object
   lowerCamelCase_      =  {}






  def   snake_case		(    self			,  UpperCamelCase     ):







   """simple docstring"""
   # create a new set with x as its member
   lowerCamelCase_      =  DisjointSetTreeNode(UpperCamelCase     )






  def   snake_case		(    self			,  UpperCamelCase     ):







   """simple docstring"""
   # find the set x belongs to (with path-compression)
   lowerCamelCase_      =  self.map[data]
   if elem_ref != elem_ref.parent:
    lowerCamelCase_      =  self.find_set(elem_ref.parent.data     )
   return elem_ref.parent






  def   snake_case		(    self			,  UpperCamelCase			,  UpperCamelCase     ):







   """simple docstring"""
   # helper function for union operation
   if nodea.rank > nodea.rank:
    lowerCamelCase_      =  nodea
   else:
    lowerCamelCase_      =  nodea
    if nodea.rank == nodea.rank:
     nodea.rank += 1







  def   snake_case		(    self			,  UpperCamelCase			,  UpperCamelCase     ):







   """simple docstring"""
   # merge 2 disjoint sets
   self.link(self.find_set(UpperCamelCase     )			,  self.find_set(UpperCamelCase     )     )





class      snake_case    (    Generic[T]			):





  """simple docstring"""




  def __init__(    self     ):







   """simple docstring"""
   # connections: map from the node to the neighbouring nodes (with weights)
   lowerCamelCase_      =  {}






  def   snake_case		(    self			,  UpperCamelCase     ):







   """simple docstring"""
   # add a node ONLY if its not present in the graph
   if node not in self.connections:
    lowerCamelCase_      =  {}






  def   snake_case		(    self			,  UpperCamelCase			,  UpperCamelCase			,  UpperCamelCase     ):







   """simple docstring"""
   # add an edge with the given weight
   self.add_node(UpperCamelCase     )
   self.add_node(UpperCamelCase     )
   lowerCamelCase_      =  weight
   lowerCamelCase_      =  weight







  def   snake_case		(    self     ):







   """simple docstring"""
   lowerCamelCase_      =  []
   lowerCamelCase_      =  set()
   for start in self.connections:
    for end in self.connections[start]:
     if (start, end) not in seen:
      seen.add((end, start)     )
      edges.append((start, end, self.connections[start][end])     )
   edges.sort(key=lambda UpperCamelCase     : x[2]     )

   # creating the disjoint set
   lowerCamelCase_      =  DisjointSetTree[T]()
   for node in self.connections:
    disjoint_set.make_set(UpperCamelCase     )

   # MST generation
   lowerCamelCase_      =  0
   lowerCamelCase_      =  0
   lowerCamelCase_      =  GraphUndirectedWeighted[T]()
   while num_edges < len(self.connections     ) - 1:
    lowerCamelCase_ ,lowerCamelCase_ ,lowerCamelCase_      =  edges[index]
    index += 1
    lowerCamelCase_      =  disjoint_set.find_set(UpperCamelCase     )
    lowerCamelCase_      =  disjoint_set.find_set(UpperCamelCase     )
    if parent_u != parent_v:
     num_edges += 1
     graph.add_edge(UpperCamelCase			,  UpperCamelCase			,  UpperCamelCase     )
     disjoint_set.union(UpperCamelCase			,  UpperCamelCase     )
   return graph



