5

我已经开始使用不同的图像处理算法编写图像处理程序,主要来自 René Schulte 的工作,并且在进行基准测试时,我注意到从我可以从不同来源找到的所有效果中,应用“柔光”效果的代码是最慢的。我不擅长优化方程,但我觉得过滤器是基于一个可能无缘无故重复变量的公式。

这可以用更短或更快的方式来概括吗?

// Basically, b is from Image A, and t from Image B
int csoftLight(float b, float t)
      {
          b /= 255;
          t /= 255;

          return (int)((t < 0.5) ? 255 * ((1 - 2 * t) * b * b + 2 * t * b) : 255 * ((1 - (2 * t - 1)) * b + (2 * t - 1) * (Math.Pow(b, 0.5))));
       }

[编辑 - 使用 Mohammed Hossain 在 PS 中发现的关于柔光的方程的结果]

// Input: 137 and 113

// Byte version:
int other = ((byte)((B < 128) ? (2 * ((A >> 1) + 64)) * ((float)B / 255) : (255 - (2 * (255 - ((A >> 1) + 64)) * (float)(255 - B) / 255))));
// Returns 116    


// float version:
int res = (int)((t < 0.5) ? 255 * ((1 - 2 * t) * b * b + 2 * t * b) : 255 * ((1 - (2 * t - 1)) * b + (2 * t - 1) * (Math.Pow(b, 0.5))));
// Returns 129

[编辑]

这是基于 Mohammed Hossain 答案的最快算法:

int csoftLight(byte A, byte B)
{
    return (int)((A < 128) ? (2 * ((B >> 1) + 64)) * ((float)A / 255) : (255 - (2 * (255 - ((B >> 1) + 64)) * (float)(255 - A) / 255)));          
}
4

1 回答 1

4

这个答案应该可以帮助您并澄清一些事情:Photoshop如何将两张图像混合在一起?

方程式之一是柔光算法。

#define ChannelBlend_SoftLight(A,B) ((uint8)((B < 128)?(2*((A>>1)+64))*((float)B/255):(255-(2*(255-((A>>1)+64))*(float)(255-B)/255)))) //not very accurate

它重要的是避免了昂贵的平方根运算,更重要的是使用位移运算符代替除以 2(无论如何,这应该由智能编译器优化掉)。它还使用比浮点运算更多的整数运算,速度更快。

这是另一个公式(由它的所有者提供,切换变量的操作,它似乎有效......

#define ChannelBlend_SoftLight(A,B) (uint8)(((A < 128) ? (2 * ((B >> 1) + 64)) * ((float) A / 255) : (255 - (2 * (255 - ((B >> 1) + 64)) * (float) (255 - A) / 255))));
于 2013-03-21T18:55:31.327 回答