I want to create a mask of an image with the values in a list. For example I have an RGB image with dimension (2, 5):
a = (np.random.rand(2, 5, 3) * 10).astype(int)
array([[[0, 5, 8],
[9, 0, 2],
[2, 2, 9],
[9, 2, 4],
[2, 5, 3]],
[[7, 5, 7],
[1, 9, 3],
[4, 3, 3],
[9, 1, 1],
[9, 5, 5]]]
b = np.array([[0, 5, 8], [7, 5, 7], [4, 3, 3]])
array([[[0, 5, 8],
[7, 5, 7],
[4, 3, 3]]])
What I want to do is I want to create a mask of image a retaining the pixel values (each pixel value is in a list of pixel value in list b) across 3 RGB channel (third dimension). Example result for given a and b is:
array([[[True, True, True], # check if [0, 5, 8] is in b
[False, False, False], # check if [9, 0, 2] is in b
[False, False, False], # check if [2, 2, 9] is in b
[False, False, False], # check if [9, 2, 4] is in b
[False, False, False]], # check if [2, 5, 3] is in b
[[True, True, True],
[False, False, False],
[True, True, True],
[False, False, False],
[False, False, False]]]
or the output can be this because we are masking an image with pixel values so the third dimension can be omitted
array([[True,
False,
False,
False,
False],
[True,
False,
True,
False,
False]]
I've tried these but they are too slow for my need:
# A naive way using list comprehension. Slowest I've tried
mask = [[True if np.any(b == a[r, c, :]) else False
for c in range(a.shape[1])] for r in range(a.shape[0])]
# I've tried this but it's probably a wrong solution since in1d flatten the array to compare
#them. I need the pixel to be compared across the 3rd dimension
mask = np.in1d(a[:, :, (?)], b, invert=True).reshape(image.shape[:2])
# Fastest I've tried. Took around 4 seconds on my machine on an image with dimension
# (3000, 3000, 3). But apparently it's not fast enough
mask = np.zeros(image.shape[:2], dtype=np.bool)
for val in b:
mask |= (a == b).all(-1)
Any help is appreciated :D