code: def crop(
      data,
      seg=None,
      crop_size=128,
      margins=(0, 0, 0),
      crop_type="center",
      pad_mode="constant",
      pad_kwargs={"constant_values": 0},
      pad_mode_seg="constant",
      pad_kwargs_seg={"constant_values": 0},
  ):
      if not isinstance(data, (list, tuple, np.ndarray)):
          raise TypeError(
              "data has to be either a numpy array or a list"
          )
  
      data_shape = tuple([len(data)] + list(data[0].shape))
      data_dtype = data[0].dtype
      dim = len(data_shape) - 2
  
      if seg is not None:
          seg_shape = tuple([len(seg)] + list(seg[0].shape))
          seg_dtype = seg[0].dtype
  
          if not isinstance(seg, (list, tuple, np.ndarray)):
              raise TypeError(
                  "data has to be either a numpy array or a list"
              )
  
          assert all(
              [i == j for i, j in zip(seg_shape[2:], data_shape[2:])]
          ), (
              "data and seg must have the same spatial "
              "dimensions. Data: {}, seg: {}.".format(
                  data_shape, seg_shape
              )
          )
  
      if type(crop_size) not in (tuple, list, np.ndarray):
          crop_size = [crop_size] * dim
      else:
          assert len(crop_size) == len(data_shape) - 2, (
              "If you provide a list/tuple as center crop make sure it has the same dimension as your "
              "data (2d/3d)"
          )
  
      if not isinstance(margins, (np.ndarray, tuple, list)):
          margins = [margins] * dim
  
      data_return = np.zeros(
          [data_shape[0], data_shape[1]] + list(crop_size),
          dtype=data_dtype,
      )
      if seg is not None:
          seg_return = np.zeros(
              [seg_shape[0], seg_shape[1]] + list(crop_size),
              dtype=seg_dtype,
          )
      else:
          seg_return = None
  
      for b in range(data_shape[0]):
          data_shape_here = [data_shape[0]] + list(data[b].shape)
          if seg is not None:
              seg_shape_here = [seg_shape[0]] + list(seg[b].shape)
  
          if crop_type == "center":
              lbs = get_lbs_for_center_crop(crop_size, data_shape_here)
          elif crop_type == "random":
              lbs = get_lbs_for_random_crop(
                  crop_size, data_shape_here, margins
              )
          else:
              raise NotImplementedError(
                  "crop_type must be either center or random"
              )
  
          need_to_pad = [[0, 0]] + [
              [
                  abs(min(0, lbs[d])),
                  abs(
                      min(
                          0,
                          data_shape_here[d + 2]
                          - (lbs[d] + crop_size[d]),
                      )
                  ),
              ]
              for d in range(dim)
          ]
  
          ubs = [
              min(lbs[d] + crop_size[d], data_shape_here[d + 2])
              for d in range(dim)
          ]
          lbs = [max(0, lbs[d]) for d in range(dim)]
  
          slicer_data = [slice(0, data_shape_here[1])] + [
              slice(lbs[d], ubs[d]) for d in range(dim)
          ]
          data_cropped = data[b][tuple(slicer_data)]
  
          if seg_return is not None:
              slicer_seg = [slice(0, seg_shape_here[1])] + [
                  slice(lbs[d], ubs[d]) for d in range(dim)
              ]
              seg_cropped = seg[b][tuple(slicer_seg)]
  
          if any([i > 0 for j in need_to_pad for i in j]):
              data_return[b] = np.pad(
                  data_cropped, need_to_pad, pad_mode, **pad_kwargs
              )
              if seg_return is not None:
                  seg_return[b] = np.pad(
                      seg_cropped,
                      need_to_pad,
                      pad_mode_seg,
                      **pad_kwargs_seg,
                  )
          else:
              data_return[b] = data_cropped
              if seg_return is not None:
                  seg_return[b] = seg_cropped
  
      return data_return, seg_return
  
imports: import random
  import numpy
  import paddle
  from paddle.nn.functional import avg_pool2d, avg_pool3d
  from typing import List, Tuple, Union, Callable
  from copy import deepcopy
  from scipy.ndimage import map_coordinates, fourier_gaussian
  from scipy.ndimage.filters import gaussian_filter, gaussian_gradient_magnitude
  from scipy.ndimage.morphology import grey_dilation
  from skimage.transform import resize
  from scipy.ndimage.measurements import label
label_desc: Use image node_id 28 for calling a global function with example usage: crop(data, seg, crop_size, margins, crop_type, pad_mode, pad_kwargs, pad_mode_seg, pad_kwargs_seg) and returns: data_return,  seg_return