Saving vector with complex components in a nifti file - python

I generate a 4D complex numpy array
for example:
numpy_array = np.tile(np.array([3, 4, 0], dtype=np.complex64), (100,100,100,1))
i want to save the numpy array as a nifti file
I tried using vtk and SimpleITK, but both of them don't support complex numbers (only vectors which are real numbers)
It seems that only nibabel support complex vectors and i manage to save the file, but i can only load it with nibabel, when i try to load it with ITK-SNAP or with Slicer it doesn't open. I know that ITK-SNAP can open complex vector of nifti files because i already have those files saved with another script using matlab
import numpy as np
import nibabel as nib
import SimpleITK as sitk
import vtk
from vtk.util.numpy_support import numpy_to_vtk
numpy_array = np.tile(np.array([3, 4, 0], dtype=np.complex64), (100,100,100,1))
nibabel save try:
image = nib.Nifti2Image(numpy_array, affine=np.eye(4))
nib.save(image , r'file_name.nii')
SimpleITK save try:
image = sitk.GetImageFromArray(numpy_array)
sitk.writeimage(image, r'file_name.nii')
vtk save try:
array = np.concatenate((np.real(numpy_array), np.imag(numpy_array)), axis=3)
stacked_array = array.reshape(-1, array.shape[-1])
vtk_array = numpy_to_vtk(stacked_array, deep=True,
array_type=vtk.VTK_FLOAT)
vtk_image = vtk.vtkImageData()
vtk_image.SetDimensions(numpy_array.shape[0], numpy_array.shape[1],
numpy_array.shape[2])
vtk_image.GetPointData().SetScalars(vtk_array)
writer = vtk.vtkNIFTIImageWriter()
writer.SetFileName(file_name)
writer.SetInputData(vtk_image)
writer.Write()
nibabel output:
nibabel creates a nifti file with vector but with other programs like ITK-SNAP it doens't open
ITK-SNAP error:
Error: Unsupported or missing image file format. ITK-SNAP failed to create an
ImageIO object for the image 'file_name.nii' using format ''.
SimpleITK error:
Traceback (most recent call last):
File "C:\ProgramData\Anaconda3\lib\site-packages\SimpleITK\SimpleITK.py", line 3366, in _get_sitk_vector_pixelid
return _np_sitk[numpy_array_type.dtype]
KeyError: dtype('complex64')
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "C:\ProgramData\Anaconda3\lib\site-packages\SimpleITK\SimpleITK.py", line 3431, in GetImageFromArray
id = _get_sitk_vector_pixelid( z )
File "C:\ProgramData\Anaconda3\lib\site-packages\SimpleITK\SimpleITK.py", line 3371, in _get_sitk_vector_pixelid
raise TypeError('dtype: {0} is not supported.'.format(numpy_array_type.dtype))
TypeError: dtype: complex64 is not supported.
vtk output:
vtk creates a vector nifti file but with 6 components instead of 3
(consider the imaginary part as components too), i saw in the
documentation of numpy_to_vtk that it doesn't support copmlex arrays,
maybe someone know about a workaround.

The SimpleITK 1.2 release supports writing 4D complex images. The missing feature is support for complex number in stk.GetImageFromArray, but it's already added to the development branch and your code works if you a compiled version of the current SimpleITK master branch or wait for the 1.3 release scheduled for October 2019.
In the mean time you can convert the complex number components to SimpleITK separately like this:
image = sitk.RealAndImaginaryToComplexImageFilter(sitk.GetImageFromArray(numpy_array.real),
sitk.GetImageFromArray(numpy_array.imag))
sitk.WriteImage(image, r'file_name.nii')

Related

SPy error: "Axes don't match array" when calling .open_memmap()

I have some .bsq files with corresponding header files (.hdr). I want to open and edit them in Python, using the spectral (SPy) module.
Since I need to edit the files from within a Python Toolbox in ArcMap (that is, a single Python script which uses the Python installation that comes with ArcMap), I decided to copy the GitHub repository of the SPy module and import it as
import sys
sys.path.append("/path/to/module")
import spatial as spy
in order to be able to run the toolbox on any computer without having to install pip or other software. (I intend to just copy the Toolbox and the module folder, or, in a later step, create a single Python script comprising the Toolbox as well as the SPy-module code.)
I opened some .bsq-file and tried to subsequently edit it as memmap, following this example.
First, I opened the image as spectral.io.bsqfile.BsqFile:
path = "/path/to/image_header.hdr"
img = spy.open_image(path)
I am able to apply various methods to img (such as: view metadata, read bands as array, etc), hence, I assume there were no issues with the path or the image file. I can also read single bands with memmap = True:
mem_band = img.read_band(0, use_memmap = True)
Reading a single band results in an array of shape (lines, samples) with dtype: float64 and where lines and sample correspond to the respective values in the .hdr file.
However, trying to apply the .open_memmap() method to the BsqFile instance as follows:
mem = img.open_memmap(writable = True)
results in the following error:
Runtime error
Traceback (most recent call last):
File "<string>", line 1, in <module>
File
"/path/to/module/spectral/io/spyfile.py", line 809, in open_memmap dst_inter))
File "/path/to/lib/site-packages/numpy/core/fromnumeric.py", line 536, in transpose
return _wrapit(a, 'transpose', axes)
File "/path/to/lib/site-packages/numpy/core/fromnumeric.py", line 45, in _wrapit
result = getattr(asattr(obj), method)(*args, **kwds)
ValueError: axes don't match array
Is this due to some incompatibilities between the numpy version that comes with the ArcMap-Python-Installation which I am required to use (numpy version 1.9.2)? Or are there other issues with the code or set-up?
Python version: 2.7.10
numpy version: 1.9.2
spectral version: 0.23.1
Edit
With the given Python version, spectral.envi.create_image() cannot create images of the given size due to an OverflowError. Potentially, this older Python version does not handle large numbers "correctly"?
Using another Python installation, the .open_memmap() method worked without issues.

