I have 1,000 RGB images (64X64) which I want to convert to an (m, n) array.
I use this:
import numpy as np
from skdata.mnist.views import OfficialImageClassification
from matplotlib import pyplot as plt
from PIL import Image
import glob
import cv2
x_data = np.array( [np.array(cv2.imread(imagePath[i])) for i in range(len(imagePath))] )
print x_data.shape
Which gives me: (1000, 64, 64, 3)
Now if I do:
pixels = x_data.flatten()
print pixels.shape
I get: (12288000,)
However, I require an array with these dimensions: (1000, 12288)
How can I achieve that?
Apply the numpy method reshape() after applying flatten() to the flattened array:
x_data = np.array( [np.array(cv2.imread(imagePath[i])) for i in range(len(imagePath))] )
pixels = x_data.flatten().reshape(1000, 12288)
print pixels.shape
Try this:
d1, d2, d3, d4 = x_data.shape
then using numpy.reshape()
x_data_reshaped = x_data.reshape((d1, d2*d3*d4))
or
x_data_reshaped = x_data.reshape((d1, -1))
(Numpy infers the the value instead of -1 from original length and defined dimension d1)
You can iterate over your images array and flatten each row independently.
numImages = x_data.shape[0]
flattened = np.array([x_data[i].flatten() for i in range(numImages)])
You could also use this:
X is your 2D picture with size 32x32 for example and the -1 it simply means that it is an unknown dimension and we want numpy to figure it out. And numpy will figure this by looking at the 'length of the array and remaining dimensions' and making sure it satisfies the above mentioned criteria (What does -1 mean in numpy reshape?). T means to invert the transposition of tensors when using the axes keyword argument (https://docs.scipy.org/doc/numpy/reference/generated/numpy.transpose.html).
X_flatten = X.reshape(X.shape[0], -1).T
Assuming you have an array image_array you can use the reshape() method.
image_array = image_array.reshape(1000, 12288)
Related
I have a numpy array of images with the shape of (5879,). Inside every index of the numpy array, I have the Pixels of the image with a shape of (640,640,3).
I want to reshape the complete array in such a way that the shape of the numpy array becomes (5879,640,640,3).
please check, whether below code works for you or not
import numpy as np
b = np.array([5879])
b.shape
output (1,)
a = np.array([[640],[640],[3]])
a = a.reshape((a.shape[0], 1))
a.shape
output (3, 1)
c = np.concatenate((a,b[:,None]),axis=0)
c.shape
Output:
(4, 1)
np.concatenate((a,b[:,None]),axis=0)
output
array([[ 640],
[ 640],
[ 3],
[5879]])
You want to stack your images along the first axis, into a 4D array. However, your images are all 3D.
So, first you need to add a leading singleton dimension to all images, and then to concatenate them along this axis:
imgs = [i_[None, ...] for i_ in orig_images] # add singleton dim to all images
x = np.concatenate(imgs, axis=0) # stack along the first axis
Edit:
Based on Mad Phyiscist's comment, it seems like using np.stack is more appropriate here: np.stack takes care of adding the leading singleton dimension for you:
x = np.stack(orig_images, axis=0)
I am generating a large number of mel spectrograms to train a NN for phoneme detection.
Each mel spectrogram (generated with librosa.core.melspectrogram in Python) is represented as a 2D numpy array, where axis 1 (the length of the vectors) varies from spectrogram to spectrogram. They vary from shape (128, 2) to (128, 200).
In order to generate a 3D array, all spectrograms must have the same shape, so I'm guessing that I should append zeros to the ends of vectors that are shorter than 200. Then I can just add them all to a Python list, call np.array on it and a 3D numpy array will be generated, right?
I have attempted this myself unsuccessfully. All help is appreciated.
Edit: (code has been requested, this is essentially what I want to do)
spectrograms = []
for audio_array in all_audio_arrays:
audio_array, sr = librosa.core.load(audio_file, sr=sample_rate, mono=True)
melspectrogram = librosa.feature.melspectrogram(y=audio_array, sr=sample_rate, S=None, n_fft=window_size, hop_length=hop_length)
# melspectrogram is a 2D numpy array
# the shape could be between (128, 2) and (128, 200)
spectrograms.append(melspectrogram)
# I want this to be 3D
np.asarray(spectrograms)
I can't answer if it's an appropriate approach for your learner to pad with zeros. But doing so is quite easy using np.concatenate
import numpy as np
a = np.ones((128,2))
b = np.ones((128,200))
padding = np.zeros((a.shape[0], b.shape[1] - a.shape[1])) #(128, 198)
a = np.concatenate((a, padding), axis=1)
print (a.shape)
>>> (128L, 200L)
Is there a numpythonic way to do this? Original array is of dimension N x M x 3, I'd like to make a N x M mask as shown. I thought there was a simple way to write this with Numpy but I'm having brain freeze.
While there may be alternative ways to implement this, I'm trying to do it this way to maintain my skills at using Numpy indexing.
This fails because img2[test] looses the original shape. Do I have to .reshape() somehow, or is there simpler way where I don't need to explicitly restate the dimensions of the axes?
import numpy as np
import matplotlib.pyplot as plt
img = np.random.random(100*100*3).reshape(100, 100, -1)
img2 = img.copy()
target = np.array([0.5, 0.3, 0.7])
test = np.abs(img - target) < 0.5
img2[test] = np.zeros(3) # probem, img2[test] looses its shape
plt.figure()
plt.imshow(np.hstack((img, img2)))
plt.show()
File "/Users/yournamehere/Documents/fishing/Eu;er diagram/stackexchange question v00.py", line 12, in <module>
img2[test] = target
ValueError: NumPy boolean array indexing assignment cannot assign 3 input values to the 11918 output values where the mask is true
Here's a one-liner showcasing the very useful keepdims kwarg
np.where(np.logical_and.reduce(test, axis=-1, keepdims=True), [0, 0, 0], img)
Brain has un-frozen. Forgot to use .all() to collape the test to a single boolean value for each N x M location. Once that is corrected, Numpy does it's thing very nicely.
import numpy as np
import matplotlib.pyplot as plt
img = np.random.random(100*100*3).reshape(100, 100, -1)
img2 = img.copy()
target = np.array([0.5, 0.3, 0.7])
test = (np.abs(img - target) < 0.5).all(axis=-1)
img2[test] = np.zeros(3) # probem, img2[test] looses its shape
plt.figure()
plt.imshow(np.hstack((img, img2)))
plt.show()
I'm using python / Numpy to store small images into ndarray.
I'm stuck when I'm trying to transform an ndarray from 32,32,1 shape to 1,32,32,1. Any help ? Thanks
You need to expand the dimensions of the numpy array. Use np.expand_dims.
arr = np.expand_dims(arr, axis=0)
arr[np.newaxis, :, :, :] will work
Instead of explicitly adding an axis you could also explicitly reshape it to add the axis:
>>> import numpy as np
>>> arr = np.ones((32, 32, 1)) # just ones for demonstration purposes
>>> reshaped = arr.reshape(1, *arr.shape)
>>> reshaped.shape
(1, 32, 32, 1)
I am running this code
from PIL import Image
import numpy as np
im = Image.open("/Users/Hugo/green_leaves.jpg")
im.load()
height, widht = im.size
p = np.array([0,0,0])
for row in range(height):
for col in range(widht):
a = im.getpixel((row,col))
p = np.append(a.asarray())
But I am getting the following error
Traceback (most recent call last):
File "/Users/hugo/PycharmProjects/Meteo API/image.py", line 17, in <module>
p = np.append(a.asarray())
AttributeError: 'tuple' object has no attribute 'asarray'
Could you help me?
You mentioned numpy. If you want a numpy array of the image, don't iterate through it, just do data = np.array(im).
E.g.
from PIL import Image
import numpy as np
im = Image.open("/Users/Hugo/green_leaves.jpg")
p = np.array(im)
Building up a numpy array by repeatedly appending to it is very inefficient. Numpy arrays aren't like python lists (python lists serve that purpose very well!!). They're fixed-size, homogenous, memory-efficient arrays.
If you did want to build up a numpy array through appending, use a list (which can be efficiently appended to) and then convert that list to a numpy array.
However, in this case, PIL images support being converted to numpy arrays directly.
On one more note, the example I gave above isn't 100% equivalent to your code. p will be a height by width by numbands (3 or 4) array, instead of a numpixels by numbands array as it was in your original example.
If you want to reshape the array into numpixels by numbands, just do:
p = p.reshape(-1, p.shape[2])
(Or equivalently, p.shape = -1, p.shape[2])
This will reshape the array into width*height by numbands (either 3 or 4, depending on whether or not there's an alpha channel) array. In other words a sequence of the red,green,blue,alpha pixel values in the image. The -1 is a placeholder that tells numpy to calculate the appropriate shape for the first axes based on the other sizes that are specified.
Initialize p as a list, and convert it to a numpy array after the for-loop:
p=[]
for row in range(height):
for col in range(widht):
a = im.getpixel((row,col))
p.append(a)
p=np.asarray(p)
This will create a list of shape (*, 3), which is same as np.array(im).reshape(-1, 3). So if you need this, just use the latter form ;)