简体   繁体   中英

numpy: combine image mask with RGB to get colored image mask

how can I combine a binary mask image array ( this_mask - shape:4,4) with a predefined color array ( mask_color , shape:3)

this_mask = np.array([
[0,1,0,0],
[0,0,0,0],
[0,0,0,0],
[0,0,0,0],
])
this_mask.shape # (4,4)

mask_color = np.array([128, 128, 64])
mask_color.shape # (3)

to get a new color mask image array ( this_mask_colored , shape:4,4,3)?

this_mask_colored = # do something with `this_mask` and `mask_color`
# [
#  [
#   [0,128,0],
#   [0,0,0],
#   [0,0,0],
#   [0,0,0]
#  ],
#  [
#   [0,128,0],
#   [0,0,0],
#   [0,0,0],
#   [0,0,0]
#  ],
#  [
#   [0,64,0],
#   [0,0,0],
#   [0,0,0],
#   [0,0,0]
#  ],
# ]
this_mask_colored.shape # (4,4,3)

I tried for loop through pixel by pixel, is it slow when when image is 225x225, what is best way to do this?

For each image, I have multiple layers of mask, and each mask layer needs to have a different predefine color.

This might work:

    this_mask = np.array([
        [0,1,0,0],
        [0,0,0,0],
        [0,0,0,0],
        [0,0,0,0],
    ])
    mask_color = np.array([128, 128, 64])

    res = []
    for row in new:
        tmp = []
        for col in row:
            tmp.append(np.array([1,1,1]) * col)
        res.append(np.array(tmp))

    res = res * mask_color

For each entry, 1 will be converted to [1, 1, 1] and 0 is [0, 0, 0]

I do this because I want to use the benefit of the operation * (element-wise multiplication)

This works:

    test = np.array([[0, 0, 0],
                     [1, 1, 1],
                     [0, 0, 0],
                     [0, 0, 0]])

    test * np.array([128, 128, 64])

We'll get

    array([[  0,   0,   0],
           [128, 128,  64],
           [  0,   0,   0],
           [  0,   0,   0]])

And we want to put all the calculation to the numpy's side. So we loop through the array just for conversion and the rest is for numpy.

This takes 0.2 secs for 255x255 of 1 with one mask_color and 2 secs for 1000x1000

The following function should do what you want.


def apply_mask_color(mask, mask_color):
    return np.concatenate(([mask[ ... , np.newaxis] * color for color in mask_color]), axis=2)

Given the following code:


this_mask = np.array([
    [0,1,0,0],
    [0,0,0,0],
    [0,0,0,0],
    [0,0,0,0],
    ])

mask_color = np.array([128, 128, 64])

applied = apply_mask_color(this_mask, mask_color)
print(applied.shape) #(4, 4, 3)

It is important to note that the output isn't QUITE what you expected. Rather, every element inside is now a 3 dimensional array housing the R GB values detailed in mask_color


print(applied)

Output:


[[[  0   0   0]
  [128 128  64]
  [  0   0   0]
  [  0   0   0]]

 [[  0   0   0]
  [  0   0   0]
  [  0   0   0]
  [  0   0   0]]

 [[  0   0   0]
  [  0   0   0]
  [  0   0   0]
  [  0   0   0]]

 [[  0   0   0]
  [  0   0   0]
  [  0   0   0]
  [  0   0   0]]]

I think is is more what you're looking for.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM