# core.image.image

## Module: `core.image.image`

Inheritance diagram for `nipy.core.image.image`:

Define the Image class and functions to work with Image instances

- fromarray : create an Image instance from an ndarray (deprecated in favor of using the Image constructor)

- subsample : slice an Image instance (deprecated in favor of image slicing)

- rollimg : roll an image axis to given location

- synchronized_order : match coordinate systems between images

- iter_axis : make iterator to iterate over an image axis

- is_image : test for an object obeying the Image API

## Classes

### `Image`

class nipy.core.image.image.Image(data, coordmap, metadata=None)

  Bases: `object`

  The Image class provides the core object type used in nipy.

  An Image represents a volumetric brain image and provides means for manipulating the image data. Most functions in the image module operate on Image objects.

  Notes

  Images can be created through the module functions. See nipy.io for image IO such as `load` and `save`

  Examples

  Load an image from disk

      >>> from nipy.testing import anatfile
      >>> from nipy.io.api import load_image
      >>> img = load_image(anatfile)

  Make an image from an array. We need to make a meaningful coordinate map for the image.

      >>> arr = np.zeros((21,64,64), dtype=np.int16)
      >>> cmap = AffineTransform('kji', 'zxy', np.eye(4))
      >>> img = Image(arr, cmap)

  __init__(data, coordmap, metadata=None)

    Create an Image object from array and CoordinateMap object.

    Images are often created through the `load_image` function in the nipy base namespace.

    Parameters:
      data array-like

        object that as attribute `shape` and returns an array from `np.asarray(data)`

      coordmap AffineTransform object

        coordmap mapping the domain (input) voxel axes of the image to the range (reference, output) axes - usually mm in real world space

      metadata dict, optional

        Freeform metadata for image. Most common contents is `header` from nifti etc loaded images.

    See also

    `load_image`

      load `Image` from a file

    `save_image`

      save `Image` to a file

  property affine
  property axes
  coordmap = AffineTransform( function_domain=CoordinateSystem(coord_names=('i', 'j', 'k'), name='', coord_dtype=float64), function_range=CoordinateSystem(coord_names=('x', 'y', 'z'), name='', coord_dtype=float64), affine=array([[3., 0., 0., 0.], [0., 5., 0., 0.], [0., 0., 7., 0.], [0., 0., 0., 1.]]) )
  classmethod from_image(img, data=None, coordmap=None, metadata=None)

    Classmethod makes new instance of this klass from instance img

    Parameters:
      data array-like

        object that as attribute `shape` and returns an array from `np.asarray(data)`

      coordmap AffineTransform object

        coordmap mapping the domain (input) voxel axes of the image to the range (reference, output) axes - usually mm in real world space

      metadata dict, optional

        Freeform metadata for image. Most common contents is `header` from nifti etc loaded images.

    Returns:
      img klass instance

        New image with data from data, coordmap from coordmap maybe metadata from metadata

    Notes

    Subclasses of `Image` with different semantics for `__init__` will need to override this classmethod.

    Examples

        >>> from nipy import load_image
        >>> from nipy.core.api import Image
        >>> from nipy.testing import anatfile
        >>> aimg = load_image(anatfile)
        >>> arr = np.arange(24).reshape((2,3,4))
        >>> img = Image.from_image(aimg, data=arr)

  get_fdata()

    Return data as a numpy array.

  property header

    The file header structure for this image, if available. This interface will soon go away - you should use ``img.metadata[‘header’] instead.

  metadata = {}
  property ndim
  property reference
  renamed_axes(**names_dict)

    Return a new image with input (domain) axes renamed

    Axes renamed according to the input dictionary.

    Parameters:
      **names_dict dict

        with keys being old names, and values being new names

    Returns:
      newimg Image

        An Image with the same data, having its axes renamed.

    Examples

        >>> data = np.random.standard_normal((11,9,4))
        >>> im = Image(data, AffineTransform.from_params('ijk', 'xyz', np.identity(4), 'domain', 'range'))
        >>> im_renamed = im.renamed_axes(i='slice')
        >>> print(im_renamed.axes)
        CoordinateSystem(coord_names=('slice', 'j', 'k'), name='domain', coord_dtype=float64)

  renamed_reference(**names_dict)

    Return new image with renamed output (range) coordinates

    Coordinates renamed according to the dictionary

    Parameters:
      **names_dict dict

        with keys being old names, and values being new names

    Returns:
      newimg Image

        An Image with the same data, having its output coordinates renamed.

    Examples

        >>> data = np.random.standard_normal((11,9,4))
        >>> im = Image(data, AffineTransform.from_params('ijk', 'xyz', np.identity(4), 'domain', 'range'))
        >>> im_renamed_reference = im.renamed_reference(x='newx', y='newy')
        >>> print(im_renamed_reference.reference)
        CoordinateSystem(coord_names=('newx', 'newy', 'z'), name='range', coord_dtype=float64)

  reordered_axes(order=None)

    Return a new Image with reordered input coordinates.

    This transposes the data as well.

    Parameters:
      order None, sequence, optional

        Sequence of int (giving indices) or str (giving names) - expressing new order of coordmap output coordinates. None (the default) results in reversed ordering.

    Returns:
      r_img object

        Image of same class as self, with reordered output coordinates.

    Examples

        >>> cmap = AffineTransform.from_start_step(
        ...             'ijk', 'xyz', [1, 2, 3], [4, 5, 6], 'domain', 'range')
        >>> cmap
        AffineTransform(
           function_domain=CoordinateSystem(coord_names=('i', 'j', 'k'), name='domain', coord_dtype=float64),
           function_range=CoordinateSystem(coord_names=('x', 'y', 'z'), name='range', coord_dtype=float64),
           affine=array([[ 4.,  0.,  0.,  1.],
                         [ 0.,  5.,  0.,  2.],
                         [ 0.,  0.,  6.,  3.],
                         [ 0.,  0.,  0.,  1.]])
        )
        >>> im = Image(np.empty((30,40,50)), cmap)
        >>> im_reordered = im.reordered_axes([2,0,1])
        >>> im_reordered.shape
        (50, 30, 40)
        >>> im_reordered.coordmap
        AffineTransform(
           function_domain=CoordinateSystem(coord_names=('k', 'i', 'j'), name='domain', coord_dtype=float64),
           function_range=CoordinateSystem(coord_names=('x', 'y', 'z'), name='range', coord_dtype=float64),
           affine=array([[ 0.,  4.,  0.,  1.],
                         [ 0.,  0.,  5.,  2.],
                         [ 6.,  0.,  0.,  3.],
                         [ 0.,  0.,  0.,  1.]])
        )

  reordered_reference(order=None)

    Return new Image with reordered output coordinates

    New Image coordmap has reordered output coordinates. This does not transpose the data.

    Parameters:
      order None, sequence, optional

        sequence of int (giving indices) or str (giving names) - expressing new order of coordmap output coordinates. None (the default) results in reversed ordering.

    Returns:
      r_img object

        Image of same class as self, with reordered output coordinates.

    Examples

        >>> cmap = AffineTransform.from_start_step(
        ...             'ijk', 'xyz', [1, 2, 3], [4, 5, 6], 'domain', 'range')
        >>> im = Image(np.empty((30,40,50)), cmap)
        >>> im_reordered = im.reordered_reference([2,0,1])
        >>> im_reordered.shape
        (30, 40, 50)
        >>> im_reordered.coordmap
        AffineTransform(
           function_domain=CoordinateSystem(coord_names=('i', 'j', 'k'), name='domain', coord_dtype=float64),
           function_range=CoordinateSystem(coord_names=('z', 'x', 'y'), name='range', coord_dtype=float64),
           affine=array([[ 0.,  0.,  6.,  3.],
                         [ 4.,  0.,  0.,  1.],
                         [ 0.,  5.,  0.,  2.],
                         [ 0.,  0.,  0.,  1.]])
        )

  property shape

