Create an ITK object from ``data_array``. This method assumes a 'channel-last' ``data_array``. Args: data_array: input data array. channel_dim: channel dimension of the data array. This is used to create a Vector Image if it is not ``None``. affi
(
cls,
data_array: NdarrayOrTensor,
channel_dim: int | None = 0,
affine: NdarrayOrTensor | None = None,
dtype: DtypeLike = np.float32,
affine_lps_to_ras: bool | None = True,
**kwargs,
)
| 477 | |
| 478 | @classmethod |
| 479 | def create_backend_obj( |
| 480 | cls, |
| 481 | data_array: NdarrayOrTensor, |
| 482 | channel_dim: int | None = 0, |
| 483 | affine: NdarrayOrTensor | None = None, |
| 484 | dtype: DtypeLike = np.float32, |
| 485 | affine_lps_to_ras: bool | None = True, |
| 486 | **kwargs, |
| 487 | ): |
| 488 | """ |
| 489 | Create an ITK object from ``data_array``. This method assumes a 'channel-last' ``data_array``. |
| 490 | |
| 491 | Args: |
| 492 | data_array: input data array. |
| 493 | channel_dim: channel dimension of the data array. This is used to create a Vector Image if it is not ``None``. |
| 494 | affine: affine matrix of the data array. This is used to compute `spacing`, `direction` and `origin`. |
| 495 | dtype: output data type. |
| 496 | affine_lps_to_ras: whether to convert the affine matrix from "LPS" to "RAS". Defaults to ``True``. |
| 497 | Set to ``True`` to be consistent with ``NibabelWriter``, |
| 498 | otherwise the affine matrix is assumed already in the ITK convention. |
| 499 | Set to ``None`` to use ``data_array.meta[MetaKeys.SPACE]`` to determine the flag. |
| 500 | kwargs: keyword arguments. Current `itk.GetImageFromArray` will read ``ttype`` from this dictionary. |
| 501 | |
| 502 | see also: |
| 503 | |
| 504 | - https://github.com/InsightSoftwareConsortium/ITK/blob/v5.2.1/Wrapping/Generators/Python/itk/support/extras.py#L389 |
| 505 | |
| 506 | """ |
| 507 | if isinstance(data_array, MetaTensor) and affine_lps_to_ras is None: |
| 508 | affine_lps_to_ras = ( |
| 509 | data_array.meta.get(MetaKeys.SPACE, SpaceKeys.LPS) != SpaceKeys.LPS |
| 510 | ) # do the converting from LPS to RAS only if the space type is currently LPS. |
| 511 | data_array = super().create_backend_obj(data_array) |
| 512 | _is_vec = channel_dim is not None |
| 513 | if _is_vec: |
| 514 | data_array = np.moveaxis(data_array, -1, 0) # from channel last to channel first |
| 515 | data_array = data_array.T.astype(get_equivalent_dtype(dtype, np.ndarray), copy=True, order="C") |
| 516 | itk_obj = itk.GetImageFromArray(data_array, is_vector=_is_vec, ttype=kwargs.pop("ttype", None)) |
| 517 | |
| 518 | d = len(itk.size(itk_obj)) |
| 519 | if affine is None: |
| 520 | affine = np.eye(d + 1, dtype=np.float64) |
| 521 | _affine = convert_data_type(affine, np.ndarray)[0] |
| 522 | if affine_lps_to_ras: |
| 523 | _affine = orientation_ras_lps(to_affine_nd(d, _affine)) |
| 524 | spacing = affine_to_spacing(_affine, r=d) |
| 525 | _direction: np.ndarray = np.diag(1 / spacing) |
| 526 | _direction = _affine[:d, :d] @ _direction |
| 527 | itk_obj.SetSpacing(spacing.tolist()) |
| 528 | itk_obj.SetOrigin(_affine[:d, -1].tolist()) |
| 529 | itk_obj.SetDirection(itk.GetMatrixFromArray(_direction)) |
| 530 | return itk_obj |
| 531 | |
| 532 | |
| 533 | @require_pkg(pkg_name="nibabel") |