Reading 3D DICOM volume into Python gives "sitk::ERROR: The file in the series have unsupported 3 dimensions"

I am using SimpleITK on Python 3.7.3 on Anaconda Spyder on CentOS 7. I have also installed Aliza and am trying to read a sample volume, /usr/share/aliza/datasets/DICOM/00_MR/PS_0.dcm into Python to process it with numpy. However the following Python code.
import SimpleITK as sitk
reader = sitk.ImageSeriesReader()
dicom_names = reader.GetGDCMSeriesFileNames( inputSeriesName )
reader.SetFileNames(dicom_names)
image = reader.Execute()
results in
Traceback (most recent call last):
File "<ipython-input-38-8c1737986203>", line 1, in <module>
image = reader.Execute()
File "/home/peter/anaconda3/lib/python3.7/site-packages/SimpleITK/SimpleITK.py", line 8473, in Execute
return _SimpleITK.ImageSeriesReader_Execute(self)
RuntimeError: Exception thrown in SimpleITK ImageSeriesReader_Execute: ../../Code/IO/src/sitkImageSeriesReader.cxx:163:
sitk::ERROR: The file in the series have unsupported 3 dimensions.
I can read in a series of 2D images, that can stack to a volume, but not all DICOM volumes come that way
I guess that when you use the ImageSeriesReader class, SimpleITK is expecting a series of 2d images. Since you don't have a series of images, but rather a single 3d image, try using the ReadImage function, like so:
import SimpleITK as sitk
image = sitk.ReadImage('/usr/share/aliza/datasets/DICOM/00_MR/PS_0.dcm' )

How to convert .npy(numpy) file to .png file where .npy array shape (30,256,256)?

I want to convert .npy file to .png file
from scipy.misc import toimage, imsave
img_array = np.load('MRNet-v1.0/train/sagittal/0003.npy')
print(img_array.shape)
name = "img"+str(i)+".png"
imsave(name,img_array)
shape : (30,256,256)
But getting error like
ValueError: 'arr' does not have a suitable array shape for any mode.
First of all, these scipy image tools are deprecated and will be removed in the future (beginning at scipy version 1.2.0). Instead, install imageio and then run:
import imageio
for i in range(30):
imsave("./slice_{0}.png".format(i), img_array[i,...])

How do I open geotiff images with GDAL in Python?

I am trying to run the following code:
from osgeo import gdal
import sys
# This allows GDAL to throw Python exceptions
src_ds = gdal.Open("fused.tif")
src_ds.show()
But I receive the following error:
Traceback (most recent call last):
File ".../gdalopen1.py", line 5, in module src_ds.show()
AttributeError: 'Dataset' object has no attribute 'show'
Why does this happen?
The following code opens a raster file and reads a band of the raster into a NumPy array.
from osgeo import gdal
ds = gdal.Open('input.tif', gdal.GA_ReadOnly)
rb = ds.GetRasterBand(1)
img_array = rb.ReadAsArray()
You have already opened the dataset, as Spacedman answered. GDAL is not a visualization library (at its core).
You can read the data with:
data = src_ds.ReadAsArray()
And then pass it on the your favourite plotting library.
Alternatively you could simply output to a more common 'picture' format (PNG for example), and use any viewer you like to display the result.
vmin = 0 # minimum value in your data (will be black in the output)
vmax = 1 # minimum value in your data (will be white in the output)
ds = gdal.Translate('fused.png', 'fused.tif', format='PNG', outputType=gdal.GDT_Byte, scaleParams=[[vmin,vmax]])
ds = None
The scaling is necessary to convert your data values to the 8-bit range (0-255) which commonly used for pictures.
You can do it by following.
from osgeo import gdal
gdal.UseExceptions()
ds = gdal.Open('Your Geotif image')
band = ds.getRasterBand(1)

PIL (Image) ValueError: Not a valid number of quantization tables. Should be between 1 and 4

I want to draw a rectangle on a picture and save it as a new file. what I'm doing is below:
from PIL import Image
from PIL import ImageChops
from PIL import ImageDraw
im = Image.open('the animal picture.jpg')
draw = ImageDraw.Draw(im)
draw.rectangle((69, 17, 418, 107))
im = im.convert('RGB')
im.save('new.jpg')
It gives an error message:
Traceback (most recent call last):
File "C:\Python27\draw_re.py", line 9, in <module>
im.save('new.jpg')
File "C:\Python27\lib\PIL\Image.py", line 1439, in save
save_handler(self, fp, filename)
File "C:\Python27\lib\PIL\JpegImagePlugin.py", line 471, in _save
ImageFile._save(im, fp, [("jpeg", (0,0)+im.size, 0, rawmode)])
File "C:\Python27\lib\PIL\ImageFile.py", line 494, in _save
for e, b, o, a in tile:
ValueError: Not a valid number of quantization tables. Should be between 1 and 4.
It looks like the problem in PIL - Not a valid numbers of quantization tables. Should be between 2 and 4, but the tip doesn't solve the problem. It makes batch processing impossible.
I worked it out. The problem caused by the Image and PIL libraries I am using.
I uninstalled and removed all previous installed PIL and Image libraries (there were confusion before and difficulties in original installations) so I have cross files and folders for the libraries.
I did the uninstallations through pip, and "Control Panel\All Control Panel Items\Programs and Features" in Windows as well. Also have manually removed the residues folders and files.
Pillow is the one shall be used. I downloaded a MS Windows installer from https://pypi.python.org/pypi/Pillow/2.6.1 and installed it. Run the script and it's working fine.

Categories

Resources