2013-03-21 4 views
5

Ich habe begonnen, ein Bildverarbeitungsprogramm aus verschiedenen Bildverarbeitungsalgorithmen zu programmieren, meistens aus der Arbeit von René Schulte, und beim Benchmark habe ich festgestellt, dass ich von allen Effekten aus verschiedenen Quellen a Code für die Anwendung eines "Softlight" -Effekts war der langsamste. Ich bin nicht gut darin, die Gleichung zu optimieren, aber ich glaube, dass der Filter auf einer Formel basiert, die vielleicht Variablen ohne Grund wiederholt.Ist diese Formel repetitiv oder optimal?

Könnte dies in etwas kürzer oder schneller zusammengefasst werden?

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

[Bearbeiten - Ergebnisse der Gleichung Mohammed Hossain über Softlight in PS gefunden mit]

// 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 

[Bearbeiten]

Hier ist der schnellste Algorithmus basiert auf Mohammed Hossain Antwort:

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)));   
} 
+0

Ich hoffe würde, dass Compiler gemeinsame subexpression Beseitigung tun würde, aber als Fließ- Point goes involved ... – nneonneo

+0

Und googlen den Namen des Kerls, der diesen Code zur ursprünglichen Quelle hinzugefügt hat, gibt nichts zurück. Ich werde am Ende den Coder rufen! –

+0

Arithmetische Operationen auf Float sind teurer als auf ganze Zahlen. Wenn es möglich ist ändere die Parameter-Typen zu int, dann kann ich eine Lösung liefern –

Antwort

4

Diese Antwort sollte Ihnen helfen und einige Dinge ein wenig aufklären: How does photoshop blend two images together?

Eine der Gleichungen ist der Softlight-Algorithmus.

#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 

Es vermeidet vor allem die teure Quadratwurzeloperation und weniger wichtiger verwendet Bit-Shift-Operatoren anstelle der Division durch 2 (die durch intelligente Compiler optimiert entfernt werden soll, sowieso). Es verwendet auch mehr Integer-Operationen als Floating-Operationen, was schneller ist.

ist hier eine andere Formel (mit freundlicher Genehmigung der Eigentümer der this, die die Operationen des variablen Schalter, und es funktioniert scheinbar ...

#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)))); 
+0

Wow, du hast genau den Zusammenhang der Gleichung. Megaupvote! –

+0

Ich weiß nicht, was ich falsch mache, aber es gibt nicht das richtige Bild zurück: 'int csoftLight (Byte A, Byte B) { Rückgabe ((Byte) ((B <128)? (2 * ((A >> 1) + 64)) * ((float) B/255): (255 - (2 * (255 - ((A >> 1) + 64)) * (float) (255 - B)/255)))); } ' –

+1

Sie müssen das für jeden Kanal des Pixels aufrufen; Wenn Sie dies in RGB tun, müssen Sie es dreimal aufrufen (R, G, B). Das Endprodukt besteht aus drei Werten (R, G, B), die die drei Kanäle des Ausgangspixels darstellen. Machst du das gerade? –

Verwandte Themen