






from typing import Dict, List, Optional, Union

import numpy as np

from ...image_processing_utils import BaseImageProcessor, BatchFeature, get_size_dict
from ...image_transforms import center_crop, normalize, rescale, resize, to_channel_dimension_format
from ...image_utils import (
    IMAGENET_DEFAULT_MEAN,
    IMAGENET_DEFAULT_STD,
    ChannelDimension,
    ImageInput,
    PILImageResampling,
    get_image_size,
    make_list_of_images,
    to_numpy_array,
    valid_images,
)
from ...utils import TensorType, is_vision_available, logging


if is_vision_available():
     import PIL


UpperCAmelCase__            =	logging.get_logger(__name__)






class 	lowercase_      (			lowercase     ):






      '''simple docstring'''




      __snake_case  						=						['''pixel_values''']







      def __init__(   self   :		Optional[int]				,      __UpperCAmelCase   :		bool = True				,      __UpperCAmelCase   :		Dict[str, int] = None				,      __UpperCAmelCase   :		bool = True				,      __UpperCAmelCase   :		Dict[str, int] = None				,      __UpperCAmelCase   :		PILImageResampling = PILImageResampling.BICUBIC				,      __UpperCAmelCase   :		bool = True				,      __UpperCAmelCase   :		Union[int, float] = 1 / 255				,      __UpperCAmelCase   :		bool = True				,      __UpperCAmelCase   :		Optional[Union[float, List[float]]] = None				,      __UpperCAmelCase   :		Optional[Union[float, List[float]]] = None				,      **__UpperCAmelCase   :		Tuple				,      )					->None:




       """simple docstring"""


       super().__init__(**__UpperCAmelCase						)
       a							=   crop_size if crop_size is not None else {'''height''': 256, '''width''': 256}
       a							=   get_size_dict(__UpperCAmelCase				,      param_name='''crop_size'''						)
       a							=   size if size is not None else {'''height''': 224, '''width''': 224}
       a							=   get_size_dict(__UpperCAmelCase						)

       a							=   do_center_crop
       a							=   crop_size
       a							=   do_resize
       a							=   size
       a							=   resample
       a							=   do_rescale
       a							=   rescale_factor
       a							=   do_normalize
       a							=   image_mean if image_mean is not None else IMAGENET_DEFAULT_MEAN
       a							=   image_std if image_std is not None else IMAGENET_DEFAULT_STD







      def    __lowerCAmelCase      (   self   :		Optional[Any]				,      __UpperCAmelCase   :		np.ndarray				,      __UpperCAmelCase   :		Dict[str, int]				,      __UpperCAmelCase   :		Optional[int] = None				,      __UpperCAmelCase   :		Optional[Union[str, ChannelDimension]] = None				,      **__UpperCAmelCase   :		Optional[int]				,      )					->np.ndarray:




       """simple docstring"""


       a							=   self.size if size is None else size
       a							=   get_size_dict(__UpperCAmelCase						)
       a							=   get_size_dict(__UpperCAmelCase				,      param_name='''crop_size'''						)

       a						,  a							=   get_image_size(__UpperCAmelCase						)
       a							=   min(__UpperCAmelCase				,      __UpperCAmelCase						)
       a							=   (size['''height'''] / crop_size['''height''']) * min_dim
       a							=   (size['''width'''] / crop_size['''width''']) * min_dim
       return center_crop(__UpperCAmelCase				,      size=(cropped_height, cropped_width)				,      data_format=__UpperCAmelCase				,      **__UpperCAmelCase						)







      def    __lowerCAmelCase      (   self   :		Dict				,      __UpperCAmelCase   :		np.ndarray				,      __UpperCAmelCase   :		Dict[str, int]				,      __UpperCAmelCase   :		PILImageResampling = PIL.Image.BICUBIC				,      __UpperCAmelCase   :		Optional[Union[str, ChannelDimension]] = None				,      **__UpperCAmelCase   :		List[Any]				,      )					->np.ndarray:




       """simple docstring"""


       a							=   get_size_dict(__UpperCAmelCase						)
       if "height" not in size or "width" not in size:
        raise ValueError(F"""The size dictionary must contain the keys 'height' and 'width'. Got {size.keys()}"""						)
       return resize(
           __UpperCAmelCase				,      size=(size['''height'''], size['''width'''])				,      resample=__UpperCAmelCase				,      data_format=__UpperCAmelCase				,      **__UpperCAmelCase						)







      def    __lowerCAmelCase      (   self   :		Optional[int]				,      __UpperCAmelCase   :		np.ndarray				,      __UpperCAmelCase   :		Union[int, float]				,      __UpperCAmelCase   :		Optional[Union[str, ChannelDimension]] = None				,      **__UpperCAmelCase   :		int				,      )					->Optional[Any]:




       """simple docstring"""


       return rescale(__UpperCAmelCase				,      scale=__UpperCAmelCase				,      data_format=__UpperCAmelCase				,      **__UpperCAmelCase						)







      def    __lowerCAmelCase      (   self   :		List[str]				,      __UpperCAmelCase   :		np.ndarray				,      __UpperCAmelCase   :		Union[float, List[float]]				,      __UpperCAmelCase   :		Union[float, List[float]]				,      __UpperCAmelCase   :		Optional[Union[str, ChannelDimension]] = None				,      **__UpperCAmelCase   :		Tuple				,      )					->np.ndarray:




       """simple docstring"""


       return normalize(__UpperCAmelCase				,      mean=__UpperCAmelCase				,      std=__UpperCAmelCase				,      data_format=__UpperCAmelCase				,      **__UpperCAmelCase						)







      def    __lowerCAmelCase      (   self   :		str				,      __UpperCAmelCase   :		ImageInput				,      __UpperCAmelCase   :		Optional[bool] = None				,      __UpperCAmelCase   :		Optional[Dict[str, int]] = None				,      __UpperCAmelCase   :		Optional[bool] = None				,      __UpperCAmelCase   :		Optional[Dict[str, int]] = None				,      __UpperCAmelCase   :		PILImageResampling = None				,      __UpperCAmelCase   :		Optional[bool] = None				,      __UpperCAmelCase   :		Optional[float] = None				,      __UpperCAmelCase   :		Optional[bool] = None				,      __UpperCAmelCase   :		Optional[Union[float, List[float]]] = None				,      __UpperCAmelCase   :		Optional[Union[float, List[float]]] = None				,      __UpperCAmelCase   :		Optional[Union[str, TensorType]] = None				,      __UpperCAmelCase   :		ChannelDimension = ChannelDimension.FIRST				,      **__UpperCAmelCase   :		List[Any]				,      )					->PIL.Image.Image:




       """simple docstring"""


       a							=   do_center_crop if do_center_crop is not None else self.do_center_crop
       a							=   crop_size if crop_size is not None else self.crop_size
       a							=   get_size_dict(__UpperCAmelCase				,      param_name='''crop_size'''						)
       a							=   do_resize if do_resize is not None else self.do_resize
       a							=   size if size is not None else self.size
       a							=   get_size_dict(__UpperCAmelCase						)
       a							=   resample if resample is not None else self.resample
       a							=   do_rescale if do_rescale is not None else self.do_rescale
       a							=   rescale_factor if rescale_factor is not None else self.rescale_factor
       a							=   do_normalize if do_normalize is not None else self.do_normalize
       a							=   image_mean if image_mean is not None else self.image_mean
       a							=   image_std if image_std is not None else self.image_std

       a							=   make_list_of_images(__UpperCAmelCase						)

       if not valid_images(__UpperCAmelCase						):
        raise ValueError(
            '''Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, '''
            '''torch.Tensor, tf.Tensor or jax.ndarray.'''						)

       if do_center_crop and crop_size is None:
        raise ValueError('''If `do_center_crop` is set to `True`, `crop_size` must be provided.'''						)

       if do_resize and size is None:
        raise ValueError('''Size must be specified if do_resize is True.'''						)

       if do_rescale and rescale_factor is None:
        raise ValueError('''Rescale factor must be specified if do_rescale is True.'''						)

       if do_normalize and (image_mean is None or image_std is None):
        raise ValueError('''Image mean and image standard deviation must be specified if do_normalize is True.'''						)

       # All transformations expect numpy arrays.
       a							=   [to_numpy_array(__UpperCAmelCase						) for image in images]

       if do_center_crop:
        a							=   [self.center_crop(__UpperCAmelCase				,      __UpperCAmelCase				,      size=__UpperCAmelCase						) for image in images]

       if do_resize:
        a							=   [self.resize(image=__UpperCAmelCase				,      size=__UpperCAmelCase				,      resample=__UpperCAmelCase						) for image in images]

       if do_rescale:
        a							=   [self.rescale(image=__UpperCAmelCase				,      scale=__UpperCAmelCase						) for image in images]

       if do_normalize:
        a							=   [self.normalize(image=__UpperCAmelCase				,      mean=__UpperCAmelCase				,      std=__UpperCAmelCase						) for image in images]

       a							=   [to_channel_dimension_format(__UpperCAmelCase				,      __UpperCAmelCase						) for image in images]

       a							=   {'''pixel_values''': images}
       return BatchFeature(data=__UpperCAmelCase				,      tensor_type=__UpperCAmelCase						)










