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
and I'm trying to transform it to
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)
CodePudding user response:
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]
CodePudding user response:
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)