code: def convert_to_numpy(
      data: Any,
      dtype: DtypeLike = None,
      wrap_sequence: bool = False,
      safe: bool = False,
  ) -> Any:
      """
      Utility to convert the input data to a numpy array. If passing a dictionary, list or tuple,
      recursively check every item and convert it to numpy array.
  
      Args:
          data: input data can be PyTorch Tensor, numpy array, list, dictionary, int, float, bool, str, etc.
              will convert Tensor, Numpy array, float, int, bool to numpy arrays, strings and objects keep the original.
              for dictionary, list or tuple, convert every item to a numpy array if applicable.
          dtype: target data type when converting to numpy array.
          wrap_sequence: if `False`, then lists will recursively call this function.
              E.g., `[1, 2]` -> `[array(1), array(2)]`. If `True`, then `[1, 2]` -> `array([1, 2])`.
          safe: if `True`, then do safe dtype convert when intensity overflow. default to `False`.
              E.g., `[256, -12]` -> `[array(0), array(244)]`. If `True`, then `[256, -12]` -> `[array(255), array(0)]`.
      """
      if safe:
          data = safe_dtype_range(data, dtype)
      if isinstance(data, torch.Tensor):
          data = np.asarray(
              data.detach().to(device="cpu").numpy(),
              dtype=get_equivalent_dtype(dtype, np.ndarray),
          )
      elif has_cp and isinstance(data, cp_ndarray):
          data = cp.asnumpy(data).astype(dtype, copy=False)
      elif isinstance(data, (np.ndarray, float, int, bool)):
          # Convert into a contiguous array first if the current dtype's size is smaller than the target dtype's size.
          # This help improve the performance because (convert to contiguous array) -> (convert dtype) is faster
          # than (convert dtype) -> (convert to contiguous array) when src dtype (e.g., uint8) is smaller than
          # target dtype(e.g., float32) and we are going to convert it to contiguous array anyway later in this
          # method.
          if (
              isinstance(data, np.ndarray)
              and data.ndim > 0
              and data.dtype.itemsize < np.dtype(dtype).itemsize
          ):
              data = np.ascontiguousarray(data)
          data = np.asarray(data, dtype=dtype)
      elif isinstance(data, list):
          list_ret = [convert_to_numpy(i, dtype=dtype) for i in data]
          return np.asarray(list_ret) if wrap_sequence else list_ret
      elif isinstance(data, tuple):
          tuple_ret = tuple(
              convert_to_numpy(i, dtype=dtype) for i in data
          )
          return np.asarray(tuple_ret) if wrap_sequence else tuple_ret
      elif isinstance(data, dict):
          return {
              k: convert_to_numpy(v, dtype=dtype)
              for k, v in data.items()
          }
  
      if isinstance(data, np.ndarray) and data.ndim > 0:
          data = np.ascontiguousarray(data)
  
      return data
  
imports: from __future__ import annotations
  import re
  from collections.abc import Sequence
  from typing import Any
  import numpy
  import torch
  import monai
  from monai.config.type_definitions import DtypeLike, NdarrayTensor
  from monai.utils import optional_import
label_desc: Use image node_id 8 for calling a global function with example usage: convert_to_numpy(data, dtype, wrap_sequence, safe) and returns: data, unknown, unknown, unknown