在我的图像编辑应用程序中,我有一个将 32 位浮点图像从 sRGB 转换为线性色彩空间的功能。公式为:

if value <= 0.04045: (value / 12.92)
if value > 0.04045: ((value + 0.055) / 1.055)^2.4)

我的图像是一个三维 numpy.ndarray 名为 img32

到目前为止我的实现:
boolarray = img32 <= 0.04045
lower = (img32 / 12.92) * boolarray.astype(np.int)
upper = np.power(((img32 + 0.055) / 1.055), 2.4) * np.invert(boolarray).astype(np.int)
img32 = lower + upper

所以,我正在创建一个新数组 boolarray ,其真值
什么是更好的解决方案?

我试过类似的东西:
img32[img32 < 0.04045] = img32 / 12.92

它在第一步中有效,但在第二个中失败:
img32[img32 >= 0.04045] = np.power(((img32 + 0.055) / 1.055), 2.4)

可能是因为包裹在 np.power 函数中时它不起作用

任何帮助表示赞赏。

最佳答案

一个干净的方法是使用 np.where ,它让我们根据掩码在两个值之间进行选择。在我们的例子中,掩码可以是 img32 >= 0.04045 ,我们将在 ((img32 + 0.055) / 1.055)**2.4 时选择 True ,否则选择 img32/12.92

所以,我们会有一个像这样的实现 -

np.where( img32 >= 0.04045,((img32 + 0.055) / 1.055)**2.4, img32/12.92 )

如果您非常关心内存并希望将结果写回到输入数组中,您可以通过创建和有选择地设置对应于这两个条件的 elems 分三步完成,如下所示 -
mask = img32 >= 0.04045
img32[mask] = ((img32[mask] + 0.055) / 1.055)**2.4
img32[~mask] = img32[~mask] / 12.92

示例案例 -
In [143]: img32 = np.random.rand(4,5).astype(np.float32)

In [144]: img32.nbytes
Out[144]: 80

In [145]: mask.nbytes
Out[145]: 20

因此,我们避免创建一个会消耗 80 字节的输出数组,而是在掩码上使用 20 字节。因此,将输入数组大小的 75% 保存在内存中。请注意,这可能会导致性能略有下降。

关于python - 在 Numpy 中将 sRGB 正确矢量化为线性转换,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39792163/

10-12 21:58