nifti-rs
nifti-rs copied to clipboard
Volume data type support
I will use this issue to track currently supported volume data types.
type | NiftiVolume (get_* ) |
IntoNdArray |
Tested | Issue / PR |
---|---|---|---|---|
Uint8 |
:white_check_mark: | :white_check_mark: | :white_check_mark: | |
Int8 |
:white_check_mark: | :white_check_mark: | :white_check_mark: | #5 |
Uint16 |
:white_check_mark: | :white_check_mark: | :white_check_mark: | #5 |
Int16 |
:white_check_mark: | :white_check_mark: | :white_check_mark: | #5 |
Uint32 |
:white_check_mark: | :white_check_mark: | :white_check_mark: | #5 |
Int32 |
:white_check_mark: | :white_check_mark: | :white_check_mark: | #5 |
Uint64 |
:white_check_mark: | :white_check_mark: | :white_check_mark: | #5 |
Int64 |
:white_check_mark: | :white_check_mark: | :white_check_mark: | #5 |
Float32 |
:white_check_mark: | :white_check_mark: | :white_check_mark: | #1 |
Float64 |
:white_check_mark: | :white_check_mark: | :white_check_mark: | #5 |
Complex64 |
:x: | :x: | :x: | |
Rgb24 |
:x: | :x: | :x: | #26 (writing only) |
Rgba32 |
:x: | :x: | :x: | |
Float128 |
:x: | :x: | :x: | |
Complex128 |
:x: | :x: | :x: | |
Complex256 |
:x: | :x: | :x: |
I see that you support u8
image but I can't get this snippet to work.
let obj = InMemNiftiObject::from_file("a path.nii.gz")
.expect("Can't read input file.");
let volume_dyn = obj.into_volume().to_ndarray::<u8>().unwrap();
It fails during the compilation with error the trait std::convert::From<f32> is not implemented for u8
. I don't even use of f32
in this block! I checked your tests and they all use to_ndarray::<f32>
Thanks for the feedback, @nilgoyette.
Perhaps the table can indeed lead to misinterpretation: while the library can read volumes of the data types above, it can currently only fetch floating point values from the volume. That is, obtaining an Array<u8, _>
is not supported, and there is no get_u8
method either. Since values are subjected to the linear transformation over the scale+intercept parameters, a conversion is not guaranteed in compile time not to lose precision, thus the constraint From<f32>
. Regardless of the data type, you should still be able to do this:
obj.into_volume().to_ndarray::<f32>().unwrap();
This is something that can be reconsidered, of course, and the crate could sure use more tests. May I know what brings you to reading a volume as an array of u8
? Perhaps you would like to retrieve the raw volume data without the linear transformation?
I was trying to read a binary mask (0-1 values). They are quite frequent in medical imaging.
I know I could use mask[i, j, k] > 0.0
for true
and mask[i, j, k] == 0.0
for false
, but this is ugly and wasteful. For the time being, I will map
over the f32 image to get a u8 image.
It may not be the right place to ask this, but I checked your library a lot today because I'm trying to save an image and there's something I don't understand. You seem to cast everything to f32
, then cast to the desired type. If it's the case, could you please tell me why? Is there a [rusty] technical reason that forces you to do so?
That is a good question, actually. I do not intend to keep it like that in the future. Ideally, we would have a trait which implements the traditional numeric cast as
, but that doesn't seem to exist in the standard library nor the num
crate. The latter has guarded numeric cast traits such as NumCast
, but they return an empty value when it cannot be represented entirely with the new type. Nevertheless, this crate could probably roll a trait of its own until a more suitable alternative is found.
And with that addressed, retrieving an array of u8
(or something else) should work as well. I'll try to pick this up the next few days.
Status update: the master branch now uses asprim::AsPrim
for the generic cast (see rust-num/num#183), which makes the crate more relaxed in terms of element conversions.
I might publish a new release soon-ish, but feel free to use the upstream version for the time being.
Edit: This has now landed in 0.3.1