import enum
import inspect
from typing import Iterable, List, Optional, Tuple, Union






class 	lowercase_      (			enum.Enum     ):






      '''simple docstring'''




      __snake_case  						=						'''timm'''
      __snake_case  						=						'''transformers'''
def 		_a					(   a				:Optional[Iterable[str]]			,							a				:Optional[Iterable[int]]			,							a				:Optional[Iterable[str]]				)							->    Optional[Any]:
 if stage_names is None:
  raise ValueError('''Stage_names must be set for transformers backbones'''				)

 if out_features is not None:
  if not isinstance(a			,							(list,)				):
   raise ValueError(F"""out_features must be a list {type(a				)}"""				)
  if any(feat not in stage_names for feat in out_features				):
   raise ValueError(F"""out_features must be a subset of stage_names: {stage_names} got {out_features}"""				)

 if out_indices is not None:
  if not isinstance(a			,							(list, tuple)				):
   raise ValueError(F"""out_indices must be a list or tuple, got {type(a				)}"""				)
  if any(idx >= len(a				) for idx in out_indices				):
   raise ValueError('''out_indices must be valid indices for stage_names {stage_names}, got {out_indices}'''				)

 if out_features is not None and out_indices is not None:
  if len(a				) != len(a				):
   raise ValueError('''out_features and out_indices should have the same length if both are set'''				)
  if out_features != [stage_names[idx] for idx in out_indices]:
   raise ValueError('''out_features and out_indices should correspond to the same stages if both are set'''				)
