How can I return the indexes of RBG?
Say p is my Numeric Python array.

>>>x = 58
>>>y = 72
>>>p[y][x]
array([255, 255, 255], dtype=uint8)

I don't know what a Numeric Python array is or how to handle them but I found how to convert it to ['255', '255', '255'], which I think I am pretty sure is a list, by using map(str, p[y][x]) and I can deal with those simple enough.

When I try p.index(p[y][x]) it throws AttributeError: 'numpy.ndarray' object has no attribute 'index'.

And for p[y][x] in p: throws ValueError: output operand requires a reduction, but reduction is not enabled

I want to return the y and x of all the same RBG and also count how many occurances there are of them.
gtk.gdk.Pixbuf.get_pixels_array This is where I got the Numeric Python array from.

Dani AI

Generated

ran into the classic broadcasting issue: a channel-wise equality test produces per-channel matches (hence the three arrays from where) instead of a single per-pixel decision. was right to lean on NumPy; the simple fix is to reduce the three channel comparisons into one boolean mask that is True only when all three channels match the target. is also correct that plain Python lists are easier to reason about but they are much slower for image-sized data.

# img is H x W x 3 (uint8); target is an (R,G,B) tuple
target = (255, 255, 255)
mask = (img == target).all(axis=-1)   # boolean H x W: True where the whole RGB matches
coords = np.argwhere(mask)            # Nx2 array of (row, col) pairs
count = coords.shape[0]
# x positions: coords[:,1]  ;  y positions: coords[:,0]

Notes and cautions: confirm your array shape (channels-last vs channels-first) and adjust the axis or transpose if needed. For a count you can also use mask.sum() which is fast and memory-efficient. If you need a fuzzy match (anti-aliasing, near-white pixels) compute per-pixel distance (e.g., squared difference sum or euclidean norm) and threshold that instead of exact equality. This approach returns each pixel once (no triple repeats) and is vectorized for speed.

Recommended Answers

All 8 Replies

np.where(p == np.array([255,255,255])) doesn't work because it also returns things like [0,0,255], basically anything with 255 and the output is confusing
(array([ 35, 35, 35, ..., 70, 71, 71]), array([ 35, 35, 35, ..., 190, 188, 189]), array([0, 1, 2, ..., 2, 2, 2]))

So I guess I cross reference check for
x = np.where(p == np.array([255,255,255]))[0]
and
y = np.where(p == np.array([255,255,255]))[1]
unless I have them mixed up and x is y and vice versa, actually infact I think I am pretty sure that it is the other way around.
Then I can use np.count_nonzero(x) and np.count_nonzero(y).

But is there a way to omit the third array? Otherwise I have to check if x[i] and y[i] are equal three sequential times in the loop some how and count them that way.

This doesn't work.
np.where(np.where(im == np.array([255,255,255]))[0] == np.where(im == np.array([255,255,255]))[1])

Actually in the case of
y = np.where(p == np.array([255,255,255]))[0]
and
x = np.where(p == np.array([255,255,255]))[1]
when I count them I want to count the zeroes so map(str, x) and map(str, y) can come in handy there so I can get the real truth of about their capacities.

Actually this post is wrong because there is no need for map(str, x) or map(str, y) because I can just use len(x) and len(y) instead of np.count_nonzero(x) and np.count_nonzero(y), I think?

You say lists are inferior to arrays, how so? I cannot find this fact anywhere else.

Numpy.array is specifically designed to work with collections of numbers, which seems to be what you want also.

I think you have array as member of array, when it is easier with matrix of three columns, R,G,B

I am somewhat confused, are you talking about a list of (r, g, b) tuples?
If you don't need the high speed of numpy, go with those.

Well speed is always more for the proficient. :)

How can I change it to a matrix of three columns, R,G,B?
Is there a way to return the x and y position of the RGBs from a matrix of three columns?

My goal is just to get the count and position of RGB in a picture, like RGB = np.array([255,255,255]) and iterate through all of them all.
np.where(p == RGB) was close but no cigar, because of it also return other RGBs if they contain 255 in them atleast once. And it return x and y three times in a row if it matches all three of the 255 as np.array([255,255,255]), I want it to only return x and y once, and only if all three of it's values match RGB

This is my p.

>>> p
array([[[ 28,  32,  33],
        [ 43,  46,  47],
        [ 45,  47,  48],
        ..., 
        [ 27,  31,  31],
        [ 30,  33,  34],
        [ 30,  33,  34]],

       [[ 29,  33,  34],
        [ 42,  45,  46],
        [ 42,  45,  46],
        ..., 
        [ 27,  31,  31],
        [ 30,  33,  34],
        [ 30,  33,  34]],

       [[ 30,  33,  34],
        [ 45,  47,  48],
        [ 45,  47,  48],
        ..., 
        [ 27,  31,  32],
        [ 30,  33,  34],
        [ 28,  32,  33]],

       ..., 
       [[206, 206, 206],
        [206, 206, 206],
        [206, 206, 206],
        ..., 
        [206, 206, 206],
        [183, 180, 178],
        [151, 149, 147]],

       [[206, 206, 206],
        [206, 206, 206],
        [206, 206, 206],
        ..., 
        [206, 206, 206],
        [183, 180, 178],
        [153, 150, 149]],

       [[206, 206, 206],
        [206, 206, 206],
        [206, 206, 206],
        ..., 
        [183, 180, 178],
        [183, 180, 178],
        [155, 152, 151]]], dtype=uint8)

I just found out
np.where(p == np.array([255,255,255]))
is the same as
np.where(p == np.array([255]))
is there another way?
I want to be able to match all three RGBs at once instead of sectionally.

In fact np.where(p == 255) is also the same thing as both of those two above.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.