【问题标题】:Plotting segmented color images using numpy masked array and imshow使用 numpy 掩码数组和 imshow 绘制分段彩色图像
【发布时间】:2018-06-20 18:08:13
【问题描述】:

我是 numpy 的掩码数组数据结构的新手,我想用它来处理分段彩色图像。

当我使用 matplotlib 的plt.imshow( masked_gray_image, "gray") 显示蒙版的灰色图像时,无效区域将显示为透明,这就是我想要的。 但是,当我对彩色图像执行相同操作时,它似乎不起作用。 有趣的是,数据点光标不会显示 rgb 值[r,g,b],而是空的[],但仍然显示颜色值而不是透明。

我做错了什么还是 matplotlib imshow 中尚未提供?

import numpy as np
import matplotlib.pyplot as plt
from scipy.misc import face

img_col = face() #example image from scipy 
img_gray = np.dot(img_col[...,:3], [0.299, 0.587, 0.114]) #convert to gray
threshold = 25 
mask2D = img_gray < threshold # some exemplary mask 
mask3D = np.atleast_3d(mask2D)*np.ones_like(img_col) # expand to 3D with broadcasting...
# using numpy's masked array to specify where data is valid
m_img_gray = np.ma.masked_where( mask2D, img_gray)
m_img_col  = np.ma.masked_where( mask3D, img_col)

fig,axes=plt.subplots(1,4,num=2,clear=True)
axes[0].imshow(mask2D.astype(np.float32)) # plot mask
axes[0].set_title("simple mask")
axes[1].imshow(m_img_gray,"gray") #plot gray verison => works 
axes[1].set_title("(works)\n masked gray")
axes[2].imshow(m_img_col)  #plot color version, => does not work
axes[2].set_title("(doesn't work)\n masked color")

# manually adding mask as alpha channel to show what I want
axes[3].imshow( np.append( m_img_col.data, 255*(1-(0 < np.sum(m_img_col.mask ,axis=2,keepdims=True) ).astype(np.uint8) ),axis=2) )
axes[3].set_title("(desired) \n alpha channel set manually")

这是一个示例图像:

[更新]: 为了更清晰,对代码和图像进行了一些小改动...

【问题讨论】:

  • 无法解决您的问题,但 1) 您的面罩无法正常广播。如果你这样做np.unique(m_img_col.mask.sum(-1)),你会看到你的像素被屏蔽了 1 或 2 个通道,这不应该是正确的。试试m_img_col = np.ma.masked_where( np.broadcast_to(mask2D[..., None], img.shape) * img, img)。 2)很可能你不能用RGB做同样的事情,因为屏蔽一个像素意味着屏蔽3个值而不是1个。此时使用RGBA更直观,更安全(如何处理
  • 感谢您的信息... 这个简单示例中的问题是 np.ma.masked_where 中的掩码生成。我不应该乘以图像,因为它也可以是 0。所以这是一个正确的版本: m_img_col = np.ma.masked_where( np.atleast_3d(mask2D)*np.ones_like(img), img) 无论如何,在我的实际应用程序中,我已经提供了掩码,所以这不是问题,但感谢您发现它:)

标签: python numpy matplotlib masked-array


【解决方案1】:

我不知道这是否是 matplotlib 尚未提供的功能,但你可以 只需将掩码为 True 的所有值设置为 255:

m_img_col.data[m_img_col.mask]=255

这样无效区域将显示为透明

【讨论】:

  • 这个方法不是透明的,只是用白色填充蒙面军团。发布图中的白色部分只是白色背景的颜色。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-14
  • 1970-01-01
  • 2017-03-28
  • 2021-08-19
相关资源
最近更新 更多