code: def distance_transform_cdt(
      input,
      metric="chessboard",
      return_distances=True,
      return_indices=False,
      distances=None,
      indices=None,
  ):
      """
      Distance transform for chamfer type of transforms.
  
      Parameters
      ----------
      input : array_like
          Input
      metric : {'chessboard', 'taxicab'}, optional
          The `metric` determines the type of chamfering that is done. If the
          `metric` is equal to 'taxicab' a structure is generated using
          generate_binary_structure with a squared distance equal to 1. If
          the `metric` is equal to 'chessboard', a `metric` is generated
          using generate_binary_structure with a squared distance equal to
          the dimensionality of the array. These choices correspond to the
          common interpretations of the 'taxicab' and the 'chessboard'
          distance metrics in two dimensions.
  
          The default for `metric` is 'chessboard'.
      return_distances, return_indices : bool, optional
          The `return_distances`, and `return_indices` flags can be used to
          indicate if the distance transform, the feature transform, or both
          must be returned.
  
          If the feature transform is returned (``return_indices=True``),
          the index of the closest background element is returned along
          the first axis of the result.
  
          The `return_distances` default is True, and the
          `return_indices` default is False.
      distances, indices : ndarrays of int32, optional
          The `distances` and `indices` arguments can be used to give optional
          output arrays that must be the same shape as `input`.
  
      """
      if (not return_distances) and (not return_indices):
          msg = "at least one of distances/indices must be specified"
          raise RuntimeError(msg)
  
      ft_inplace = isinstance(indices, numpy.ndarray)
      dt_inplace = isinstance(distances, numpy.ndarray)
      input = numpy.asarray(input)
      if metric in ["taxicab", "cityblock", "manhattan"]:
          rank = input.ndim
          metric = generate_binary_structure(rank, 1)
      elif metric == "chessboard":
          rank = input.ndim
          metric = generate_binary_structure(rank, rank)
      else:
          try:
              metric = numpy.asarray(metric)
          except Exception:
              raise RuntimeError("invalid metric provided")
          for s in metric.shape:
              if s != 3:
                  raise RuntimeError("metric sizes must be equal to 3")
  
      if not metric.flags.contiguous:
          metric = metric.copy()
      if dt_inplace:
          if distances.dtype.type != numpy.int32:
              raise RuntimeError("distances must be of int32 type")
          if distances.shape != input.shape:
              raise RuntimeError("distances has wrong shape")
          dt = distances
          dt[...] = numpy.where(input, -1, 0).astype(numpy.int32)
      else:
          dt = numpy.where(input, -1, 0).astype(numpy.int32)
  
      rank = dt.ndim
      if return_indices:
          sz = numpy.product(dt.shape, axis=0)
          ft = numpy.arange(sz, dtype=numpy.int32)
          ft.shape = dt.shape
      else:
          ft = None
  
      _nd_image.distance_transform_op(metric, dt, ft)
      dt = dt[tuple([slice(None, None, -1)] * rank)]
      if return_indices:
          ft = ft[tuple([slice(None, None, -1)] * rank)]
      _nd_image.distance_transform_op(metric, dt, ft)
      dt = dt[tuple([slice(None, None, -1)] * rank)]
      if return_indices:
          ft = ft[tuple([slice(None, None, -1)] * rank)]
          ft = numpy.ravel(ft)
          if ft_inplace:
              if indices.dtype.type != numpy.int32:
                  raise RuntimeError("indices must of int32 type")
              if indices.shape != (dt.ndim,) + dt.shape:
                  raise RuntimeError("indices has wrong shape")
              tmp = indices
          else:
              tmp = numpy.indices(dt.shape, dtype=numpy.int32)
          for ii in range(tmp.shape[0]):
              rtmp = numpy.ravel(tmp[ii, ...])[ft]
              rtmp.shape = dt.shape
              tmp[ii, ...] = rtmp
          ft = tmp
  
      # construct and return the result
      result = []
      if return_distances and not dt_inplace:
          result.append(dt)
      if return_indices and not ft_inplace:
          result.append(ft)
  
      if len(result) == 2:
          return tuple(result)
      elif len(result) == 1:
          return result[0]
      else:
          return None
  
imports: from __future__ import division, print_function, absolute_import
  import warnings
  import numpy
  from .None import _ni_support
  from .None import _nd_image
  from .None import filters
label_desc: Use image node_id 21 for calling a global function with example usage: distance_transform_cdt(input, metric, return_distances, return_indices, distances, indices) and returns: tuple, result, None