def 		_a					(   a				:Optional[List[str]]			,							a				:Optional[Union[List[int], Tuple[int]]]			,							a				:List[str]			,							)							->    Union[str, Any]:
 if out_indices is None and out_features is None:
  a							=   [len(a				) - 1]
  a							=   [stage_names[-1]]
 elif out_indices is None and out_features is not None:
  a							=   [stage_names.index(a				) for layer in out_features]
 elif out_features is None and out_indices is not None:
  a							=   [stage_names[idx] for idx in out_indices]
 return out_features, out_indices
def 		_a					(   a				:Optional[List[str]]			,							a				:Optional[Union[List[int], Tuple[int]]]			,							a				:List[str]			,							)							->    Tuple[List[str], List[int]]:
 verify_out_features_out_indices(out_features=a			,							out_indices=a			,							stage_names=a				)
 a						,  a							=   _align_output_features_output_indices(
     out_features=a			,							out_indices=a			,							stage_names=a				)
 # Verify that the aligned out_features and out_indices are valid
 verify_out_features_out_indices(out_features=a			,							out_indices=a			,							stage_names=a				)
 return output_features, output_indices






class 	lowercase_      :






      '''simple docstring'''




      __snake_case  						=						None







      def    __lowerCAmelCase      (   self   :		Any				,      __UpperCAmelCase   :		Tuple						)					->None:




       """simple docstring"""


       if getattr(self				,      '''_backbone'''				,      __UpperCAmelCase						) is None:
        raise ValueError('''self._backbone must be set before calling _init_timm_backbone'''						)

       # These will diagree with the defaults for the transformers models e.g. for resnet50
       # the transformer model has out_features = ['stem', 'stage1', 'stage2', 'stage3', 'stage4']
       # the timm model has out_features = ['act', 'layer1', 'layer2', 'layer3', 'layer4']
       a							=   [stage['''module'''] for stage in self._backbone.feature_info.info]
       a							=   [stage['''num_chs'''] for stage in self._backbone.feature_info.info]
       a							=   self._backbone.feature_info.out_indices
       a							=   self._backbone.feature_info.module_name()

       # We verify the out indices and out features are valid
       verify_out_features_out_indices(
           out_features=__UpperCAmelCase				,      out_indices=__UpperCAmelCase				,      stage_names=self.stage_names						)
       a						,  a							=   out_features, out_indices







      def    __lowerCAmelCase      (   self   :		Any				,      __UpperCAmelCase   :		Tuple						)					->None:




       """simple docstring"""


       a							=   getattr(__UpperCAmelCase				,      '''stage_names'''						)
       a							=   getattr(__UpperCAmelCase				,      '''out_features'''				,      __UpperCAmelCase						)
       a							=   getattr(__UpperCAmelCase				,      '''out_indices'''				,      __UpperCAmelCase						)

       a							=   stage_names
       a						,  a							=   get_aligned_output_features_output_indices(
           out_features=__UpperCAmelCase				,      out_indices=__UpperCAmelCase				,      stage_names=__UpperCAmelCase						)
       # Number of channels for each stage. This is set in the transformer backbone model init
       a							=   None







      def    __lowerCAmelCase      (   self   :		str				,      __UpperCAmelCase   :		Union[str, Any]						)					->None:




       """simple docstring"""


       a							=   config

       a							=   getattr(__UpperCAmelCase				,      '''use_timm_backbone'''				,      __UpperCAmelCase						)
       a							=   BackboneType.TIMM if self.use_timm_backbone else BackboneType.TRANSFORMERS

       if self.backbone_type == BackboneType.TIMM:
        self._init_timm_backbone(__UpperCAmelCase						)
       elif self.backbone_type == BackboneType.TRANSFORMERS:
        self._init_transformers_backbone(__UpperCAmelCase						)
       else:
        raise ValueError(F"""backbone_type {self.backbone_type} not supported."""						)







      @property
      def    __lowerCAmelCase      (   self   :		Dict						)					->Optional[Any]:




       """simple docstring"""


       return self._out_features







      @out_features.setter
      def    __lowerCAmelCase      (   self   :		Tuple				,      __UpperCAmelCase   :		List[str]						)					->List[Any]:




       """simple docstring"""


       a						,  a							=   get_aligned_output_features_output_indices(
           out_features=__UpperCAmelCase				,      out_indices=__UpperCAmelCase				,      stage_names=self.stage_names						)







      @property
      def    __lowerCAmelCase      (   self   :		Dict						)					->int:




       """simple docstring"""


       return self._out_indices







      @out_indices.setter
      def    __lowerCAmelCase      (   self   :		Tuple				,      __UpperCAmelCase   :		Union[Tuple[int], List[int]]						)					->List[str]:




       """simple docstring"""


       a						,  a							=   get_aligned_output_features_output_indices(
           out_features=__UpperCAmelCase				,      out_indices=__UpperCAmelCase				,      stage_names=self.stage_names						)







      @property
      def    __lowerCAmelCase      (   self   :		Tuple						)					->str:




       """simple docstring"""


       return {stage: self.num_features[i] for i, stage in enumerate(self.stage_names						)}







      @property
      def    __lowerCAmelCase      (   self   :		int						)					->Optional[int]:




       """simple docstring"""


       return [self.out_feature_channels[name] for name in self.out_features]







      def    __lowerCAmelCase      (   self   :		Optional[Any]				,      *__UpperCAmelCase   :		List[str]				,      **__UpperCAmelCase   :		Optional[Any]						)					->Optional[int]:




       """simple docstring"""


       a							=   dict(inspect.signature(self.forward						).parameters						)
       a							=   {k: v for k, v in kwargs.items() if k in signature}
       return self(*__UpperCAmelCase				,      **__UpperCAmelCase						)







      def    __lowerCAmelCase      (   self   :		List[str]				,      __UpperCAmelCase   :		Dict				,      __UpperCAmelCase   :		Optional[bool] = None				,      __UpperCAmelCase   :		Optional[bool] = None				,      __UpperCAmelCase   :		Optional[bool] = None				,      )					->int:




       """simple docstring"""


       raise NotImplementedError('''This method should be implemented by the derived class.'''						)







      def    __lowerCAmelCase      (   self   :		Union[str, Any]						)					->Optional[Any]:




       """simple docstring"""


       a							=   super().to_dict()
       a							=   output.pop('''_out_features'''						)
       a							=   output.pop('''_out_indices'''						)
       return output






