我正在使用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
的索引存储在rgb
的轴0上,而不必实际编写代码。那么,NumPy中是否有类似于cmyk = lut.fancier_take(rgb, axis=0)
的东西呢?
此外,我得到了一个形状为(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)
……
arange
。虽然效果很好,但我发现将lut
从(17, 17, 17, 4)
的形状转换为(4, 4913)
,然后使用take
和我自己版本的ravel_multi_index
来提取所需值,速度可以快10倍左右... - Jaime