2

I have an image(2D array) with 3 color channels. Something like this:

[[[128 197 254]
  [128 197 254]
  [128 197 254]
  ...
  [182 244 255]
  [182 244 255]
  [182 244 255]]

 [[128 197 254]
  [128 197 254]
  [128 197 254]
  ...
  [182 244 255]
  [182 244 255]
  [182 244 255]]

 [[128 197 254]
  [128 197 254]
  [128 197 254]
  ...
  [182 244 255]
  [182 244 255]
  [182 244 255]]

 ...

 [[128 197 254]
  [128 197 254]
  [128 197 254]
  ...
  [182 244 255]
  [182 244 255]
  [182 244 255]]

 [[128 197 254]
  [128 197 254]
  [128 197 254]
  ...
  [182 244 255]
  [182 244 255]
  [182 244 255]]

 [[128 197 254]
  [128 197 254]
  [128 197 254]
  ...
  [182 244 255]
  [182 244 255]
  [182 244 255]]]

I want to get the indexes of the colors that are [255, 255, 255] for example. I tried using np.where() or np.argwhere(), but it compared values not arrays. What is the fastest and most efficient way to do it?

2
  • How did you try to use np.where? Commented Apr 5, 2019 at 20:21
  • 1
    where is only as good as the boolean condition array that you give it. Commented Apr 5, 2019 at 20:50

2 Answers 2

3

IIUC, you may use np.nonzero

np.nonzero((arr==255).all(axis=2))

That will return a tuple of arrays, which represent the indexes. If you do

arr[ind]

where ind is the return from the first expr, you may access/modify all rows with all 255.

Sign up to request clarification or add additional context in comments.

Comments

-1

A numpy way to do this with np.where would be

import numpy as np

# Generating an example array
width = 100 
height = 100
channels = 3
img = np.random.rand(width, height, channels) * 255

# Defining the three value channels
r=0 
g=1 
b=2

# Defining the query values for the channels, here [255, 255, 255]
r_query = 255
g_query = 255
b_query = 255

# Print a 2D array with the coordinates of the white pixels
print(np.where((img[:,:,r] == r_query) & (img[:,:,g] == g_query) & (img[:,:,b] == b_query)))

This gives you a 2D-Array with the coordinates of the white pixels [255, 255, 255] in your original array (image).

Note: Another way would be using OpenCV

mask = cv2.inRange(img, [255, 255, 255], [255, 255, 255])
output = cv2.bitwise_and(img, img, mask = mask)

2 Comments

@RafaelC, thanks for the comment and smooth answer (+1). The last entry in my codesnippet refers to the three channels (r, g, b) when sticking to the image analogy. I guess it depends on the shape of the array. This code works for me without errors and does what was asked.
Ah ok I see what you did there ;)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.