Search code examples
pythonnumpymask

numpy.all strange behaviour


In the following code, I try to generate a mask on an image. The mask should only be true where the image (originalFormat, ndarry with shape [720, 1280, 3]) has a specific value (segmentId, nd array with shape [3,]).

Here's a small part of the code as minimal example:

originalFormat = np.array(Image.open(path_to_image))[..., :3]
segment_ids = np.unique(originalFormat.reshape(-1, originalFormat.shape[2]), axis=0)
segment_ids.sort(axis=0)

segmentId = segment_ids[0]
mask = originalFormat == segmentId
test = [True, True, True] in mask
mask = mask.all(axis=2)
test = True in mask

In the second line of the second block, I create the mask and get an output of shape [720, 1280, 3].
In the third line, I test if the image contains the segmentId.
In the fourth line, I apply np.all on the second axis of the mask to get a mask of shape [720, 1280].
In the fifth line, I test again, but now there are no true values in the mask.
So np.all returns false for all values, but should be true for at least one value.

enter image description here


Solution

  • The test [True, True, True] in mask does not do what you think it does. Here [True, True, True] is a plain Python list, and in is a plain Python operator, nothing NumPy-specific, whereas mask is a NumPy array.

    Thus, it is actually not quite clear what the test checks. See the linked question. In any case, there do not need to be three True values in the same row for this test to evaluate as True. Here`s a small example reproducing the behavior you observed:

    originalFormat = np.arange(12).reshape((2, 2, 3))
    segmentId = np.array([6, 4, 5])