【问题标题】:Use numpy to mask an image with a pattern?使用 numpy 用图案掩盖图像?
【发布时间】:2011-01-11 07:03:13
【问题描述】:

我正在使用 numpy 来构建像素数组。一个 800x600 的图像是一个 uint8、800x600x3 的 3 维数组。我也有一个具有固定模式的类似数组(棋盘格,请参阅here)。我有另一个数组,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 像素复制到掩码为零的图像像素?

【问题讨论】:

    标签: python image-processing numpy


    【解决方案1】:
    idx=(mask==0)
    image[idx]=chex[idx]
    

    请注意,image 的形状为 (800,600,3),而 idx 的形状为 (800,600)。 The rules 用于索引状态

    如果选择元组小于 n,然后是尽可能多的 : 对象 被添加到选择的结束 元组,以便修改后的选择 元组的长度为 N。

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

    【讨论】:

      【解决方案2】:

      我想用@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)
      

      我还应该注意到PIL.Image(来自Pillow 库)能够以更少的步骤将图像粘贴到另一个图像上。

      【讨论】:

        【解决方案3】:

        我发现最简单的方法是创建一个掩码,其中 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
        

        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
        

        【讨论】:

          【解决方案4】:

          试试:

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

          【讨论】:

            【解决方案5】:

            我使用了 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) and img.shape (8, 6, 3)好像不符合np.where.的要求
            猜你喜欢
            • 2013-06-06
            • 1970-01-01
            • 1970-01-01
            • 2015-11-08
            • 2017-12-06
            • 1970-01-01
            • 2015-10-30
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多