How to get all the static pixels in a numpy array of shape (T, H, W, C)?

Question:

I’m trying to get an image of all static pixels across a numpy array of shape (T, H, W, C) where T is the temporal value, H is height, W is width and C is channel.
Currently my approach is as follows:

mask_static = cv2.bitwise_and(array[0], array[1])
for image in array[2:]:
   mask_static = cv2.bitwise_and(mask_static, image)

return mask_static

The issue with this approach is that if there are minimal changes in the values, the pixels still appear in the final mask. Is there a way of quickly checking that pixel value at position [i,j] is equal in all T’s?

Thanks!

Note: I am not trying to do background extraction and I am well aware of openCV2’s functions for foreground masking but this isn’t what I am looking for.

Asked By: cyril

||

Answers:

You could check if the pixel values differences are below a given threshold from one image to the next, and update the mask in consequence.

I used a threshold if you are working with float values which can be suffer from the machine precision.

Here I used the 1-norm to compare pairs of pixels with C values each (namely the sum of the absolute differences of the given pixel channels), but you can compare eachpair of pixel as you wish

mask = np.ones_like(array[0,:,:,0], dtype = bool) # Mask of shape (H, W)
eps = 1e-8 # threshold to consider 2 pixels equal

for i in range(len(array) -1):
    mask = mask & (np.linalg.norm(array[i] - array[i+1], ord = 1, axis = 2) < eps) #logic AND with the next similar pixels locations

Adding the one line version of it if it is useful for anyone:

eps = 1e-8
mask = np.logical_and(*[np.linalg.norm(array[i] - array[i+1], ord = 1, axis = 2) < eps  for i in range(len(array) -1) ])
Answered By: PlainRavioli
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.