I have a numpy array Data of 1D of size [36*64]. Basically, I have 36, 8*8 images stored in a 1D array. Each image is stored in Height(8)*Width(8) format.
For e.g.: ith image is stored from Data[i*8*8 : (i*8*8 + 8*8)].
Now I want to make a tile of images from the given 36 images, i.e. 6 images stacked on top of each other. Example.
Basically, I want to transform my 1D Numpy array into a 2D array of images in the above mentioned format.
I would prefer answers with just using Numpy methods.
To convert your 1D array to 2D use reshape as shown with an example:
# Creating 36 images each of shape 8x8
initial_1D = np.random.randn(2304).reshape(36, 8, 8)
Collage can be formed using PIL. For clear understanding refer here Making a collage in PIL
If I understand you correctly, you can do it like this
# make example data
a = np.linspace(0, 36*64-1, 36*64)
print(a[:64])
print(a.shape)
# reshape 1D to 3D array
b = a.reshape(-1, 8, 8)
# look at first "image"
print(b[0])
If I did not understand you correctly, you need to put the -1, 8, 8 in a different order.
Related
Suppose my image is 256x256x1. I need to reshape each 8x8x1 block in the image to a vector, which will result in a 32x32x64 tensor, in which each of the 1x1x64 vectors is the reshaped version of the corresponding 8x8 block. How could I do this with numpy or cv2?
You can perform a series of reshapes and transpositions to get the result you want. For example, start by splitting the existing dimensions to add more:
a = a.reshape(32, 8, 32, 8)
The reshape does not need to copy data. Now move the dimensions you want to group to the back:
a = a.transpose(0, 2, 1, 3)
This creates a copy of the array with the blocks you want arranged contiguously. Now you can reshape just the blocks:
a = a.reshape(32, 32, 64)
This reshape won't copy any data either since you are preserving the memory layout.
I have a ndarray of shape (68, 64, 64) called 'prediction'. These dimensions correspond to image_number, height, width. For each image, I have a tuple of length two that contains coordinates that corresponds to a particular location in each 64x64 image, for example (12, 45). I can stack these coordinates into another Numpy ndarray of shape (68,2) called 'locations'.
How can I construct a slice object or construct the necessary advanced indexing indices to access these locations without using a loop? Looking for help on the syntax. Using pure Numpy matrixes without loops is the goal.
Working loop structure
Import numpy as np
# example code with just ones...The real arrays have 'real' data.
prediction = np.ones((68,64,64), dtype='float32')
locations = np.ones((68,2), dtype='uint32')
selected_location_values = np.empty(prediction.shape[0], dtype='float32')
for index, (image, coordinates) in enumerate(zip(prediction, locations)):
selected_locations_values[index] = image[coordinates]
Desired approach
selected_location_values = np.empty(prediction.shape[0], dtype='float32')
correct_indexing = some_function_here(locations). # ?????
selected_locations_values = predictions[correct_indexing]
A straightforward indexing should work:
img = np.arange(locations.shape[0])
r = locations[:, 0]
c = locations[:, 1]
selected_locations_values = predictions[img, r, c]
Fancy indexing works by selecting elements of the indexed array that correspond to the shape of the broadcasted indices. In this case, the indices are quite straightforward. You just need the range to tell you what image each location corresponds to.
I am currently working on a project where i am trying to create a machine learning model that is able to classify actions in a video. I already created a script that is able to detect a person in a video and generate data based on the movements of the body parts. This generates a 4D array with the following input shape:
(nframes, nperson, nbodyparts, 3 coördinates per body part)
The input shape of just 1 video (2 persons) with a duration of 3 second and filmed in 60fps/s will look like this:
(180, 2, 25, 3)
The 4D array for every video is saved as a numpy file, so if i process 400 video's. I will get 400 numpy files.
The next step is to create a keras or tensorflow RNN-LSTM model that is able to train on the 400 numpy files and able to work with the 4D array of every video, but i really don't know how to get this to work. I already searched for some solutions but the only thing i could fine is that Keras is only able to work with 3D array.
I really would appreciate your help and view on how i could solve this, with hopefully an example code.
King regards,
I assume you are using numpy.array. Reshaping the 4d array into 3d could be done by np.resahpe(). Documentation can be found here.
Example:
import numpy as np
# create a sample 4d array data of shape (10, 2, 25, 3)
data = np.arange(10*2*25*3).reshape((10, 2, 25, 3))
# condense the 4d array to 3d array by explicitly stating the shape.
data_reshaped = data.reshape((10, 2, 75))
# or you can use -1 to ask numpy infer the dimension
data_reshaped2 = data.reshape((10, 2, -1))
# you can also reshape your data into 2d of shape (10, 150)
data_reshaped3 = data.reshape((10, -1))
Then, you can follow tutorials online to build your model. An example tutorial could be this.
Note: You mentioned that "Keras is only able to work with the 3D array." I think one of the dimension is reserved for batch_size. So, I suggest you should convert your 4d array into 2d.
I have an numpy array X which contains 2d images. numpy array dimensions are (1000,60,40) (1000=no.of img).
I want to feed this array to my model but requires dimensions to be
(1000,60,40,1) (appended 1 is for no. of channels).
so i reshape the array by
Y=X.reshape(1000,60,40,1)
as I was having wrong predictions I checked by re-reshaping the reshaped array to check if it was same as my orig img,
I did that by doing
Z=Y.reshape(1000,60,40)
And I saved them as PNG by doing
for i in range(1000):
misc.imsave('img_rereshaped'+str(i)+'.png',Z[i])
It gives some png files as output but they are not same as the respective original ones from the X numpy array
Am I reshaping in the wrong way or reshaping changes the input data and again reshaping the reshaped data would give different result than the original data?
To test whether the reshaping is causing a problem, it's better to test it without involving other potential errors coming from, say, misc.imsave() etc.
Running something like:
import numpy as np
a = np.random.rand(10,3)
b = np.reshape(a, [10, 3, 1])
c = np.reshape(b, [10, 3])
print(np.sum(c - a))
you'll see that going back and forth using reshape doesn't cause a problem.
Could be you're not using the PNG save correctly. Perhaps the function expects 3 channels for example. Try plotting it locally using matplotlib.
I am trying to create an empty numpy array, and save all the images that I get from my device. The images come in as numpy array of shape (240,320,3). Creating an empty array to store these images seems like the correct thing to do. When I try to append however, I get this error:
ValueError: all the input arrays must have same number of dimensions
Code as follows:
import numpy as np
# will be appending many images of size (240,320,3)
images = np.empty((0,240,320,3),dtype='uint8')
# filler image to append
image = np.ones((240,320,3),dtype='uint8') * 255
images = np.append(images,image,axis=0)
I need to append many images to this array, so after 100 appends, the shape of the images array should be of shape (100,240,320,3) if done correctly.
Better than np.append is:
images = np.empty((100,240,320,3),dtype='uint8')
for i in range(100):
image = ....
images[i,...] = image
or
alist = []
for i in range(100):
image = ....
alist.append(image)
images = np.array(alist)
# or images = np.stack(alist, axis=0) for more control
np.append is just a cover for np.concatenate. So it makes a new array each time through the loop. By the time you add the 100th image, you have copied the first one 100 times!. The other disadvantage with np.append is that you have to adjust the dimensions of image, a frequent source of error. The other frequent error is getting that initial 'empty' array shape wrong.
Your images array has four dimensions, so you must append a four dimensional item to it. To do so, simply add a new axis to image like so:
images = np.append(images,image[np.newaxis, ...], axis=0)
In a sense, when passing an axis numpy.append is more akin to list.extend than list.append.