Use numpy to mask an image with a pattern?
Try:
image[mask[:] == 0,...] = chex[mask[:] == 0,...]
idx=(mask==0)
image[idx]=chex[idx]
Note that image
has shape (800,600,3), while idx
has shape (800,600). The rules for indexing state
if the selection tuple is smaller than n, then as many : objects as needed are added to the end of the selection tuple so that the modified selection tuple has length N.
Thus indexing arrays have a sort of broadcasting ability of their own. idx
's shape gets promoted to (800,600,:)
I found it easiest to create a mask wherein 1 = "pixel to keep" and 0 = "pixel to remove".
Then I multiplied my image by that mask to remove the unwanted pixels. Example to retain only the frame (outside) of a portrait:
from scipy.misc import imread
import matplotlib.pyplot as plt
import numpy as np
im = imread('portrait.jpg', mode='L') # read in image
plt.imshow(im) # show the original image
mask = np.ones(im.shape) # create a mask with the image's shape
bw = 0.1 # identify border width and height as fraction of image size
bx = int(im.shape[1] * bw) # get the x dimension border width
by = int(im.shape[0] * bw) # get the y dimension border height
mask[bx:-bx,by:-by] = 0 # create a mask with 1 for border and 0 for inside
masked = im * mask # multiply `im` by the mask to zero out non-border pixels
plt.imshow(masked) # show the result of the masking operation
I wanted to illustrate an example using @unutbu answer. In this scenario, I have an image of a cat that I rotate. This rotation causes some black edges that look ugly especially when pasted on a non-black background.
import matplotlib.pyplot as plt
from scipy.ndimage import rotate
cat = plt.imread('cat.jpeg')
bg = plt.imread('background.jpeg')
rotcat = rotate(cat, angle=8, reshape=True) ## rotating creates some black edges
height, width, _ = rotcat.shape
bgcopy = bg.copy() ## create a copy of the background; paste on copy
x, y = 40, 50
bgcopy[x:x+height, y:y+width] = rotcat
plt.imsave('cat-on-bg-mask.jpg', bgcopy)
So, I find the areas of the mask and replace those values with the original background values
mask_ind = (bgcopy == 0)
bgcopy[mask_ind] = bg[mask_ind]
plt.imsave('cat-on-bg.jpg', bgcopy)
I should also note that PIL.Image
(from the Pillow
library) has the ability to paste an image onto another image with fewer steps.