【问题标题】:How to mask image with binary mask?如何用二进制掩码掩码图像
【发布时间】:2020-04-13 09:14:20
【问题描述】:

假设我这里有一张灰度图像:

这里还有一个二进制蒙版图像:

具有相同的尺寸和形状。我如何生成这样的东西:

其中二进制掩码中1表示的值是真实值,掩码中为0的值在最终图像中为空。

【问题讨论】:

  • 将它们相乘?
  • 这些不是灰度图像。
  • 我将 matplotlib 与 viridis 颜色图一起使用,因此它们不会显示为灰色,但它们不是 rgb。
  • 您的图片尺寸不同。另外请始终发布没有彩色地图的正确图像;否则你会迷惑人们,也很难展示灰度图像的解决方案。

标签: python image numpy opencv image-processing


【解决方案1】:

其他答案对我不起作用。那时,我花了很多时间来寻找一个好的遮罩功能。以下是两个仅使用 numpy 的简单答案。

import numpy as np

arr = np.arange(27).reshape(3,3,3) #3 channel image
mask = np.zeros(shape=(3,3))
mask[1,1] = 1 # binary mask
mask_3d = np.stack((mask,mask,mask),axis=0) #3 channel mask

## Answer 1
# Simply multiply the image array with the mask

masked_arr = arr*mask_3d

## Answer 2
# Use the where function in numpy

masked_arr = np.where(mask_3d==1,arr,mask_3d)

#Both answer gives
print(masked_arr)

array([[[ 0.,  0.,  0.],
        [ 0.,  4.,  0.],
        [ 0.,  0.,  0.]],

       [[ 0.,  0.,  0.],
        [ 0., 13.,  0.],
        [ 0.,  0.,  0.]],

       [[ 0.,  0.,  0.],
        [ 0., 22.,  0.],
        [ 0.,  0.,  0.]]])

【讨论】:

    【解决方案2】:

    这里有另外两种使用 Python Opencv 的方法。第一个类似于@nathancy。第二个使用乘法来进行掩蔽。 我使用与@nathancy 提供的相同图像:

    import cv2
    import numpy as np
    
    # read image
    img = cv2.imread('pink_flower.png')
    
    #mask it - method 1:
    # read mask as grayscale in range 0 to 255
    mask1 = cv2.imread('pink_flower_mask.png',0)
    result1 = img.copy()
    result1[mask1 == 0] = 0
    result1[mask1 != 0] = img[mask1 != 0]
    
    # mask it - method 2:
    # read mask normally, but divide by 255.0, so range is 0 to 1 as float
    mask2 = cv2.imread('pink_flower_mask.png') / 255.0
    # mask by multiplication, clip to range 0 to 255 and make integer
    result2 = (img * mask2).clip(0, 255).astype(np.uint8)
    
    cv2.imshow('image', img)
    cv2.imshow('mask1', mask1)
    cv2.imshow('masked image1', result1)
    cv2.imshow('masked image2', result2)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    # save results
    cv2.imwrite('pink_flower_masked1.png', result1)
    cv2.imwrite('pink_flower_masked2.png', result2)
    


    两种方法的结果相同:

    【讨论】:

      【解决方案3】:

      使用cv2.bitwise_and 使用二进制掩码对图像进行掩码。蒙版上的任何白色像素(值为 1)将被保留,而黑色像素(值为 0)将被忽略。这是一个例子:

      输入图像(左),蒙版(右)

      屏蔽后的结果

      代码

      import cv2
      import numpy as np
      
      # Load image, create mask, and draw white circle on mask
      image = cv2.imread('1.jpeg')
      mask = np.zeros(image.shape, dtype=np.uint8)
      mask = cv2.circle(mask, (260, 300), 225, (255,255,255), -1) 
      
      # Mask input image with binary mask
      result = cv2.bitwise_and(image, mask)
      # Color background white
      result[mask==0] = 255 # Optional
      
      cv2.imshow('image', image)
      cv2.imshow('mask', mask)
      cv2.imshow('result', result)
      cv2.waitKey()
      

      【讨论】:

        猜你喜欢
        • 2018-07-21
        • 1970-01-01
        • 2017-04-10
        • 2022-01-09
        • 1970-01-01
        • 1970-01-01
        • 2021-11-28
        • 1970-01-01
        • 2018-09-27
        相关资源
        最近更新 更多