Home > Back-end >  How to filter a elements of matrixes?
How to filter a elements of matrixes?

Time:10-09

I want to get some pixel values from an image which are not equal with a specified value. But I want to get back in RGB format and not as a long vector. How can I do it?

import cv2
import numpy as np

image = cv2.imread('image.jpg')
sought = [36,255,12]
result = image[image!=sought]

import sys
np.set_printoptions(threshold=sys.maxsize)
print(result)

And I've got:

  [20 103  75  21  98  70  16 100  72  18 101  73  19  97  69  15  95  66
  15  95  67  13 101  73  19 104  77  21  96  69  13  94  65   8  99  69
  14  98  68  13  94  63  10  88  66  24  92  69  24  92  67  23  93  67
  13  93  67  13  93  67  13  97  72  16  96  70  16  93  66  15  96  68
  .....
  99  69  14  96  66  11  91  67  25  88  65  20  92  68  14  96  69  18
  96  70  16  91  64  13  95  67  13  92  64  10  90  63]

But I want something like this:

     [[[R,G,B], [R,G,B], [R,G,B], [R,G,B]],
       ......
      [[R,G,B], [R,G,B], [R,G,B], [R,G,B]]]

What did I miss here?

CodePudding user response:

With result = image[image != sought] you lost the shape of image. The solution is to get a mask (image != sought) and work on the image with that mask (e.g. using np.where)

Generate some data:

import numpy as np

H, W, C = 8, 8, 3
sought = [255, 0, 0]
colors = np.array(
    [sought, [0, 0, 255], [0, 255, 0], [0, 255, 255], [255, 0, 255], [255, 255, 0]]
)
colors_idxs = np.random.choice(np.arange(len(colors)), size=(H, W))
image = colors[colors_idxs]

Compute mask (note the keepdims=True for np.where to work easier):

mask = np.any(image != sought, axis=-1, keepdims=True)

# Get color back into the mask
mask_inpaint_pos = np.where(mask, image, 0)
mask_inpaint_neg = np.where(mask, 0, image)

Plot:

import matplotlib.pyplot as plt

fig, (ax_im, ax_mask, ax_mask_pos, ax_mask_neg) = plt.subplots(ncols=4, sharey=True)

ax_im.set_title("Original")
ax_im.imshow(image)

ax_mask.set_title("Mask binary")
ax_mask.imshow(mask.astype(int), cmap="gray")

ax_mask_pos.set_title("Mask True RGB")
ax_mask_pos.imshow(mask_inpaint_pos)

ax_mask_neg.set_title("Mask False RGB")
ax_mask_neg.imshow(mask_inpaint_neg)

plt.show()

orig / mask / masks rgb

CodePudding user response:

If the wanted output is a list of pixels, then after the component-wise comparison, you must check what pixels differ on any of the R,G or B with .any(axis = 2):

image[(image != sought).any(axis=2)]

output of the form:

array([[ 22, 136, 161],
       [197, 141, 153],
       [173, 122,  65],
       [137, 189,  67],
             ...
       [166, 205, 238],
       [207,  99, 129],
       [ 44,  76,  97]])
  • Related