Frage

Meine innere Schleife enthält eine Berechnung, die zeigt Profilierungs problematisch.

Die Idee ist, ein Graustufen-Pixel x nehmen (0 <= x <= 1) und "erhöht den Kontrast". Meine Anforderungen sind ziemlich locker, nur das folgende:

  • für x <0,5, 0 <= f (x)
  • für x> 0,5, x
  • f (0) = 0
  • f (x) = 1 - f (1 - x), das heißt es soll "symmetrische"
  • sein
  • Vorzugsweise sollte die Funktion glatt sein.

So das Diagramm wie folgt aussehen muss:

Grafik.

Ich habe zwei Implementierungen (ihre Ergebnisse unterscheiden sich aber beide sind konformes):

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 bitte ich entweder eine microoptimization für eine dieser Implementierungen oder ein Original, schnellere Formel der eigenen.

Vielleicht kann einer von euch auch die Bits twiddle;)

War es hilfreich?

Lösung

Trivial können Sie einfach Schwelle, aber ich glaube, dies zu dumm ist:

return i < 0.5 ? 0.0 : 1.0;

Da Sie zunehmenden Kontrast "erwähnen gehe ich davon aus die Eingangswerte Luminanzwerte sind. Wenn ja, und sie sind diskret (vielleicht ist es ein 8-Bit-Wert), könnten Sie eine Lookup-Tabelle verwenden, um dies zu tun, ganz schnell.

Ihre 'mulContrastize' sieht ziemlich schnell. Eine Optimierung wäre integer math zu verwenden. Sagen wir mal wieder Ihre Eingabewerte tatsächlich als ein 8-Bit-Wert ohne Vorzeichen weitergegeben werden konnten in [0..255]. (Auch hier möglicherweise eine gute Annahme?) Man könnte etwas tun, etwa wie ...

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

Andere Tipps

Betrachten Sie den folgenden sigmoid -förmigen Funktionen (richtig auf den gewünschten Bereich übersetzt):

Screenshot


ich die obige Abbildung mit MATLAB erzeugt. Wenn hier interessiert der Code:

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'})

Eine abschnittsweise Interpolation kann schnell und flexibel sein. Es erfordert nur wenige Entscheidungen, gefolgt von einer Multiplikation und Addition, und jede Kurve annähern kann. Es vermeidet auch die Verständlichkeit, die durch Lookup-Tabellen (oder die zusätzlichen Kosten in zwei Lookups, gefolgt von einer Interpolation dieser heraus zu glätten) eingeführt werden kann, obwohl die lut könnte für Ihren Fall perfekt funktionieren.

Mit nur wenigen Segmenten, können Sie ein ziemlich gutes Spiel zu bekommen. Hier wird es in den Farb Gradienten Verständlichkeit sein , die viel schwieriger sein wird als Verständlichkeit in den absoluten Farben zu erkennen.

Wie Eamon Nerbonne in den Kommentaren weist darauf hin, Segmentierung kann durch „choos [ing] Ihre Segmentierungspunkte basierend auf so etwas wie die zweite Ableitung Detail zu maximieren“ optimiert werden, das heißt, wo die Steigung am meisten verändert. Klar, in meinem geposteten Beispiel in der Mitte des fünf Segment Falles drei Segmente hinzufügen, nicht viel mehr ins Detail.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top