0

I have a 3D array of dimensions (200,200,3). These are images of dimensions (200,200) stacked using numpy.dstack. I would like to count the number of values along axis=2 that are greater than a corresponding 2D threshold array of dimensions (200,200). The output counts array should have dimensions (200,200). Here is my code so far.

import numpy as np

stacked_images=np.random.rand(200,200,3)
threshold=np.random.rand(200,200)
counts=(stacked_images<threshold).sum(axis=2)

I am getting the following error.

ValueError: operands could not be broadcast together with shapes (200,200,3) (200,200)

The code works if threshold is an integer/float value. For example.

threshold=0.3
counts=(stacked_images<threshold).sum(axis=2)

Is there a simple way to do this if threshold is a 2D array? I guess I am not understanding numpy broadcasting rules correctly.

Vishnu
  • 499
  • 1
  • 5
  • 23
  • Possible duplicate of [Numpy \`ValueError: operands could not be broadcast together with shape ...\`](https://stackoverflow.com/questions/11856493/numpy-valueerror-operands-could-not-be-broadcast-together-with-shape) – MB-F May 24 '17 at 06:13
  • 1
    Extend `thresh` to `3D` : `(stacked_images > threshold[...,None]).sum(2)`. – Divakar May 24 '17 at 11:51
  • @kazemakase I had looked through the link you provided earlier. The general answer given there is correct to look into numpy broadcasting rules. However, I was not aware how to extend my array into 3D. – Vishnu May 24 '17 at 17:04
  • @Divakar Your solution worked. Thank you! :) – Vishnu May 24 '17 at 17:05

1 Answers1

1

numpy is expecting to make a value by value operation. In your case you seem to be wanting to know if any value in the full Z (axis=2) trace exceeds the equivalent x, y value in threshold.

As so just make sure threshold has the same shape, namely by building a 3D threshold using whatever method you prefer. Since you mentioned numpy.dstack:

import numpy as np

stacked_images = np.random.rand(10, 10, 3)
t = np.random.rand(10, 10)
threshold = np.dstack([t, t, t])
counts = (stacked_images < threshold).sum(axis=2)
print(counts)

, which results in:

[[2 0 3 3 1 3 1 0 1 2]
 [0 1 2 0 0 1 0 0 1 3]
 [2 1 3 0 3 2 1 3 1 3]
 [2 0 0 3 3 2 0 2 0 1]
 [1 3 0 0 0 3 0 2 1 2]
 [1 1 3 2 3 0 0 3 0 3]
 [3 1 0 1 2 0 3 0 0 0]
 [3 1 2 1 3 0 3 2 0 2]
 [3 1 1 2 0 0 1 0 1 0]
 [0 2 2 0 3 0 0 2 3 1]]
armatita
  • 12,825
  • 8
  • 48
  • 49