### `SliceMaker`

class nipy.core.image.image.SliceMaker

  Bases: `object`

  This class just creates slice objects for image resampling

  It only has a __getitem__ method that returns its argument.

  XXX Wouldn’t need this if there was a way XXX to do this XXX subsample(img, [::2,::3,10:1:-1]) XXX XXX Could be something like this Subsample(img)[::2,::3,10:1:-1]

  __init__(*args, **kwargs)

## Functions

nipy.core.image.image.fromarray(data, innames, outnames)

  Create an image from array data, and input/output coordinate names

  The mapping between the input and output coordinate names is the identity matrix.

  Please don’t use this routine, but instead prefer:

      from nipy.core.api import Image, AffineTransform
      img = Image(data, AffineTransform(innames, outnames, np.eye(4)))

  where `4` is `len(innames) + 1`.

  Parameters:
    data numpy array

      A numpy array of three dimensions.

    innames sequence

      a list of input axis names

    innames sequence

      a list of output axis names

  Returns:
    image An Image object

  See also

  `load`

    function for loading images

  `save`

    function for saving images

  Examples

      >>> img = fromarray(np.zeros((2,3,4)), 'ijk', 'xyz')
      >>> img.coordmap
      AffineTransform(
         function_domain=CoordinateSystem(coord_names=('i', 'j', 'k'), name='', coord_dtype=float64),
         function_range=CoordinateSystem(coord_names=('x', 'y', 'z'), name='', coord_dtype=float64),
         affine=array([[ 1.,  0.,  0.,  0.],
                       [ 0.,  1.,  0.,  0.],
                       [ 0.,  0.,  1.,  0.],
                       [ 0.,  0.,  0.,  1.]])
      )

