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?
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With