Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is this formula repetitive or optimal

I've started to code a image processing program from different image processing algorithms, mostly from René Schulte work, and when benchmarking, I noticed that from all the effects I could find from different sources, a code for applying a 'Softlight' effect was the slowest. I'm not good in optimizing equation, but I feel that the filter is based on a formula that is maybe repeating variables with no reason.

Could this be summarized in something shorter or faster?

// 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))));
       }

[Edit - Results using the equation Mohammed Hossain found about softlight in 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

[Edit]

Here's the quickest algorithm based on Mohammed Hossain answer:

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)));          
}
like image 709
Léon Pelletier Avatar asked Oct 04 '22 15:10

Léon Pelletier


1 Answers

This answer should help you and clarify some things up a bit: How does photoshop blend two images together?

One of the equations is the soft light algorithm.

#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

It importantly avoids the costly square root operation and less importantly uses bit-shift operators in place of division by 2 (which should be optimized away by smart compilers, anyways). It also uses more integer operations than floating operations, which is more faster.

Here is another formula (courtesy to the owners of this which switches the variable's operations, and it seemingly works...

#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))));
like image 83
Mohammed Hossain Avatar answered Oct 10 '22 03:10

Mohammed Hossain