

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'''







       lowercase_						=    ['''image_processor''']
       lowercase_						=    '''SamImageProcessor'''

       def __init__(							self ,   lowercase__     ):







             '''simple docstring'''



             super().__init__(__lowerCAmelCase     )
             __A    =self.image_processor
             __A    =-1_0
             __A    =self.image_processor.size['''longest_edge''']

       def __call__(							self ,   lowercase__=None ,   lowercase__=None ,   lowercase__=None ,   lowercase__=None ,   lowercase__ = None ,   **lowercase__ ,   ):







             '''simple docstring'''



             __A    =self.image_processor(
                 __lowerCAmelCase ,   return_tensors=__lowerCAmelCase ,   **__lowerCAmelCase ,   )

             # pop arguments that are not used in the foward but used nevertheless
             __A    =encoding_image_processor['''original_sizes''']

             if hasattr(__lowerCAmelCase ,   '''numpy'''     ):  # Checks if Torch or TF tensor
                   __A    =original_sizes.numpy()

             __A    ,		__A    ,		__A    =self._check_and_preprocess_points(
                 input_points=__lowerCAmelCase ,   input_labels=__lowerCAmelCase ,   input_boxes=__lowerCAmelCase ,   )

             __A    =self._normalize_and_convert(
                 __lowerCAmelCase ,   __lowerCAmelCase ,   input_points=__lowerCAmelCase ,   input_labels=__lowerCAmelCase ,   input_boxes=__lowerCAmelCase ,   return_tensors=__lowerCAmelCase ,   )

             return encoding_image_processor

       def     __UpperCamelCase     (							self ,   lowercase__ ,   lowercase__ ,   lowercase__=None ,   lowercase__=None ,   lowercase__=None ,   lowercase__="pt" ,   ):







             '''simple docstring'''



             if input_points is not None:
                   if len(__lowerCAmelCase     ) != len(__lowerCAmelCase     ):
                         __A    =[
                             self._normalize_coordinates(self.target_size ,   __lowerCAmelCase ,   original_sizes[0]     ) for point in input_points
                         ]
                   else:
                         __A    =[
                             self._normalize_coordinates(self.target_size ,   __lowerCAmelCase ,   __lowerCAmelCase     )
                             for point, original_size in zip(__lowerCAmelCase ,   __lowerCAmelCase     )
                         ]
                   # 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:
                               __A    ,		__A    =self._pad_points_and_labels(__lowerCAmelCase ,   __lowerCAmelCase     )

                   __A    =np.array(__lowerCAmelCase     )

             if input_labels is not None:
                   __A    =np.array(__lowerCAmelCase     )

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

             if input_boxes is not None:
                   if return_tensors == "pt":
                         __A    =torch.from_numpy(__lowerCAmelCase     )
                         # boxes batch size of 1 by default
                         __A    =input_boxes.unsqueeze(1     ) if len(input_boxes.shape     ) != 3 else input_boxes
                   elif return_tensors == "tf":
                         __A    =tf.convert_to_tensor(__lowerCAmelCase     )
                         # boxes batch size of 1 by default
                         __A    =tf.expand_dims(__lowerCAmelCase ,   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":
                         __A    =torch.from_numpy(__lowerCAmelCase     )
                         # point batch size of 1 by default
                         __A    =input_points.unsqueeze(1     ) if len(input_points.shape     ) != 4 else input_points
                   elif return_tensors == "tf":
                         __A    =tf.convert_to_tensor(__lowerCAmelCase     )
                         # point batch size of 1 by default
                         __A    =tf.expand_dims(__lowerCAmelCase ,   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":
                         __A    =torch.from_numpy(__lowerCAmelCase     )
                         # point batch size of 1 by default
                         __A    =input_labels.unsqueeze(1     ) if len(input_labels.shape     ) != 3 else input_labels
                   elif return_tensors == "tf":
                         __A    =tf.convert_to_tensor(__lowerCAmelCase     )
                         # point batch size of 1 by default
                         __A    =tf.expand_dims(__lowerCAmelCase ,   1     ) if len(input_labels.shape     ) != 3 else input_labels
                   encoding_image_processor.update({'''input_labels''': input_labels}     )

             return encoding_image_processor

       def     __UpperCamelCase     (							self ,   lowercase__ ,   lowercase__     ):







             '''simple docstring'''



             __A    =max([point.shape[0] for point in input_points]     )
             __A    =[]
             for i, point in enumerate(__lowerCAmelCase     ):
                   if point.shape[0] != expected_nb_points:
                         __A    =np.concatenate(
                             [point, np.zeros((expected_nb_points - point.shape[0], 2)     ) + self.point_pad_value] ,   axis=0     )
                         __A    =np.append(input_labels[i] ,   [self.point_pad_value]     )
                   processed_input_points.append(__lowerCAmelCase     )
             __A    =processed_input_points
             return input_points, input_labels

       def     __UpperCamelCase     (							self ,   lowercase__ ,   lowercase__ ,   lowercase__ ,   lowercase__=False     ):







             '''simple docstring'''



             __A    ,		__A    =original_size
             __A    ,		__A    =self.image_processor._get_preprocess_shape(__lowerCAmelCase ,   longest_edge=__lowerCAmelCase     )
             __A    =deepcopy(__lowerCAmelCase     ).astype(__lowerCAmelCase     )

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

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

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

             return coords

       def     __UpperCamelCase     (							self ,   lowercase__=None ,   lowercase__=None ,   lowercase__=None ,   ):







             '''simple docstring'''



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

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

             if input_labels is not None:
                   if hasattr(__lowerCAmelCase ,   '''numpy'''     ):
                         __A    =input_labels.numpy().tolist()

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

             if input_boxes is not None:
                   if hasattr(__lowerCAmelCase ,   '''numpy'''     ):
                         __A    =input_boxes.numpy().tolist()

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

             return input_points, input_labels, input_boxes

       @property
       def     __UpperCamelCase     (							self     ):







             '''simple docstring'''



             __A    =self.image_processor.model_input_names
             return list(dict.fromkeys(__lowerCAmelCase     )     )


       def     __UpperCamelCase     (							self ,   *lowercase__ ,   **lowercase__     ):







             '''simple docstring'''



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








'''simple docstring'''


def 						lowerCamelCase__   (				a							):
						assert (
						    isinstance(a    ,	a							) and number_of_steps > 0
						), f'number_of_steps needs to be positive integer, your input {number_of_steps}'
						if number_of_steps == 1:
												return 1
						__snake_case ,       __snake_case						 =   1, 1
						for _ in range(number_of_steps - 1							):
												__snake_case ,       __snake_case						 =   current + previous, current
						return current


if __name__ == "__main__":
	import doctest

	doctest.testmod()

