【发布时间】:2018-02-21 10:34:38
【问题描述】:
我正在对尺寸为 5000x3000x3 的图像进行伽马校正。
公式是
值 ^ (1 / gamma)
对于 0.0 到 1.0 的 RGB 值
我的输入 gamma 值范围从 0.0 到 10.0,而 gamma = 0.0 始终输出 0.0。
问题在于所涉及的 pow 计算太慢了。
在 float[, ,] 上执行此操作大约需要 1300 毫秒:
for (int y = 0; y < 3000; y++)
{
for (int x = 0; x < 5000; x++)
{
for (int z = 0; z < 3; z++)
{
arr[x, y, z] = (float)Math.Pow(arr[x, y, z], 0.3);
}
}
}
在 FloatMatrix 上使用 NMathFunctions.Pow 大约需要 1100 毫秒:
a = NMathFunctions.Pow(a, 0.3f);
知道如何加快速度吗?
【问题讨论】:
-
根据您的精度要求,您始终可以设置查找表并使用最近邻或线性插值(或高阶插值,但这很可能无法解决性能问题)。
-
您是否考虑过添加并行化?在我看来,每个值都独立于其余值,因此并行算法没有理由不起作用
-
确实,在我问之前我做了很多谷歌搜索,但我希望能立即在 C# 中使用更简单的东西。感谢您的链接,我会通过它。我不是数学家,但请帮助我了解 2^(p*log2(x)) 如何简化任何事情?还涉及到 pow 操作?编辑:你为什么删除你的评论?
-
@Glubus 值得一试是的。我只是假设像 NMath 这样的库会处理这个问题。
-
@tde,我已经删除了评论,因为我的数学技能已经无法证明这一点(而且我无法在 5 分钟后编辑评论)。这个想法是将昂贵的操作表示为由便宜的操作组成的表达式,现在轮到谷歌了;)