Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Masking BGR image using a 2D mask

I have a three-dimensional array (image) with shape (480, 640, 3). Here, the 3 refers to BGR color code. I would like to place a mask over this image using the data from the array of the Red image. Depending on its value, certain pixels need to be masked.

Creating the mask works fine. It behaves exactly as expected. In order to apply the mask to the original image, I first apply the mask to the Blue and Green image. All is still fine. Now I stack the three masked arrays, which returns an array with shape (480, 640, 3). However, plotting this array using imshow results in the original image. No sign of any mask.

Below I put my code. The code works for any image size/shape. All you need to do is change the name "Whatever_image_you_like.png" to the name of any image on your pc.

import numpy
import numpy.ma
import scipy.misc
import matplotlib.pyplot as plt

pixel_value = 130   #Value in range 0 to 255

image = scipy.misc.imread("Whatever_image_you_like.png")

#Extract Blue, Green, and Red image from original image
image_B = numpy.copy(image[:, :, 0])
image_G = numpy.copy(image[:, :, 1])
image_R = numpy.copy(image[:, :, 2])

#Define mask depending on pixel value in Red image
image_mask = numpy.empty([image.shape[0], image.shape[1]], dtype = bool)
image_mask[image_R < pixel_value] = False

#Apply mask to Blue, Green, and Red images
B_masked = numpy.ma.masked_array(image_B, mask = ~image_mask)
G_masked = numpy.ma.masked_array(image_G, mask = ~image_mask)
R_masked = numpy.ma.masked_array(image_R, mask = ~image_mask)

#Stack masked images together again
masked_image = numpy.ma.dstack((B_masked, G_masked, R_masked))

#Plot original image and masked version
fig = plt.figure()

ax1 = fig.add_subplot(2, 1, 1)
ax1.imshow(image)

ax2 = fig.add_subplot(2, 1, 2)
ax2.imshow(masked_image)

plt.show()

What am I doing wrong? Is there a better way to approach this problem?

like image 412
The Dude Avatar asked Nov 08 '14 19:11

The Dude


People also ask

How do you mask a 2D array in Python?

To mask rows and/or columns of a 2D array that contain masked values, use the np. ma. mask_rowcols() method in Numpy. The function returns a modified version of the input array, masked depending on the value of the axis parameter.

How do you mask an image?

Quick steps for creating a clipping mask: Select a text or graphic layer to fill with an image. Click Fill with image on the tool palette & choose an image. Select Edit image fill on the Text Tools panel. Adjust the image behind your text or shapes, then click Done.


1 Answers

Try to use a mask with the same shape as the image (actually, this will be a 3D mask). After generating your image_mask, do

# create mask with same dimensions as image
mask = numpy.zeros_like(image)

# copy your image_mask to all dimensions (i.e. colors) of your image
for i in range(3): 
    mask[:,:,i] = image_mask.copy()

# apply the mask to your image
masked_image = image[mask]

This way I avoid masked arrays in numpy for the time being.

like image 180
jkalden Avatar answered Oct 15 '22 13:10

jkalden