【问题标题】:Numpy.putmask with images带有图像的 Numpy.putmask
【发布时间】:2011-04-04 02:22:52
【问题描述】:

我将图像转换为具有 RGBA 值的 ndarray。假设它是 50 x 50 x 4。

我想用值array([255, 255, 255, 255]) 替换array([0, 0, 0, 0]) 的所有像素。所以:

from numpy import *
from PIL import Image
def test(mask):
        mask = array(mask)
        find = array([255, 255, 255, 255])
        replace = array([0, 0, 0, 0])
        return putmask(mask, mask != find, replace)

mask = Image.open('test.png')
test(mask)

我做错了什么?这给了我一个ValueError: putmask: mask and data must be the same size。但是,如果我将数组更改为数字(查找 = 255,替换 = 0),它就可以工作。

【问题讨论】:

    标签: python arrays image image-processing numpy


    【解决方案1】:

    更简洁的方法是

    img = Image.open('test.png')
    a = numpy.array(img)
    a[(a == 255).all(axis=-1)] = 0
    img2 = Image.fromarray(a, mode='RGBA')
    

    更一般的,如果find和repl的项目不一样,你也可以这样做

    find = [1, 2, 3, 4]
    repl = [5, 6, 7, 8]
    a[(a == find).all(axis=-1)] = repl
    

    【讨论】:

      【解决方案2】:

      进行这种通道屏蔽的一种方法是将数组拆分为 r,g,b,a 通道,然后使用 numpy 逻辑位操作定义索引:

      import numpy as np
      import Image
      
      def blackout(img):
          arr = np.array(img)
          r,g,b,a=arr.T
          idx = ((r==255) & (g==255) & (b==255) & (a==255)).T
          arr[idx]=0
          return arr
      
      img = Image.open('test.png')
      mask=blackout(img)
      img2=Image.fromarray(mask,mode='RGBA')
      img2.show()
      

      【讨论】:

        【解决方案3】:

        此解决方案使用putmask,我认为它最接近 OPs 代码。 OP 应该知道的原始代码中有两个错误:1)putmask 是就地操作。它返回None。 2) putmask 也需要大小相等的数组。它(太糟糕了)没有 axis 关键字参数。

        import numpy as np
        from PIL import Image
        
        img1 = Image.open('test.png')
        arry = np.array(img1)
        find = np.array([255, 255, 255, 255])
        repl = np.array([  0,   0,   0,   0])
        # this is the closest to the OPs code I could come up with that
        # compares each pixel array with the 'find' array
        mask = np.all(arry==find, axis=2)
        # I iterate here just in case repl is not always the same value
        for i,rep in enumerate(repl):
            # putmask works in-place - returns None
            np.putmask(arry[:,:,i], mask, rep)
        
        img2 = Image.fromarray(arry, mode='RGBA')
        img2.save('testx.png')
        

        【讨论】:

        • 1.为什么你使用np.logical_not(imga-find) 而不是imga != find? 2.imga到底是​​什么? 3.如果repl中的所有条目都相同,您将如何避免循环?
        • @Sven Marnach: 2) 谢谢imga 应该是arry。 1) 我不知道您可以使用== 进行广播。 3) 我会创建一个 3D 蒙版和putmask(arry, mask, 0)。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-07-27
        • 2011-06-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多