class_docstr: Implements an abstract preprocessor object which performs casting, resizing, batching and normalization.
  
  Args:
  ----
      output_size: expected size of each page in format (H, W)
      batch_size: the size of page batches
      mean: mean value of the training distribution by channel
      std: standard deviation of the training distribution by channel
class_docstr_tok: ["Implements","an","abstract","preprocessor","object","which","performs","casting",",","resizing",",","batching","and","normalization",".","Args",":","--","--","output_size",":","expected","size","of","each","page","in","format","(","H",",","W",")","batch_size",":","the","size","of","page","batches","mean",":","mean","value","of","the","training","distribution","by","channel","std",":","standard","deviation","of","the","training","distribution","by","channel"]
docstr: Prepare document data for model forwarding
  
  Args:
  ----
      x: list of images (np.array) or tensors (already resized and batched)
  
  Returns:
  -------
      list of page batches
docstr_tok: ["Prepare","document","data","for","model","forwarding","Args",":","--","--","x",":","list","of","images","(","np.array",")","or","tensors","(","already","resized","and","batched",")","Returns",":","--","--","--","-","list","of","page","batches"]
code: def __call__(
      self,
      x: Union[
          tf.Tensor, np.ndarray, List[Union[tf.Tensor, np.ndarray]]
      ],
  ) -> List[tf.Tensor]:
      """Prepare document data for model forwarding
  
      Args:
      ----
          x: list of images (np.array) or tensors (already resized and batched)
  
      Returns:
      -------
          list of page batches
      """
      # Input type check
      if isinstance(x, (np.ndarray, tf.Tensor)):
          if x.ndim != 4:
              raise AssertionError("expected 4D Tensor")
          if isinstance(x, np.ndarray):
              if x.dtype not in (np.uint8, np.float32):
                  raise TypeError(
                      "unsupported data type for numpy.ndarray"
                  )
              x = tf.convert_to_tensor(x)
          elif x.dtype not in (tf.uint8, tf.float16, tf.float32):
              raise TypeError("unsupported data type for torch.Tensor")
  
          # Data type & 255 division
          if x.dtype == tf.uint8:
              x = tf.image.convert_image_dtype(x, dtype=tf.float32)
          # Resizing
          if (x.shape[1], x.shape[2]) != self.resize.output_size:
              x = tf.image.resize(
                  x,
                  self.resize.output_size,
                  method=self.resize.method,
                  antialias=self.resize.antialias,
              )
  
          batches = [x]
  
      elif isinstance(x, list) and all(
          isinstance(sample, (np.ndarray, tf.Tensor)) for sample in x
      ):
          # Sample transform (to tensor, resize)
          samples = list(multithread_exec(self.sample_transforms, x))
          # Batching
          batches = self.batch_inputs(samples)
      else:
          raise TypeError(f"invalid input type: {type(x)}")
  
      # Batch transforms (normalize)
      batches = list(multithread_exec(self.normalize, batches))
  
      return batches
  
file_path: doctr/doctr/models/preprocessor/tensorflow.py
imports: import math
  from typing import Any, List, Tuple, Union
  import numpy
  import tensorflow
  from doctr.transforms import Normalize, Resize
  from doctr.utils.multithreading import multithread_exec
  from doctr.utils.repr import NestedObject
label_desc: Use image node_id 4 for calling the PreProcessor obj's underlying member method code with example usage: obj.__call__(x) and returns: batches