python - 如果该 RGB 值属于列表,如何替换图像中的所有 RGB 值

标签 python numpy

如果图像中的 RGB 值在我的列表中且没有循环,我需要更改该图像中的所有 RGB 值。

我知道为了改变 RGB 值我只需要这样做:

img[np.all(img == (99, 121, 109), axis=-1)] = (255,255,255)

但是,例如,在我的例子中,值 (99, 121, 109) 属于一个列表

   rgbL = [[99, 121, 109], 
           [102, 118, 107], 
           [102, 126, 114], 
                   .......,
           [105, 114, 101]]

为了更改属于我的 rgbL 列表的图像中的所有 RGB 值,我需要循环到我的 rgbL 的所有值。但我的 list 太长了。有没有一种方法可以在不循环的情况下做到这一点?

最佳答案

不幸的是,没有快速的方法可以做到这一点。无论您使用循环还是优化的 numpy 解决方案,在幕后您都必须对照 rgbL 的每个元素检查每个像素。鉴于此,您可以使用 isinstructured array 结合view数据以执行正确的分组。

诀窍是制作一个 custom type代表像素。这样,您就可以比较整个元素而不是颜色 channel ,这是 isin 默认情况下所做的。

pixel = np.dtype([('r', img.dtype), ('g', img.dtype), ('b', img.dtype)])

您不能将像素数据类型定义为子数组类型,如 pixel = np.dtype((img.dtype, img.shape[-1]))。当您尝试查看数据时,这将导致错误。

您现在可以将 img 视为 pixel 元素的 2D 数组,而不是 uint8float< 的 3D 数组,视情况而定:

data = img.view(pixel).squeeze(axis=-1)

您可以对列表执行相同的操作:

rgbA = np.array(rgbL).view(pixel).squeeze(axis=-1)

你也可以这样做

rgbA = np.array([tuple(p) for p in rgbL], dtype=pixel)

您不能使用np.array(rgbL, dtype=pixel),因为在这种情况下元素将无法正确初始化。

现在 isin 将为您提供您想要的掩码:

mask = np.isin(data, rgbA)

可以直接敷面膜:

data[mask] = 255

如果要设置 channel 之间不同的值,请记住使用元组来指定像素条目:

>>> data[mask] = (255, 255, 255)  # OK
>>> data[mask] = [255, 255, 255]
ValueError: NumPy boolean array indexing assignment cannot assign 3 input values to the 1 output values where the mask is true

由于 dataimg 的 View ,因此您已完成。

注意:仅当您的图像在三维空间中连续时,此方法才有效。否则,您将无法对两个数组使用相同的数据类型。如果不是这种情况,您将必须复制图像数据,以便它至少在三维空间中是连续的。对于大多数在高光谱图像或其他东西上不是奇怪 View 的正常阵列,你会没事的。

TL;DR

pixel = np.dtype([('r', img.dtype), ('g', img.dtype), ('b', img.dtype)])

def replace(img, pixels, value):
    data = img.view(pixel).squeeze(-1)
    pixels = np.array(pixels, dtype=img.dtype).view(pixel).squeeze(-1)
    data[isin(data, pixels)] = tuple(value)

关于python - 如果该 RGB 值属于列表,如何替换图像中的所有 RGB 值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61850743/

相关文章:

python - MATLAB/Octave corr 和 Python numpy.correlate 有什么区别?

python-2.7 - 使用 numpy.histogram2d 和 matplotlib 绘制二维直方图时遇到问题

python线性回归实现

Python C++ api - 在函数重载中返回不同类型

python - pretty-print SciPy 数组

python - 使用numpy数组实现softmax函数

python - 如何在OpenCV中将图片复制并粘贴为画中画

python - 根据每个 ID 的阈值日期选择 pandas 中的行

python - 输入列表中的单个项目

python - HDF5-DIAG : Error detected in HDF5 (1. 8.11)