3

我正在使用带有 NumPy 的查找表 (LUT) 实现颜色插值。有一次,我使用 RGB 值的 4 个最高有效位从 17x17x17x4 LUT 中选择相应的 CMYK 值。现在它看起来像这样:

import numpy as np
rgb = np.random.randint(16, size=(3, 1000, 1000))
lut = np.random.randint(256, size=(17, 17, 17, 4))
cmyk = lut[rgb[0], rgb[1], rgb[2]]

第一个问题来了……有没有更好的办法?您可以告诉 NumPy 的索引lut是沿轴 0 存储的rgb,而不必实际写出来,这似乎很自然。cmyk = lut.fancier_take(rgb, axis=0)那么在 NumPy中有什么类似的东西吗?

此外,我留下了一个 shape 数组(1000, 1000, 4),因此为了与输入保持一致,我需要使用几个来旋转它swapaxes

cmyk = cmyk.swapaxes(2, 1).swapaxes(1, 0).copy()

而且我还需要添加复制语句,因为如果不是,结果数组在内存中不连续,这会给以后带来麻烦。

现在我倾向于在花哨的索引之前旋转 LUT,然后按照以下方式做一些事情:

swapped_lut = lut.swapaxes(2, 1).swapaxes(1, 0)
cmyk = swapped_lut[np.arange(4), rgb[0], rgb[1], rgb[2]]

但同样,它似乎并不正确......必须有一种更优雅的方式来做到这一点,对吧?像cmyk = lut.even_fancier_take(rgb, in_axis=0, out_axis=0)...

4

2 回答 2

3

我建议使用tuple强制索引按行,np.rollaxistranspose代替swapaxes

lut[tuple(rgb)].transpose(2, 0, 1).copy()

或者

np.rollaxis(lut[tuple(rgb)], 2).copy()

要首先滚动轴,请使用:

np.rollaxis(lut, -1)[(Ellipsis,) + tuple(rgb)]
于 2012-08-17T23:48:33.903 回答
1

lut如果您 swap ,您将需要执行以下操作,np.arange(4)这将不起作用:

swapped_lut = np.rollaxis(lut, -1)
cmyk = swapped_lut[:, rgb[0], rgb[1], rgb[2]].copy()

或者你可以更换

cmyk = lut[rgb[0], rgb[1], rgb[2]]
cmyk = cmyk.swapaxes(2, 1).swapaxes(1, 0).copy()

和:

cmyk = lut[tuple(rgb)]
cmyk = np.rollaxis(cmyk, -1).copy()

但是要尝试一步完成所有操作,...也许:

rng = np.arange(4).reshape(4, 1, 1)
cmyk = lut[rgb[0], rgb[1], rgb[2], rng]

这根本不是很可读是吗?

看看这个问题的答案,Numpy multi-dimensional array indexing swaps axis order。它很好地解释了 numpy 如何广播多个数组以获得输出大小。在这里,您要在 lut 中创建广播到 (4, 1000, 1000) 的索引。希望这有点道理。

于 2012-08-17T23:30:58.250 回答