Search code examples
pythonnumpyopencvimagefilter

Replace all pixels in numpy array with pixels in separate array unless the value is 0


There's an opencv image which I split into 3 channels:

 image #opencv image

 img_red = image[:, :, 2]
 img_green = image[:, :, 1]
 img_blue = image[:, :, 0]

Then there are three filters:

red_filter
green_filter
blue_filter

Which are all numpy arrays, but are mostly populated by zeroes so that the format looks something like this:

[0, 0, 0, 132, ... 0, 15,   0, 230, 0]
               ...                   
[32, 0, 5, 0,  ... 0,  2, 150,   0, 0]

I'd like to use every nonzero value in these filters to overwrite the same index in the channels.

Something like this:

img_red[index] = red_filter[index] if red_filter != 0
img_green[index] = green_filter[index] if green_filter != 0
img_blue[index] = blue_filter[index] if blue_filter != 0
final_img = cv2.merge(img_red, img_green, img_blue)

For example if the channel would look like this:

[44, 225, 43, ... 24, 76, 56]

And the filter:

[0,   0, 25   ... 2,   0, 91]

Then the result should be:

[44, 225, 25 ...  2,  76, 91]

I've tried using for loops and list comprehensions, but this code would have to be run over every frame in a video, so I'm wondering if there's a faster way to achieve the same result.

Is there some sort of image filtering in opencv, or numpy operation that would fulfill this process efficiently?


Solution

  • It seems like you're looking np.where method:

    channel = np.array([44, 225, 43, 24, 76, 56])
    filter = np.array([0,   0, 25, 2,   0, 91])
    #result = np.array([44, 225, 25, 2,  76, 91])
    >>> np.where(filter==0, channel, filter)
    array([ 44, 225,  25,   2,  76,  91])