代码之家  ›  专栏  ›  技术社区  ›  Ned Batchelder

使用numpy来用图案来遮罩图像?

  •  17
  • Ned Batchelder  · 技术社区  · 15 年前

    我正在使用numpy构建像素数组。800x600图像是一个由uint800x600x3组成的三维数组。我也有一个固定模式的类似数组(一个棋盘,参见 here )。我还有另一个数组,800x600个mask值。如果遮罩为零,我要将图案像素复制到图像像素。如果遮罩不是零,我想让图像像素单独存在。

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

    这似乎是可行的:

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

    但给出了“valueerror:数组不能广播到正确的形状”。

    我使用什么将chex像素复制到遮罩为零的图像像素?

    4 回复  |  直到 6 年前
        1
  •  18
  •   unutbu    15 年前
    idx=(mask==0)
    image[idx]=chex[idx]
    

    注意 image 形状(800600,3),而 idx 形状(800600)。 The rules 用于索引状态

    如果选择元组小于 n,那么多:需要的对象 添加到 结束 所选内容的 使修改后的选择 元组的长度为n。

    因此索引数组有一种自己的广播能力。 IDX 的形状提升为(800600,:)

        2
  •  1
  •   Jon    6 年前

    我想用@unutbu answer举例说明。在这个场景中,我有一个旋转的猫的图像。这种旋转会导致一些黑色边缘看起来很难看,尤其是粘贴在非黑色背景上时。

    导入matplotlib.pyplot as plt 从scipy.ndImage导入旋转 cat=plt.imread('cat.jpeg') bg=plt.imread('background.jpeg') rotcat=旋转(cat,角度=8,重塑=真)旋转创建一些黑色边缘 高度,宽度,rotcat.shape bg copy=bg.copy()创建背景副本;粘贴到副本上 x,y=40,50 bgcopy[x:x+高度,y:y+宽度]=rotcat plt.imsave('cat-on-bg-mask.jpg',bgcopy) < /代码>

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

    mask\u ind=(bgcopy==0)
    bgcopy[屏蔽查找]=bg[屏蔽查找]
    plt.imsave('cat-on-bg.jpg',bgcopy)
    < /代码> 
    
    

    我还应该注意到,pil.image(来自bendlelibrary)有能力用更少的步骤将图像粘贴到另一个图像上。

    一些看起来很难看的黑色边缘,尤其是粘贴在非黑色背景上时。

    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)
    

    bad pasting

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

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

    good pasting

    我也应该注意到PIL.Image(从Pillowlibrary)可以用更少的步骤将图像粘贴到另一个图像上。

        3
  •  0
  •   ezod    15 年前

    尝试:

    image[mask[:] == 0,...] = chex[mask[:] == 0,...]
    
        4
  •  0
  •   doug    15 年前

    我使用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)