使用numpy将图像与图案进行遮罩处理?

26

我正在使用numpy构建像素数组。一个800x600的图像是一个三维的uint8数组,大小为800x600x3。我还有一个类似的数组,其中有一个固定的模式(一个棋盘格,可以在这里看到)。我还有另一个800x600的掩码值数组。当掩码为零时,我想将模式像素复制到图像像素中。当掩码不为零时,我想保持图像像素不变。

>>> image.shape
(800, 600, 3)
>>> chex.shape
(800, 600, 3)
>>> mask.shape
(800, 600)

这个感觉应该可以工作:

image[mask == 0,...] = chex

但是会报错"ValueError: array is not broadcastable to correct shape"。

我该使用什么方法将 chex 像素复制到图像像素中,其中 mask 为零?

5个回答

34
idx=(mask==0)
image[idx]=chex[idx]

请注意,image的形状为(800,600,3),而idx的形状为(800,600)。索引状态的规则如下:

如果选择元组小于n,则会添加尽可能多的对象到选择元组的末尾,以便修改后的选择元组的长度为N。

因此,索引数组具有自己的广播能力。idx的形状被提升为(800,600,:)。

5

我想通过@unutbu的回答来举个例子。在这种情况下,我有一张旋转的猫的图片。这种旋转会导致出现一些黑色的边缘,特别是当贴在非黑色背景上时显得很丑陋。

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)

粘贴不好

因此,我找到口罩的区域,并用原始背景值替换这些值。

mask_ind = (bgcopy == 0)
bgcopy[mask_ind] = bg[mask_ind]
plt.imsave('cat-on-bg.jpg', bgcopy)

值得一提的是,Pillow库中的PIL.Image可以用更少的步骤将一张图片粘贴到另一张图片上。

good pasting


4

我发现最简单的方法是创建一个掩码,其中1表示“保留像素”,0表示“删除像素”。

然后,我将我的图像乘以该掩码,以去除不需要的像素。例如,仅保留肖像的边框(外侧):

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

enter image description here

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

enter image description here


2

尝试:

image[mask[:] == 0,...] = chex[mask[:] == 0,...]

0

我使用了三个数组来表示您的图像数组、检查器数组和掩码数组,它们分别是8x6x3、8x6x3和8x6。

# first create mini-versions of your arrays:
mask = NP.random.random_integers(0, 1, 48).reshape(8, 6)
img = NP.random.random_integers(3, 9, 8*6*3).reshape(8, 6, 3)
chk = NP.ones((8, 6, 3))

# all the work done in these two lines
mask = mask[:,:,NP.newaxis]
res = NP.where(mask==0, chk, img)

三张图片的形状,mask.shape (8, 6), chk.shape (8, 6, 3) 和 img.shape (8, 6, 3) 似乎不符合 np.where 的要求。 - Gathide

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接