Reputation: 17
I would like to store the pixel brightness values of several images in a 3D array, but am unsure how to set the values of an entire 'plane' of the 3D 'cube' in one go. Here's my attempt:
imag = Image.open(imagArray[i])
imagPix[:,:,i] = self.getPixelValues(imag)
imagArray is an array of filepaths for images stored on the local computer and imagPix is the 3D array of pixel values. imagPix is initially defined as:
imagPix = np.zeros((width, height, lenImagArray))
where width and height are the dimensions of the image and lenImagArray is the number of images to be saved in the array (in this case 3). I have tried the imagPix[:,:,i] line with '0:' and ':' operators to no avail.
The specific error I receive is:
ValueError: could not broadcast input array from shape (640, 480, 3) into shape (640, 480)
The getPixelValues method returns a 2D array of pixel brightness values. Code for this is below:
def getPixelValues(self, pixImg): ## pixImg is the location of the image, not the image itself
## open image and convert to rgb
imag = Image.open(str(pixImg))
imag = imag.convert('RGB')
## get size of image
width, height = imag.size
pixData = list(imag.getdata())
pixData = [pixData[i * width:(i+1) * width] for i in xrange(height)]
## close image and return pixel array
imag.close()
return pixData
Do I have to use a for loop instead of setting all the values in one go? Thanks in advance. :)
EDIT:
Now that my problems with getdata() returning a tuple have been fixed I've run into a new problem when using numpy.mean():
pixData = np.array(imag.getdata())
pixData = [pixData[i * width:(i+1) * width] for i in xrange(height)]
pixData = np.mean(pixData, 2)
This give me the error:
ValueError: could not broadcast input array from shape (480, 640) into shape (640, 480)
So the dimensions of my array have been 'rotated' for no discernible reason.
Upvotes: 1
Views: 1320
Reputation: 19981
You are actually trying to assign a 3-dimensional array to a 2-dimensional slice. What happens is:
imag.getdata()
returns a sequence of pixel values. Those pixel values are actually (R,G,B) tuples.list(imag.getdata())
is a list of tuples.pixData
after the manipulation inside getPixelValues
is a list of lists of tuples.What you need to do about this will depend on what you actually want to happen. As it stands, your imagPix
array is clearly intended to be a 3-dimensional stack of 2-dimensional (greyscale) images. So you could convert your 3-dimensional image to 2 dimensions in some appropriate way. (It might be enough just to pull out one slice of it, or you might want to take some sort of weighted average of the colour planes, or something.)
Alternatively, perhaps you actually want imagPix
to be a 4-dimensional stack of 3-dimensional images.
Or perhaps whatever process creates those images should be creating explicitly-greyscale ones, and getPixelValues
shouldn't be converting them to RGB at all.
Upvotes: 1