22

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?

apples-oranges
  • 959
  • 2
  • 9
  • 21

5 Answers5

11

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
Ray
  • 40,256
  • 21
  • 101
  • 138
  • Neat! Will this preserve the original image properties i.e. I don’t lose any pixel information? – apples-oranges May 01 '16 at 15:07
  • 2
    `Flatten()` and `reshape()` are be lossless. The dimensions of the resulting array should always multiply to be the same total. Flatten has a `shape()` as a 1-D array, not an n-D array, hence no second value for its shape. It looks like `array([1, 2, 3,])`. An n-D with shape (3,1) array would look like `array([[1],[2],[3]])`. – Ray May 01 '16 at 15:23
  • 1
    Here's a great SO post on shaping: http://stackoverflow.com/questions/22053050/difference-between-numpy-array-shape-r-1-and-r – Ray May 01 '16 at 15:29
  • 2
    @apples-oranges also, depending on what you're doing, you might just want to `reshape` the original data directly--flatten creates a restructured copy of the data you might not need. `x_data.reshape(1000, 12288)` – Ray May 01 '16 at 15:57
  • Thanks again for the tip! The plan is to parse the array through the t-SNE algorithm :-). – apples-oranges May 01 '16 at 16:15
9

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)

Břetislav Hájek
  • 3,056
  • 2
  • 15
  • 17
lskrinjar
  • 5,483
  • 7
  • 29
  • 54
3

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)])
zr0gravity7
  • 2,917
  • 1
  • 12
  • 33
James Evans
  • 830
  • 8
  • 12
3

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
Community
  • 1
  • 1
Sal.te
  • 115
  • 7
  • It would be helpful if you were to elaborate a bit on this, as it might better help others understand your solution. – Jeffrey Feb 12 '20 at 21:24
0

Assuming you have an array image_array you can use the reshape() method.

image_array = image_array.reshape(1000, 12288)
Eeshaan
  • 1,557
  • 1
  • 10
  • 22