nipy.core.image.image.is_image(obj)

  Returns true if this object obeys the Image API

  This allows us to test for something that is duck-typing an image.

  For now an array must have a ‘coordmap’ attribute, and a callable ‘get_fdata’ attribute.

  Parameters:
    obj object

      object for which to test API

  Returns:
    is_img bool

      True if object obeys image API

  Examples

      >>> from nipy.testing import anatfile
      >>> from nipy.io.api import load_image
      >>> img = load_image(anatfile)
      >>> is_image(img)
      True
      >>> class C(object): pass
      >>> c = C()
      >>> is_image(c)
      False

nipy.core.image.image.iter_axis(img, axis, asarray=False)

  Return generator to slice an image img over axis

  Parameters:
    img `Image` instance
    axis int or str

      axis identifier, either name or axis number

    asarray{False, True}, optional
  Returns:
    g generator

      such that list(g) returns a list of slices over axis. If asarray is False the slices are images. If asarray is True, slices are the data from the images.

  Examples

      >>> data = np.arange(24).reshape((4,3,2))
      >>> img = Image(data, AffineTransform('ijk', 'xyz', np.eye(4)))
      >>> slices = list(iter_axis(img, 'j'))
      >>> len(slices)
      3
      >>> slices[0].shape
      (4, 2)
      >>> slices = list(iter_axis(img, 'k', asarray=True))
      >>> slices[1].sum() == data[:,:,1].sum()
      True

nipy.core.image.image.rollaxis(img, axis, inverse=False)

  Roll axis backwards, until it lies in the first position.

  It also reorders the reference coordinates by the same ordering. This is done to preserve a diagonal affine matrix if image.affine is diagonal. It also makes it possible to unambiguously specify an axis to roll along in terms of either a reference name (i.e. ‘z’) or an axis name (i.e. ‘slice’).

  This function is deprecated; please use `rollimg` instead.

  Parameters:
    img Image

      Image whose axes and reference coordinates are to be reordered by rolling.

    axis str or int

      Axis to be rolled, can be specified by name or as an integer.

    inverse bool, optional

      If inverse is True, then axis must be an integer and the first axis is returned to the position axis. This keyword is deprecated and we’ll remove it in a future version of nipy.

  Returns:
    newimg Image

      Image with reordered axes and reference coordinates.

  Examples

      >>> data = np.zeros((30,40,50,5))
      >>> affine_transform = AffineTransform.from_params('ijkl', 'xyzt', np.diag([1,2,3,4,1]))
      >>> im = Image(data, affine_transform)
      >>> im.coordmap
      AffineTransform(
         function_domain=CoordinateSystem(coord_names=('i', 'j', 'k', 'l'), name='', coord_dtype=float64),
         function_range=CoordinateSystem(coord_names=('x', 'y', 'z', 't'), name='', coord_dtype=float64),
         affine=array([[ 1.,  0.,  0.,  0.,  0.],
                       [ 0.,  2.,  0.,  0.,  0.],
                       [ 0.,  0.,  3.,  0.,  0.],
                       [ 0.,  0.,  0.,  4.,  0.],
                       [ 0.,  0.,  0.,  0.,  1.]])
      )
      >>> im_t_first = rollaxis(im, 't')
      >>> np.diag(im_t_first.affine)
      array([ 4.,  1.,  2.,  3.,  1.])
      >>> im_t_first.shape
      (5, 30, 40, 50)
      >>> im_t_first.coordmap
      AffineTransform(
         function_domain=CoordinateSystem(coord_names=('l', 'i', 'j', 'k'), name='', coord_dtype=float64),
         function_range=CoordinateSystem(coord_names=('t', 'x', 'y', 'z'), name='', coord_dtype=float64),
         affine=array([[ 4.,  0.,  0.,  0.,  0.],
                       [ 0.,  1.,  0.,  0.,  0.],
                       [ 0.,  0.,  2.,  0.,  0.],
                       [ 0.,  0.,  0.,  3.,  0.],
                       [ 0.,  0.,  0.,  0.,  1.]])
      )

