wirher
wirher

Reputation: 976

How to set all pixels that are not in the list of allowed values to white?

I have an image that contains RGB pixels. I have a list of pixels meaningful_pixels: List[Tuple(int, int, int)] that I consider to be meaningful information and I want to set all other pixels to white (255, 255, 255)

This is the original image

enter image description here

and I'm trying to transform it to

enter image description here

I already successfully created list of "allowed pixels", which is the "purple-to-yellow" gradient of top-left rectangle, which is stored in meaningful_pixels variable, of shape (num_of_pixels, 3).

I am able to remove black rectangle by creating mask and using it to change pixels

# actual code
mask = np.all(image == [0, 0, 0], axis=-1)
image[mask] = [255, 255, 255]

But I don't know how to create a mask when I have a list of values instead of one.

I was able to accomplish that with a for loop but the performance was pretty bad. I need help with accomplishing that with numpy "vectorized" approach for maximum performance. Something like:

#pseudocode
image = np.remove_value_if_not_in_list(image, allowed_pixels)

Solution

# creates mask of "allowed pixels"
mask = np.all(np.isin(img, allowed_pixels) == [True, True, True], axis=-1)
# use inverted mask to replace pixels with white
img[~mask] = [255, 255, 255]

Upvotes: 0

Views: 534

Answers (2)

Lachlan
Lachlan

Reputation: 370

I use numpy.where() for similar processes. I have combined this with numpy.isin() as well, which would achieve what you want.

Code example something like:

import numpy as np

#pseudocode
image = np.where(np.isin(image, list_of_exlusions), image, mask_value)

Upvotes: 1

Woodford
Woodford

Reputation: 4449

You can use np.vectorize to take a Python function and apply it to an ndarray using broadcasting.

def is_not_meaningful_pixel(pixel):
    return pixel not in meaningful_pixels

mask = np.vectorize(is_not_meaningful_pixel)(image)
image[mask] = (255, 255, 255)

Here's a more concrete example with data:

BAD_VALUES = (2, 3, 4)
REPLACEMENT_VALUE = 99
data = np.arange(7)

def condition(val):
    return val in BAD_VALUES
vectorized_condition = np.vectorize(condition)

mask = vectorized_condition(data)
data[mask] = REPLACEMENT_VALUE

print(data)

# output
[ 0  1 99 99 99  5  6]

Upvotes: 0

Related Questions