My numpy array (name: data) has following size: (10L,3L,256L,256L).
It has 10 images with each 3 color channels (RGB) and each an image size of 256x256 pixel.
I want to compute the mean pixel value for each color channel of all 10 images. If I use the numpy function np.mean(data), I receive the mean for all pixel values. Using np.mean(data, axis=1) returns a numpy array with size (10L, 256L, 256L).
If I understand your question correctly you want an array containing the mean value of each channel for each of the three images. (i.e. an array of shape (10,3) ) (Let me know in the comments if this is incorrect and I can edit this answer)
If you are using a version of numpy greater than 1.7 you can pass multiple axes to np.mean as a tuple
mean_values = data.mean(axis=(2,3))
Otherwise you will have to flatten the array first to get it into the correct shape.
mean_values = data.reshape((data.shape[0], data.shape[1], data.shape[2]*data.shape[3])).mean(axis=2)
Related
This question already has an answer here:
How would I find the mode (stats) of pixel values of an image?
(1 answer)
Closed 2 years ago.
I have an image of a dog, which has shape (432, 575, 4). The 3rd dimension in the ndarray contains the RGBA values for each pixel. I want to find out what the most common pixel is, i.e. the mode.
For a 2d array, I can use the following line: np.unique(a, axis=0, return_counts=True)
However, I can't work out how to only compare the vectors in the 3rd dimension of a 3d array. This question is similar, but it only works for a 2d array: Finding the most common subarray within a numpy array. If I simply change the axis to '=1`, it doesn't give me the result that I need.
Since you don't care for the image's shape, you can use reshape to flatten your image and use the linked answer:
rgba, counts = np.unique(a.reshape(-1,4), axis=0, return_counts=True)
# the mode here
rgba[np.argmax(counts)]
I have a 3D image which is a numpy array of shape (1314, 489, 3) and looks as follows:
Now I want to calculate the mean RGB color value of the mask (the cob without the black background). Calculating the RGB value for the whole image is easy:
print(np.mean(colormaskcutted, axis=(0, 1)))
>>[186.18434633 88.89164511 46.32022921]
But now I want this mean RGB color value only for the cob. I have a 1D boolean mask
array for the mask with this shape where one value corresponds to all of the 3 color channel values: (1314, 489)
I tried slicing the image array for the mask, as follows:
print(np.mean(colormaskcutted[boolean[:,:,0]], axis=(0, 1)))
>>124.57794089613752
But this returned only one value instead of 3 values for the RGB color.
How can I filter the 3D numpy image for a 1D boolean mask so that the mean RGB color calculation can be performed?
If your question is limited to computing the mean, you don't necessarily need to subset the image. You can simply do, e.g.
np.sum(colormaskcutted*boolean[:,:,None], axis = (0,1))/np.sum(boolean)
P.S. I've played around with indexing, you can amend your original approach as follows:
np.mean(colormaskcutted[boolean,:], axis = 0)
P.P.S. Can't resist some benchmarking. So, the summation approach takes 15.9s (1000 iterations, dimensions like in the example, old computer); the advanced indexing approach is slightly longer, at 17.7s. However, the summation can be optimized further. Using count_nonzero as per Mad Physicist suggestion marginally improves the time to 15.3s. We can also use tensordot to skip creating a temporary array:
np.tensordot(colormaskcutted, boolean, axes = [[0,1], [0,1]])/np.count_nonzero(msk)
This cuts the time to 4.5s.
Suppose I have a numpy array A which can be of any dimensions len(A.shape) can be 1,2,3,..etc. and a corresponding array, crop which len(crop) = len(A.shape) and I want to extract the interior values of A using crop. Here is an example for 2D array.
A = np.random.rand(30).reshape([5,6])
crop = np.array([1,2])
Wanted output:
A[crop[0]:-crop[0], crop[1]:-crop[1])
Assuming value of crop will be reasonable with respect to size of A. How do I do this for any dimension of array A ?
Here's one way with slice notation -
A[tuple([slice(i,-i,None) for i in crop])]
Or with the shorthand np.s_ -
A[tuple([np.s_[i:-i] for i in crop])]
If the start and end indices are given for each dimension, we can do something like as shown in Slicing NumPy array given start and end indices for generic dimensions.
I have a numpy array of size 5000x32x32x3. The number 5000 is the number of images and each image is 32x32 in width and height and has 3 color channels.
Now I would like to create a numpy array of shape 5000x3x32x32 in a way that the data is preserved.
What I mean by preserving data is :
There should be 5000 data points in the resulting array
The 2nd dimension (3) of the array correctly determines the color channel i.e all the elements whose 2nd dimension is 0 belong to red channel, whose 2nd dimension is 1 belong to green channel,whose 2nd dimension is 2 belong to blue channel.
Simply reshaping the by np.reshape(data,(5000,3,32,32)) would not work as it would not preserve the channels but just reshape the data into the desired shape.
I think you are looking for a permutation of the axes, numpy.transpose can get this job done:
data = np.transpose( data, (0, 3, 1, 2))
I have an image's numpy array of shape (224,224,4). Each pixel has 4 dimension - r,g,b,alpha. I need to extract the (r,g,b) values for each pixel where it's alpha channel is 255.
I thought to first delete all elements in the array where alpha value is <255, and then extract only the first 3 values(r,g,b) of these remaining elements, but doing it in simple loops in Python is very slow. Is there a fast way to do it using numpy operations?
Something similar to this? https://stackoverflow.com/a/21017621/4747268
This should work: arr[arr[:,:,3]==255][:,:,:3]
something like this?
import numpy as np
x = np.random.random((255,255,4))
y = np.where(x[:,:,3] >0.5)
res = x[y][:,0:3]
where you have to fit > 0.5 to your needs (e.g. ==255). The result will be a matrix with all pixels stacked vertically