0

I pass an array of size (734,814,3) to a function but numpy.where() gives one dimensional result instead of the two-dimensional one, which it should for a 2D array

def hsi2rgb(img):
    img_rgb = np.empty_like(img)
    h = img[:,:,0] #(734,814)
    s = img[:,:,1] #(734,814)
    i = img[:,:,2] #(734,814)
    l1 = 0.00
    l2 = 2*3.14/3
    l3 = 4*3.14/3
    l4 = 3.14
    r1 = np.where(np.logical_and(h>=l1, h<l2)) #(99048,)
    r2 = np.where(np.logical_and(h>=l2, h<l3))
    r3 = np.where(np.logical_and(h>=l3, h<l4))
    hs = h[r1]
    return img_rgb

r1 is shown to be a tupple, and r1[0],r1[1] are of the size 99048, which shouldn't be the case. r1 should have row indices and column indices of those values which satisfy the condition. I tried it without the logical and, using just one condition, but the problem persists.

Vahni
  • 272
  • 1
  • 10

1 Answers1

2

I followed your code, and np.where returned the expected result: a tuple with two 1D arrays containing the indexes where the condition is met:

import numpy as np
h = np.random.uniform(size=(734, 814))
r1 = np.where(np.logical_and(h >= 0.1, h < 0.9))
print(r1[0].shape, r1[1].shape)    # (478129,) (478129,)

This means that 478129 elements met the condition. For each of them, r1[0] will have its row index, and r11 will have its column index. Namely, if r1 looks like

(array([  0,   0,   0, ..., 733, 733, 733]), array([  0,   1,   2, ..., 808, 809, 811]))

then I know that h[0, 0], h[0, 1], h[0, 2], etc satisfy the conditions: the row index comes from the first array, the column index from the second. This structure may be less readable, but it's usable for indexing the array h.

The transposed form of the output is more readable, being a 2D array with row-column index pairs:

array([[  0,   0],
       [  0,   1],
       [  0,   2],
       ...,
       [733, 808],
       [733, 809],
       [733, 811]])

It can be obtained by transposing r1 (if you need the original r1 as well), or directly with np.argwhere:

r1 = np.argwhere(np.logical_and(h >= 0.1, h < 0.9))
  • Thanks for your answer. Is there an easy way of accessing the indices in this case? Using img_rgb[r1[:,0],r1[:,1]][0] = h[r1[:,0],r1[:,1]] gives broadcasting error "could not broadcast input array from shape (99048) into shape (3)" – Vahni Jun 26 '18 at 05:13
  • Don't do `array[something][0]` that's not a good NumPy approach and it is a reason for the error here. The original form of `r1`, a tuple, is designed for ease of indexing. `rgb[r1[0], r1[1], 0] = h[r1[0], r1[1]]` is all it takes. –  Jun 26 '18 at 09:02