nipy.core.image.image.rollimg(img, axis, start=0, fix0=True)

  Roll axis backwards in the inputs, until it lies before start

  Parameters:
    img Image

      Image whose axes and reference coordinates are to be reordered by rollimg.

    axis str or int

      Axis to be rolled, can be specified by name or as an integer. If an integer, axis is an input axis. If a name, can be name of input or output axis. If an output axis, we search for the closest matching input axis, and raise an AxisError if this fails.

    start str or int, optional

      position before which to roll axis axis. Default to 0. Can again be an integer (input axis) or name of input or output axis.

    fix0 bool, optional

      Whether to allow for zero scaling when searching for an input axis matching an output axis. Useful for images where time scaling is 0.

  Returns:
    newimg Image

      Image with reordered input axes and corresponding data.

  Examples

      >>> data = np.zeros((30,40,50,5))
      >>> affine_transform = AffineTransform('ijkl', 'xyzt', np.diag([1,2,3,4,1]))
      >>> im = Image(data, affine_transform)
      >>> im.coordmap
      AffineTransform(
         function_domain=CoordinateSystem(coord_names=('i', 'j', 'k', 'l'), name='', coord_dtype=float64),
         function_range=CoordinateSystem(coord_names=('x', 'y', 'z', 't'), name='', coord_dtype=float64),
         affine=array([[ 1.,  0.,  0.,  0.,  0.],
                       [ 0.,  2.,  0.,  0.,  0.],
                       [ 0.,  0.,  3.,  0.,  0.],
                       [ 0.,  0.,  0.,  4.,  0.],
                       [ 0.,  0.,  0.,  0.,  1.]])
      )
      >>> im_t_first = rollimg(im, 't')
      >>> im_t_first.shape
      (5, 30, 40, 50)
      >>> im_t_first.coordmap
      AffineTransform(
         function_domain=CoordinateSystem(coord_names=('l', 'i', 'j', 'k'), name='', coord_dtype=float64),
         function_range=CoordinateSystem(coord_names=('x', 'y', 'z', 't'), name='', coord_dtype=float64),
         affine=array([[ 0.,  1.,  0.,  0.,  0.],
                       [ 0.,  0.,  2.,  0.,  0.],
                       [ 0.,  0.,  0.,  3.,  0.],
                       [ 4.,  0.,  0.,  0.,  0.],
                       [ 0.,  0.,  0.,  0.,  1.]])
      )

nipy.core.image.image.subsample(img, slice_object)

  Subsample an image

  Please don’t use this function, but use direct image slicing instead. That is, replace:

      frame3 = subsample(im, slice_maker[:,:,:,3])

  with:

      frame3 = im[:,:,:,3]

  Parameters:
    img Image
    slice_object: int, slice or sequence of slice

      An object representing a numpy ‘slice’.

  Returns:
    img_subsampled: Image

      An Image with data img.get_fdata()[slice_object] and an appropriately corrected CoordinateMap.

  Examples

      >>> from nipy.io.api import load_image
      >>> from nipy.testing import funcfile
      >>> from nipy.core.api import subsample, slice_maker
      >>> im = load_image(funcfile)
      >>> frame3 = subsample(im, slice_maker[:,:,:,3])
      >>> np.allclose(frame3.get_fdata(), im.get_fdata()[:,:,:,3])
      True

nipy.core.image.image.synchronized_order(img, target_img, axes=True, reference=True)

  Reorder reference and axes of img to match target_img.

  Parameters:
    img Image
    target_img Image
    axes bool, optional

      If True, synchronize the order of the axes.

    reference bool, optional

      If True, synchronize the order of the reference coordinates.

  Returns:
    newimg Image

      An Image satisfying newimg.axes == target.axes (if axes == True), newimg.reference == target.reference (if reference == True).

  Examples

      >>> data = np.random.standard_normal((3,4,7,5))
      >>> im = Image(data, AffineTransform.from_params('ijkl', 'xyzt', np.diag([1,2,3,4,1])))
      >>> im_scrambled = im.reordered_axes('iljk').reordered_reference('txyz')
      >>> im == im_scrambled
      False
      >>> im_unscrambled = synchronized_order(im_scrambled, im)
      >>> im == im_unscrambled
      True

  The images don’t have to be the same shape

      >>> data2 = np.random.standard_normal((3,11,9,4))
      >>> im2 = Image(data, AffineTransform.from_params('ijkl', 'xyzt', np.diag([1,2,3,4,1])))
      >>> im_scrambled2 = im2.reordered_axes('iljk').reordered_reference('xtyz')
      >>> im_unscrambled2 = synchronized_order(im_scrambled2, im)
      >>> im_unscrambled2.coordmap == im.coordmap
      True

  or have the same coordmap

      >>> data3 = np.random.standard_normal((3,11,9,4))
      >>> im3 = Image(data3, AffineTransform.from_params('ijkl', 'xyzt', np.diag([1,9,3,-2,1])))
      >>> im_scrambled3 = im3.reordered_axes('iljk').reordered_reference('xtyz')
      >>> im_unscrambled3 = synchronized_order(im_scrambled3, im)
      >>> im_unscrambled3.axes == im.axes
      True
      >>> im_unscrambled3.reference == im.reference
      True
      >>> im_unscrambled4 = synchronized_order(im_scrambled3, im, axes=False)
      >>> im_unscrambled4.axes == im.axes
      False
      >>> im_unscrambled4.axes == im_scrambled3.axes
      True
      >>> im_unscrambled4.reference == im.reference
      True