用于“高对比度"的快速公式.曲线 [英] Fast formula for a "high contrast" curve
问题描述
我的内循环包含一个计算,分析表明存在问题.
My inner loop contains a calculation that profiling shows to be problematic.
该想法是取灰度像素x(0 <= x <1),并增加其对比度".我的要求很宽松,只有以下几点:
The idea is to take a greyscale pixel x (0 <= x <= 1), and "increase its contrast". My requirements are fairly loose, just the following:
- 对于x< .5,0< = f(x)< x
- 对于x> .5,x
- f(0)= 0
- f(x)= 1-f(1-x),即它应该是对称的"
- 最好,函数应该平滑.
因此图必须看起来像这样:
So the graph must look something like this:
.
我有两种实现方式(它们的结果不同,但都一致):
I have two implementations (their results differ but both are conformant):
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;
}
因此,我要求对这些实现之一进行微优化,或者要求使用自己的原始更快的公式.
So I request either a microoptimization for one of these implementations, or an original, faster formula of your own.
也许你们当中的一位甚至可以旋转这些位;)
Maybe one of you can even twiddle the bits ;)
推荐答案
通常,您可以简单地设置阈值,但是我认为这太愚蠢了:
Trivially you could simply threshold, but I imagine this is too dumb:
return i < 0.5 ? 0.0 : 1.0;
由于您提到对比度增加",因此我假设输入值为亮度值.如果是这样,并且它们是离散的(也许是8位值),则可以使用查找表来快速完成此操作.
Since you mention 'increasing contrast' I assume the input values are luminance values. If so, and they are discrete (perhaps it's an 8-bit value), you could use a lookup table to do this quite quickly.
您的"mulContrastize"看起来相当快.一种优化是使用整数数学.再次说,您的输入值实际上可以作为[0..255]中的8位无符号值传递. (再次,可能是一个很好的假设?)您可以做类似...的事情.
Your 'mulContrastize' looks reasonably quick. One optimization would be to use integer math. Let's say, again, your input values could actually be passed as an 8-bit unsigned value in [0..255]. (Again, possibly a fine assumption?) You could do something roughly like...
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);
这篇关于用于“高对比度"的快速公式.曲线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!