How to reshape an array containg image data - python

I have 4554 images in my numpy array X_train with the shape of the array as follows.
print(np.shape(X_train))
(4554,) # TOtal numbe of images
X_train[0].shape
(120, 120, 4) # Each image is 120x120 with 4 channels.
Now I want to reshape the array into (4554, 120, 120, 4), so that when I print
print(np.shape(X_train)
It gives me the shape (4554, 120, 120, 4) instead of (4554,).
I tried the following reshape method but it gives me error.
X_train=X_train.reshape((X_train.shape[0],X_train[0].shape))
Error: TypeError: 'tuple' object cannot be interpreted as an integer

You're looking for the numpy.stack() method.
If you have a list of 3d matrices, you can make a 4d matrix like so:
numpy.stack(your_list_of_training_data, axis=0)
See the documentation here for an explanation: https://docs.scipy.org/doc/numpy-1.10.1/reference/generated/numpy.stack.html

To convert 2D array to 4D, try to flat 2D array first and then reshape as below , hope it works.
num_images = 4554
X_train_flat = [img.flatten() for img in X_train]
X_train_flat = np.array(X_train_flat)
X_train = X_train_flat.reshape(num_images, 120, 120, 4)

Related

Turn x numpy arrays with dimensions [n, m] into a single array with dimensions [x, n, m] in Python [duplicate]

This question already has answers here:
Numpy stack in the first dimension?
(3 answers)
Closed 1 year ago.
I am doing some image processing in Python. I have a set of grey scale images (512 x 512) saved in a stacked .tif file with 201 images. When I open this file with skimage.io.imread, it generates a 3D array with dimensions [201, 512, 512], allowing me to easily iterate over each greyscale image - which is what I desire.
After performing some operations on these images, I have a list of ten 2D arrays, which I want to put back into the same dimension format that skimage.io.imread produced - ie. [10, 512, 512].
Using numpy.dstack produces an array with dimension [512, 512, 10]. And numpy.concatenate does not do the job either.
How can I turn this list of 2D arrays into a 3D array with the dimensions specified above?
One solution is considering you have an array of shape [512, 512, 10] and move the last axis to the first:
import numpy as np
imgs = np.random.random((512, 512, 10))
imgs = np.moveaxis(imgs, -1, 0)
print(imgs.shape)
# (10, 512, 512)
The other ways is to use np.vstack() like:
import numpy as np
# List of 10 images of size (512 x 512) each
imgs = [np.random.random((512, 512)) for _ in range(10)]
output = np.vstack([x[None, ...] for x in imgs])
print(output.shape)
# (10, 512, 512)
The most general solution is to use plain np.stack and specify which axis you want to add to the array.
Taking the notation from #amrind's answer:
result = np.stack(imgs, axis=0)
This is roughly equivalent to just doing
result = np.array(imgs)

Convert a 3d array to a 4d array

I have a matrix and I am obtaining a 2 channel matrix with images having size 256x120.
Now, I need to store several images so I need to reshape my matrix to (No.ofimages,256,120,2).
I tried to use reshape and then append:
But I am getting a TypeError: 'builtin_function_or_method' object is not subscriptable when using reshape
Any ideas on how I can solve it?
Based on my current understanding of your issue:
import numpy as np
img = np.random.random((112,112,2))
print(img.shape)
result = np.empty((0, 112, 112, 2)) # first axis is zero, for adding images along it
for i in range(100): # replace this loop with something that reads in the images
result = np.append(result, img[np.newaxis, ...], axis=0) # add a new axis to each image and append them to result
print(result.shape)
Will produce:
(112, 112, 2)
(100, 112, 112, 2)
To access the images stored in the result variable, simply use indexing:
print(result[1].shape) # e.g., access the second image
Will produce:
(112, 112, 2)

Creating 4D arrays from 3D arrays in Python

I'm having trouble getting a series of 3D "images" stored as a single 4D array. The code below is what I'm using to convert the 2D 640x512 images from the camera into a 3D array.
listImage = []
for i in range(492):
fname = '2019-12-04_11-59-12' + str(i) + '.fits'
fits_import = FITS.Read('Run 4\\' + fname)
listImage.append(fits_import[1])
arrayListImage = np.asarray(listImage)
The result, "arrayListImage", has a shape of [492, 640, 512]. Using the same code to read in 2 3D arrays results in an array of shape (2,). The type of "fits_import[1]" is a numpy.ndarray.
I expected this to return an array of shape [2, 492, 640, 512]. Why is this method not consistent in going to 4D?
Use np.stack instead of np.asarray:
arrayListImage = np.stack(listImage, axis=0)

np.reshape 1d array to 2d array - choosing right dimensions

I'm trying to reshape a 1d array to a 2d array with numpy's reshape:
import numpy as np
inputArray =np.random.randint(low=0, high=4, size=160000)
inputArray_ = inputArray.reshape(-1,4000, 4000,4)
Which returns a value error:
ValueError: cannot reshape array of size 160000 into shape (400,400,4)
Use
inputArray_ = np.reshape(inputArray, (-1, 2))
Or
inputArray_ = np.reshape(inputArray, (len(inputArray)/2,2))
since 400*400*4 = 640,000 is bigger than 160000 you cannot reshape.
You don't have enough values to fill the new shape.
640,000-160,000 = 480,000. you lack 480,000 values.
divide your shape of 160000 by the other dimensions-multiplicated, if a int is the result, it works.
e.g.
inputArray_ = inputArray.reshape(-1,40, 40, 10)
this will result in a shape of [10,40,40,10]
since 160000 / (40*40*10) = 10 ---> 10 is the dim that the "-1" takes

Understanding numpy shape

I'm newbie with Python and also with Numpy.
I have this code:
one_array.shape
When I run it, I get this output:
(20, 48, 240, 240)
one_array is a Numpy Array that has 20 images.
What do mean the other three numbers in shape output (48, 240, 240)?
Your array consist of 20 images, each of them is the size 48X240X240. Which is odd, I would expect that it will be something like 240X240X3 but for some reason you have way more channels (referring to RGB). ]
So the shape function return the size of dimension along each axis (the current shape of the entire array), so in your case there is (20, 48, 240, 240)
Edit:
As the user said, each image consist of 48 NITFY images of 1 channel which explain the output of shape
Imagine your Numpy Array as a Vector that can be in one dimension, but in your case it looks like it is in dimension 4.
(20, 4, 240, 240) means a big matrix composed of 20 x 4 x 240 x 240 elements.
one_array.shape == (20, 48, 240, 240) means that one_array is a 4-dimensional array with 20*48*240*240 or 55296000 elements.
You are right, you can think of one_array as an array with 20 elements, in which is element in another array with shape (48, 240, 240). However, usually is it better to think that one_array is a 4 dimensional array, that has a total of 20x48x240x240 = 55296000 elements.

Categories