“高对比度”曲线的快速公式

问题描述 投票:5回答:3

我的内部循环包含一个计算,分析显示有问题。

想法是采用灰度像素x(0 <= x <= 1),并“增加其对比度”。我的要求相当宽松,如下:

  • 对于x <.5,0 <= f(x)<x
  • 对于x> .5,x <f(x)<= 1
  • f(0)= 0
  • f(x)= 1 - f(1 - x),即它应该是“对称的”
  • 优选地,该功能应该是平滑的。

因此图表必须如下所示:

.

我有两个实现(他们的结果不同但两者都符合):

float cosContrastize(float i) {
    return .5 - cos(x * pi) / 2;
}

float mulContrastize(float i) {
    if (i < .5) return i * i * 2;
    i = 1 - i;
    return 1 - i * i * 2;
}

因此,我要求对这些实现之一进行微优化,或者为您自己的原始,更快的公式。

也许你们其中一个人甚至可以把这些小事扭曲;)

optimization math formula
3个回答
5
投票

琐碎的你可能只是门槛,但我想这太愚蠢了:

return i < 0.5 ? 0.0 : 1.0;

由于你提到'增加对比度',我假设输入值是亮度值。如果是这样,并且它们是离散的(可能是8位值),您可以使用查找表来快速完成此操作。

你的'mulContrastize'看起来相当快。一个优化是使用整数数学。让我们再次说明,您的输入值实际上可以作为[0..255]中的8位无符号值传递。 (再次,可能是一个很好的假设吗?)你可以做一些大致相似的事情......

int mulContrastize(int i) {
  if (i < 128) return (i * i) >> 7; 
  // The shift is really: * 2 / 256
  i = 255 - i;
  return 255 - ((i * i) >> 7);

13
投票

考虑以下sigmoid形函数(正确转换为所需范围):

我使用MATLAB生成了上图。如果有兴趣,这里是代码:

x = -3:.01:3;
plot(   x, 2*(x>=0)-1, ...
        x, erf(x), ...
        x, tanh(x), ...
        x, 2*normcdf(x)-1, ...
        x, 2*(1 ./ (1 + exp(-x)))-1, ...
        x, 2*((x-min(x))./range(x))-1  )
legend({'hard' 'erf' 'tanh' 'normcdf' 'logit' 'linear'})

4
投票

分段插值可以快速灵活。它只需要几个决策,然后进行乘法和加法,并且可以近似任何曲线。它还避免了查找表可以引入的过程(或两次查找中的额外成本,然后通过插值来平滑这一点),尽管lut可能对您的情况完全正常。

alt text

只需几个部分,您就可以获得非常好的匹配。这里将有颜色渐变的路线,这将比绝对颜色的路线更难检测。

正如Eamon Nerbonne在评论中指出的那样,可以通过“根据二阶导数选择分割点以最大化细节”来优化分割,也就是说,斜率变化最大的地方。很明显,在我发布的示例中,在五个分段案例的中间有三个段不会添加更多细节。

© www.soinside.com 2019 - 2024. All rights reserved.