I’m new to python/numpy prorammation.
I have a 3-dimensional array representing an image (x and y axis) and each point of the image is associated with a pixel with its rgb values:
So for example:
a = np.array([[[0, 2, 2], [1, 3, 2]], [[1, 4, 5], [6, 5, 3]]])
I'd like to compute the mean of the R, G, and B color channels over the image.
For exemple (0+1+1+6)/4, (2+3+4+5)/4, (2+2+5+3)/4.
And i have to use the function numpy.mean.
I’ve tested several things by slicing but I feel it’s not the right thing to do: (patch == image)
enter image description here
thx for your help !
Let us consider this array rgb
array([[[1, 1, 1],
[1, 2, 3],
[4, 5, 6]],
[[1, 2, 3],
[0, 0, 0],
[1, 0, 0]]])
Then mean values for each channel we can get it by
import numpy as np
rgb = np.array([[[1,1,1],[1,2,3],[4,5,6]],[1,2,3],[0,0,0],[1,0,0]]])
print(rgb.shape)
rgb_mean = np.mean(np.mean(rgb, axis=1), axis=0)
print(rgb_mean)
rgb_mean = rgb_mean.astype(np.uint8)
print(rgb_mean.shape)
print(rgb_mean)
output
(2, 3, 3)
array([1.33333333, 1.66666667, 2.16666667])
(3,)
array([1, 1, 2], dtype=uint8)
Related
I hava a image of white objects on black backgorund. How can I get array of coordinates of all white pixels of separated objects on picture? I am using OpenCV and Python.
If I have an matrix like this (1=255):
m = np.array([
[1,1,0,1,1],
[1,1,0,1,1],
[1,0,0,0,0],
[0,0,0,1,1],
[0,0,0,1,1],])
I should get matrix of coordinates like this:
[
[(0,0),(0,1),(1,0),(1,1),(2,0)]
[(0,3),(0,4),(1,3),(1,4)]
[(3,3),(3,4),(4,3),(4,4)]
]
I know there is a function findContoures (and I was using this: cnts = cv2.findContours(m, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)) but it doesn't give me all coordinates.
I don't totally follow the structure of the expected output but np.argwhere can probably do what you want. For example, this:
np.argwhere(m == 1)
Gives you this:
array([[0, 0],
[0, 1],
[0, 3],
[0, 4],
[1, 0],
[1, 1],
[1, 3],
[1, 4],
[2, 0],
[3, 3],
[3, 4],
[4, 3],
[4, 4]])
Maybe you can consider using connectedComponents instead of findContoures.
Say I have two matrices, A and B:
A = np.array([[1, 3, 2],
[2, 2, 3],
[3, 1, 1]])
B = np.array([[0, 1, 0],
[1, 1, 0],
[1, 1, 1]])
I want to take one column in A and multiply it by each column in B element-wise, then proceed to the next column in A. So, using just one column as an example, I will use A[:,0] (values 1,2,3), and multiply it by each column in B to get this:
array([[0, 1, 0],
[2, 2, 0],
[3, 3, 3]])
I've implemented this using np.einsum like so:
np.einsum('i,ij->ij',A[:,0],B)
I then want to generate a 3D matrix with the depth dimension corresponding to the multiplication by each column in A, which I implemented using a for loop:
np.stack([np.einsum('i,ij->ij',A[:,i],B) for i in range(0,A.shape[1])])
This returns my desired array:
array([[[0, 1, 0],
[2, 2, 0],
[3, 3, 3]],
[[0, 3, 0],
[2, 2, 0],
[1, 1, 1]],
[[0, 2, 0],
[3, 3, 0],
[1, 1, 1]]])
How would I go about doing this without the loop? Can this be done purely with np.einsum? Is there another function in NumPy that will do this more simply?
Here's a simple way:
A.T[:,:,None]*B
adding the last None in indexing creates a new axis which is then used for broadcasting the elementwise multiplication.
How about this code?
A.T.reshape(3, 3, 1) * B
Reshaping ndarray can make doing many things...
Keeping with your usage of einsum:
np.einsum('ij,ik->jik', A, B)
I have an n x m x 3 numpy array. This represents a middle-step towards an RGB representation of a complex-function plotter. When the function being plotted takes infinite values or has singularities, parts of the RGB data become NaNs.
I'm looking for an efficient way to replace a row containing a NaN with a row of my choice, perhaps [0, 0, 0] or [1, 1, 1]. In terms of the RGB values, this has the effect of replacing poorly-behaving pixels with white or black pixels. By efficient, I mean some way that takes advantage of numpy's vectorization and speed.
Please note that I am not looking to merely replace the NaN values with 0 (which I know how to do with numpy.where); if a row contains a NaN, I want to replace the whole row. I suspect this can be done nicely in numpy, but I'm not sure how.
Concrete Question
Suppose we are given a 2 x 2 x 3 array arr. If a row contains a 5, I want to replace the row with [0, 0, 0]. Trivial code that does this slowly is as follows.
import numpy as np
arr = np.array([[[1, 2, 3], [4, 5, 6]], [[1, 3, 5], [2, 4, 6]]])
# so arr is
# array([[[1, 2, 3],
# [4, 5, 6]],
#
# [[1, 3, 5],
# [2, 4, 6]]])
# Trivial and slow version to replace rows containing 5 with [0,0,0]
for i in range(len(arr)):
for j in range(len(arr[i])):
if 5 in arr[i][j]:
arr[i][j] = np.array([0, 0, 0])
# Now arr is
#
# array([[[1, 2, 3],
# [0, 0, 0]],
#
# [[0, 0, 0],
# [2, 4, 6]]])
How can we accomplish this taking advantage of numpy?
A simpler way would be -
arr[np.isin(arr,5).any(-1)] = 0
If it's just a single value that you are looking for, then we could simplify to -
arr[(arr==5).any(-1)] = 0
If you are looking to match against NaN, we need to do the comparison differently and use np.isnan instead -
arr[np.isnan(arr).any(-1)] = 0
If you are looking to assign array values, instead of just 0, the solutions stay the same. Hence it would be -
arr[(arr==5).any(-1)] = new_array
Using np.broadcast_to
arr[np.broadcast_to((arr == 5).any(-1)[..., None], arr.shape)] = 0
array([[[1, 2, 3],
[0, 0, 0]],
[[0, 0, 0],
[2, 4, 6]]])
Just as FYI, based on your description, if you want to find np.nans instead of integers like 5, you shouldn't use ==, but rather np.isnan
arr[np.broadcast_to((np.isnan(arr)).any(-1)[..., None], arr.shape)] = 0
you can do it using in1d function like below
arr = np.array([[[1, 2, 3], [4, 5, 6]], [[1, 3, 5], [2, 4, 6]]])
arr[np.in1d(arr,5).reshape(arr.shape).any(axis=2)] = [0,0,0]
arr
Hi I want to extract a nested list's elements at diagonal above with numpy.tril. From my understanding, set parameter k>0, it will return diagonal above. However, my code doesn't return the result expected.
np.tril([[1,2,3],[4,5,6],[7,8,9]], 1)
>>> array([[1, 2, 0],
[4, 5, 6],
[7, 8, 9]])
expected output:
array([1,2,3],
[4,5,0],
[7,0,0,])
You can flip the array, get the upper triangle, then flip it back:
In [1]: import numpy as np
In [2]: a = np.array([[1,2,3],[4,5,6],[7,8,9]])
In [3]: np.triu(a[:, ::-1])[:, ::-1]
Out[3]:
array([[1, 2, 3],
[4, 5, 0],
[7, 0, 0]])
Two issues. First, np.tril (as indicated in its name) gives a lower diagonal. Second, triangular arrays are conventionally the mirror image of your desired output.
We can take a peek at the source code for np.triu and adapt it for a new triu_anti function via np.fliplr:
def triu_anti(m, k=0):
m = np.asanyarray(m)
mask = np.fliplr(np.tri(*m.shape[-2:], k=k-1, dtype=bool))
return np.where(mask, np.zeros(1, m.dtype), m)
res = triu_anti([[1,2,3],[4,5,6],[7,8,9]])
print(res)
# array([[1, 2, 3],
# [4, 5, 0],
# [7, 0, 0]])
Using T for twice
np.tril(a.T,0).T
array([[1, 2, 3],
[0, 5, 6],
[0, 0, 9]])
I want to fill a numpy.ndarray with data (32x32 pixel integer pictures==arrays)
From the name of the file of the picture I know where in my ndarray I want my values to be stored.
I would like to give my ndarray a list but also some slice(0) in it, because the picture is stored in the last two dimensions. How do I do that?
I would like to do something like
Pesudocode:
data=numpy.ndarray(dim1,dim2,dim3,32,32)
list=function(filename)
data[list,slice(0),slice(0)]=read_image(filename)
Is that possible?
My list has entries specifying the positions of the ndarray [int,int,int] and my read image is a 32 times 32 integer array (filling the last two dimension of my ndarray).
To perform this assignment, pass a suitable array in each of the first three dimensions, and : (meaning entire index range) in the last two dimensions.
If your list is, for example,
list = [[1, 2, 3], [4, 2, 0], [5, 3, 4], [2, 2, 2]]
then the array to pass as the first index is [1, 4, 5, 2], and similarly for two others: [2, 2, 3, 2] and [3, 0, 4, 2]. Complete example with fake (random) image:
data = np.zeros((6, 7, 8, 32, 32))
list = [[1, 2, 3], [4, 2, 0], [5, 3, 4], [2, 2, 2]]
image = np.random.uniform(size=(32, 32))
ix = np.array(list)
data[ix[:, 0], ix[:, 1], ix[:, 2], :, :] = image
Here ix[:, 0] is [1, 4, 5, 2], ix[:, 1] is [2, 2, 3, 2], and so on.
Reference: NumPy indexing and broadcasting.