class 	lowercase_      :






      '''simple docstring'''




      @property
      def    __lowerCAmelCase      (   self   :		List[str]						)					->Optional[int]:




       """simple docstring"""


       return self._out_features







      @out_features.setter
      def    __lowerCAmelCase      (   self   :		int				,      __UpperCAmelCase   :		List[str]						)					->int:




       """simple docstring"""


       a						,  a							=   get_aligned_output_features_output_indices(
           out_features=__UpperCAmelCase				,      out_indices=__UpperCAmelCase				,      stage_names=self.stage_names						)







      @property
      def    __lowerCAmelCase      (   self   :		str						)					->str:




       """simple docstring"""


       return self._out_indices







      @out_indices.setter
      def    __lowerCAmelCase      (   self   :		str				,      __UpperCAmelCase   :		Union[Tuple[int], List[int]]						)					->int:




       """simple docstring"""


       a						,  a							=   get_aligned_output_features_output_indices(
           out_features=__UpperCAmelCase				,      out_indices=__UpperCAmelCase				,      stage_names=self.stage_names						)







      def    __lowerCAmelCase      (   self   :		Dict						)					->List[Any]:




       """simple docstring"""


       a							=   super().to_dict()
       a							=   output.pop('''_out_features'''						)
       a							=   output.pop('''_out_indices'''						)
       return output


