# Get \`numpy\` to \`SimpleITK\` data type mapping

**URL:** <https://discourse.itk.org/t/get-numpy-to-simpleitk-data-type-mapping/7479>\
**Category:** Beginner Questions\
**Tags:** simpleitk\
**Created:** [March 26, 2025, 8:01pm UTC](https://discourse.itk.org/t/get-numpy-to-simpleitk-data-type-mapping/7479 "2025-03-26T20:01:34Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![jhlegarreta](https://discourse.itk.org/user_avatar/discourse.itk.org/jhlegarreta/32/476_2.png) [@jhlegarreta](https://discourse.itk.org/u/jhlegarreta)\
**Post date:** [March 26, 2025, 8:01pm UTC](https://discourse.itk.org/t/get-numpy-to-simpleitk-data-type-mapping/7479/1 "2025-03-26T20:01:34Z")

</div>

Hi,  
is there a way to get the mapping of `numpy` data types to the `SimpleITK` data types?

I have seen this,

> <https://github.com/SimpleITK/SimpleITK/blob/cfa2e0a46b022da2ffdce0771e64f0e103a16547/Wrapping/Python/SimpleITK/extra.py#L165-L192>

but it is a method variable, and it requires an input image. I am wondering whether I cant get the `SimpleITK` type equivalent given the `numpy` data type, e.g. get `sitkUInt8` given `numpy.uint8`. For obvious reasons, I am not willing to hard-code the mapping myself.

Sorry for this very basic question, but have not found any relevant code/posts.

Thanks.

---

<div class="post-metadata">

**Author:** ![zivy](https://discourse.itk.org/user_avatar/discourse.itk.org/zivy/32/1726_2.png) [@zivy](https://discourse.itk.org/u/zivy)\
**Post date:** [March 26, 2025, 8:59pm UTC](https://discourse.itk.org/t/get-numpy-to-simpleitk-data-type-mapping/7479/2 "2025-03-26T20:59:36Z")

</div>

Hello @jhlegarreta,

Not exactly sure what is the intended goal here, so my answer may or may not be relefant.

The direction from numpy types to SimpleITK is one-to-many (np.uint64 can be mapped to sitVectorUInt64 or sitkUInt64).

If the intent is to create a SimpleITK image from a numpy array the `GetImageFromArray` has a `isVector` parameter which takes care of the ambiguity mentioned above and maps the types correctly ([the relevant code](https://github.com/SimpleITK/SimpleITK/blob/cfa2e0a46b022da2ffdce0771e64f0e103a16547/Wrapping/Python/SimpleITK/extra.py#L197-L253) with the mapping is just below the code you were looking at).

If this doesn’t address the issue, please provide more details.

---

<div class="post-metadata">

**Author:** ![jhlegarreta](https://discourse.itk.org/user_avatar/discourse.itk.org/jhlegarreta/32/476_2.png) [@jhlegarreta](https://discourse.itk.org/u/jhlegarreta)\
**Post date:** [March 26, 2025, 9:11pm UTC](https://discourse.itk.org/t/get-numpy-to-simpleitk-data-type-mapping/7479/3 "2025-03-26T21:11:36Z")

</div>

Hi @zivy,  
thanks for chiming in.

I have a very simple script that takes an image and changes its pixel type using `SimpletITK`. Right now, as the use case is labelmap images, I have the target `SimpleITK` pixel type hard-coded, but I would like to offer some flexibility and have the pixel type as an input argument to the script.

I thought that since across my applications I use `NumPy` a lot more than `SimpleITK` I would accept a `NumPy` data type string as the argument.

I see now the one-to-many mapping. Although that may be an issue at some point, for now I could content myself using the `_get_sitk_pixelid` if that is exposed by the public API. So given the `NumPy` data type, I could create a simple `NumPy` array, and the give that to `_get_sitk_pixelid` and then somehow retrieve the data type from the returned integer value?

---

<div class="post-metadata">

**Author:** ![zivy](https://discourse.itk.org/user_avatar/discourse.itk.org/zivy/32/1726_2.png) [@zivy](https://discourse.itk.org/u/zivy)\
**Post date:** [March 26, 2025, 9:58pm UTC](https://discourse.itk.org/t/get-numpy-to-simpleitk-data-type-mapping/7479/4 "2025-03-26T21:58:51Z")

</div>

Hi @jhlegarreta,

Thanks for the clarification. So what you really are looking for is a mapping from arbitrary strings, input to the script, to a SimpleITK pixel type. Below is possibly a solution:

```auto
import SimpleITK as sitk
import argparse
import sys

str_2_sitk_pixel_type = {
    "uint8": sitk.sitkUInt8, # the key is arbitrary so could have been "np_uint8"
    "uint16": sitk.sitkUInt16,
    "uint32": sitk.sitkUInt32,
    "uint64": sitk.sitkUInt64,
    "int8": sitk.sitkInt8,
    "int16": sitk.sitkInt16,
    "int32": sitk.sitkInt32,
    "int64": sitk.sitkInt64,
    "float32": sitk.sitkFloat32,
    "float64": sitk.sitkFloat64,
    "complex64": sitk.sitkComplexFloat32,
    "complex128": sitk.sitkComplexFloat64,
}

def positive_int(i):
    res = int(i)
    if res > 0:
        return res
    raise argparse.ArgumentTypeError(f"Invalid argument ({i}), expected value > 0 .")

def main(argv=None):

    parser = argparse.ArgumentParser()

    parser.add_argument(
        "image_sizes", type=positive_int, nargs=2, help="image size x and y pixels"
    )
    parser.add_argument(
        "pixel_type",
        choices=list(str_2_sitk_pixel_type.keys()),
        help="String representations of SimpleITK pixel types.",
    )
    args = parser.parse_args(argv)

    # This will always work because argparse enforced valid values for the inputs
    image = sitk.Image(args.image_sizes, str_2_sitk_pixel_type[args.pixel_type])
    print(image)
    
    sys.exit(0)

if __name__ == " __main__":
    sys.exit(main())

```

---

<div class="post-metadata">

**Author:** ![jhlegarreta](https://discourse.itk.org/user_avatar/discourse.itk.org/jhlegarreta/32/476_2.png) [@jhlegarreta](https://discourse.itk.org/u/jhlegarreta)\
**Post date:** [March 26, 2025, 10:26pm UTC](https://discourse.itk.org/t/get-numpy-to-simpleitk-data-type-mapping/7479/5 "2025-03-26T22:26:20Z")

</div>

Thanks @zivy. Precisely, I want to avoid writing the mapping myself and rely on what `SimpletITK` could offer 😬.

---

<div class="post-metadata">

**Author:** ![zivy](https://discourse.itk.org/user_avatar/discourse.itk.org/zivy/32/1726_2.png) [@zivy](https://discourse.itk.org/u/zivy)\
**Post date:** [March 27, 2025, 2:12am UTC](https://discourse.itk.org/t/get-numpy-to-simpleitk-data-type-mapping/7479/6 "2025-03-27T02:12:05Z")

</div>

Hi @jhlegarreta,

A way that circumvents the need for mapping but is a bit dangerous is to require the string input to be the SimpleITK pixel type and use `eval`:

```auto
import SimpleITK as sitk

s = "sitk.sitkUInt8"
image = sitk.Image([1,1], eval(s))

```

---

<div class="post-metadata">

**Author:** ![blowekamp](https://discourse.itk.org/user_avatar/discourse.itk.org/blowekamp/32/79_2.png) [@blowekamp](https://discourse.itk.org/u/blowekamp)\
**Post date:** [March 27, 2025, 12:27pm UTC](https://discourse.itk.org/t/get-numpy-to-simpleitk-data-type-mapping/7479/7 "2025-03-27T12:27:26Z")

</div>

There are a couple things going on here that I am having problems figuring what you are trying to do.

First you describe you usage as “label map images”. I am not sure if you want itk::Image of labels or an itk::LabelMap. There are rather different and can both be represented in SimpleITK.

Second, numpy uses [“data type objects”](https://numpy.org/doc/2.1/reference/arrays.dtypes.html#arrays-dtypes) to describe the data of arrays. There is more details related to these data type objects that most users know. But the commonly used enumerations `numpy.uint8` are not actually datatype objects, and comparisons with them break down in some cases. They need to be converted to `dtype` objects to do useful comparisons.

I think you are on your own to convert strings to numpy dtypes. I would recommend using a manual map over `eval` from user input. Maybe some regex could be used.

Second, I’d use the following function in SimpleITK.extra:

```auto
def _get_sitk_pixelid(numpy_array_type: Type["numpy.ndarray"]) -> int:

```

The argument really should be “convertible to dtype” and not as specific as an array. Also, this method probably should be made public.

If you have some specific code it made help.

---

<div class="post-metadata">

**Author:** ![jhlegarreta](https://discourse.itk.org/user_avatar/discourse.itk.org/jhlegarreta/32/476_2.png) [@jhlegarreta](https://discourse.itk.org/u/jhlegarreta)\
**Post date:** [March 27, 2025, 12:49pm UTC](https://discourse.itk.org/t/get-numpy-to-simpleitk-data-type-mapping/7479/8 "2025-03-27T12:49:05Z")

</div>

> [@zivy](#):
>
> A way that circumvents the need for mapping but is a bit dangerous is to require the string input to be the SimpleITK pixel type and use `eval`:

Interesting. Why is it dangerous?

---

<div class="post-metadata">

**Author:** ![jhlegarreta](https://discourse.itk.org/user_avatar/discourse.itk.org/jhlegarreta/32/476_2.png) [@jhlegarreta](https://discourse.itk.org/u/jhlegarreta)\
**Post date:** [March 27, 2025, 12:56pm UTC](https://discourse.itk.org/t/get-numpy-to-simpleitk-data-type-mapping/7479/9 "2025-03-27T12:56:07Z")

</div>

> [@blowekamp](#):
>
> First you describe you usage as “label map images”. I am not sure if you want itk::Image of labels or an itk::LabelMap. There are rather different and can both be represented in SimpleITK.

I am not thinking of a labelmap in terms of SimpleITK: for “labelmap” I mean an image containing integer values issues by a segmentation method.

> Second, numpy uses [“data type objects”](https://numpy.org/doc/2.1/reference/arrays.dtypes.html#arrays-dtypes) to describe the data of arrays. There is more details related to these data type objects that most users know. But the commonly used enumerations `numpy.uint8` are not actually datatype objects, and comparisons with them break down in some cases. They need to be converted to `dtype` objects to do useful comparisons.

The labelmaps that I am trying to convert are issued by some tool that unfortunately writes these images as having a float pixel type, and then I am using another tool that requires labelmap images to have integer pixel types. I cannot assume more than that/do not have more information.

> If you have some specific code it made help.

The essential part of the code can be summarized to:

```auto
out_pixel_type = sitk.sitkUInt16

img = sitk.ReadImage(args.in_fname, out_pixel_type)

sitk.WriteImage(img, args.out_fname)

```

---

<div class="post-metadata">

**Author:** ![blowekamp](https://discourse.itk.org/user_avatar/discourse.itk.org/blowekamp/32/79_2.png) [@blowekamp](https://discourse.itk.org/u/blowekamp)\
**Post date:** [March 27, 2025, 1:04pm UTC](https://discourse.itk.org/t/get-numpy-to-simpleitk-data-type-mapping/7479/10 "2025-03-27T13:04:14Z")

</div>

The dangers of `eval` is something every developer should know. It allows any user input to be executed.

---

<div class="post-metadata">

**Author:** ![zivy](https://discourse.itk.org/user_avatar/discourse.itk.org/zivy/32/1726_2.png) [@zivy](https://discourse.itk.org/u/zivy)\
**Post date:** [March 27, 2025, 1:10pm UTC](https://discourse.itk.org/t/get-numpy-to-simpleitk-data-type-mapping/7479/11 "2025-03-27T13:10:57Z")

</div>

Hi @jhlegarreta,

`eval` is dangerous because it will execute the code found in the string which may be harmful for the user (delete files or any other operation you can do with Python).

If you have complete control of the string contents then probably ok to use. For example if the string passed to eval is obtained using argparse and the parameter is limited to a “choices” set that you control, the user will be limited to valid selections and cannot provide problematic input, so there is no problem.

---

<div class="post-metadata">

**Author:** ![blowekamp](https://discourse.itk.org/user_avatar/discourse.itk.org/blowekamp/32/79_2.png) [@blowekamp](https://discourse.itk.org/u/blowekamp)\
**Post date:** [March 27, 2025, 1:21pm UTC](https://discourse.itk.org/t/get-numpy-to-simpleitk-data-type-mapping/7479/12 "2025-03-27T13:21:45Z")

</div>

> [@jhlegarreta](#):
>
> ```auto
> out_pixel_type = sitk.sitkUInt16
> 
> img = sitk.ReadImage(args.in_fname, out_pixel_type)
> 
> sitk.WriteImage(img, args.out_fname)
> 
> ```

Reading the input image into a casted type may result in truncation. You may want to read the input image input then automatically chooses type by computing the min/max then select the appropriate SimpleITK pixel type.

Here is what GH Copilot wrote to do this:

```auto
import SimpleITK as sitk

# Read the input image
in_fname = "input_image.nii"
out_fname = "output_image.nii"
image = sitk.ReadImage(in_fname)

# Compute image statistics
stats = sitk.StatisticsImageFilter()
stats.Execute(image)
min_pixel_value = stats.GetMinimum()
max_pixel_value = stats.GetMaximum()

# Determine the appropriate integer pixel type
if min_pixel_value >= 0:
    if max_pixel_value <= 255:
        pixel_type = sitk.sitkUInt8
    elif max_pixel_value <= 65535:
        pixel_type = sitk.sitkUInt16
    elif max_pixel_value <= 4294967295:
        pixel_type = sitk.sitkUInt32
    else:
        pixel_type = sitk.sitkUInt64
else:
    if min_pixel_value >= -128 and max_pixel_value <= 127:
        pixel_type = sitk.sitkInt8
    elif min_pixel_value >= -32768 and max_pixel_value <= 32767:
        pixel_type = sitk.sitkInt16
    elif min_pixel_value >= -2147483648 and max_pixel_value <= 2147483647:
        pixel_type = sitk.sitkInt32
    else:
        pixel_type = sitk.sitkInt64

# Cast the image to the selected type
cast_image = sitk.Cast(image, pixel_type)

# Write the image to the output file
sitk.WriteImage(cast_image, out_fname)

```

---

<div class="post-metadata">

**Author:** ![blowekamp](https://discourse.itk.org/user_avatar/discourse.itk.org/blowekamp/32/79_2.png) [@blowekamp](https://discourse.itk.org/u/blowekamp)\
**Post date:** [March 27, 2025, 2:22pm UTC](https://discourse.itk.org/t/get-numpy-to-simpleitk-data-type-mapping/7479/13 "2025-03-27T14:22:55Z")

</div>

> [@zivy](#):
>
> If you have complete control of the string contents then probably ok to use. For example if the string passed to eval is obtained using argparse and the parameter is limited to a “choices” set that you control, the user will be limited to valid selections and cannot provide problematic input, so there is no problem.

IMHO, this is still a risky recommendation. For this case to convert a string to a numpy dtype the following can be used: `np.dtype("uint8")`. There are many other strings that the dtype constructor also supports, that would not be supported as conversion into an itk/sitk image type.

---

<div class="post-metadata">

**Author:** ![jhlegarreta](https://discourse.itk.org/user_avatar/discourse.itk.org/jhlegarreta/32/476_2.png) [@jhlegarreta](https://discourse.itk.org/u/jhlegarreta)\
**Post date:** [March 27, 2025, 4:04pm UTC](https://discourse.itk.org/t/get-numpy-to-simpleitk-data-type-mapping/7479/14 "2025-03-27T16:04:28Z")

</div>

OK, thanks for the explanations, I see the obvious danger about `eval`.

> You may want to read the input image input then automatically chooses type by computing the min/max then select the appropriate SimpleITK pixel type.

Looks the most appropriate solution. Should have thought about it. Thanks @blowekamp @zivy.

> Also, this method probably should be made public.

@blowekamp Let me know if you want me to submit a PR.
