views:

373

answers:

3
+4  A: 

Trivially you could simply threshold, but I imagine this is too dumb:

return i < 0.5 ? 0.0 : 1.0;

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.

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);
Sean Owen
A threshold is too far from smooth to be useful in my case. They are luminance values, yeah. They aren't discrete values - they are actually floats, for two reasons. First, in OpenGL, float textures are fastest. And second, I made the decision to use 0.0-1.0 floats to make my math easy *and* fast. But I never thought of contrastizing with a lookup table, I'll look into that and see if it outweighs the OpenGL texture concern. The implementation you posted is nice indeed, but not as nice as a lookup table. And my mulContrastize is "reasonably quick" indeed, but not in such a tight inner loop :)
Stefan Monov
Btw, you shouldn't divide by 255 twice, just once. So you should shift by 7.
Stefan Monov
Oops you are right, that normalizes one step too far. Will fix the example.
Sean Owen
++ for the lookup-table suggestion.
Mike Dunlavey
Yeah, I ended up using a lookup table. By itself, it did zero improvement. But it allowed me to do several other optimizations - so - thanks!
Stefan Monov
40% final speedup, btw.
Stefan Monov
+10  A: 
Amro
+1. well-done.
Jason S
The OP's main issue is speed. How do these speed things up?
tom10
Thanks, at least I know they're called 'sigmoid' now ;) I did an easy implementation with tanh, it's as fast as the cos one. The rest will take quite a bit more thought and I think they'll be slower but we'll see.
Stefan Monov
++ Nice. Personally, I lean toward logit (actually it's the inverse logit function), because you only have to call exp() once, and a division. You can make it sharper by scaling X.
Mike Dunlavey
@tom10, the OP can see the formulas used, an consider which suites best.
Dykam
+2  A: 
tom10
And if you're really being snazzy, you can choose your segmentation points based on something like the second derivative to maximize detail (no point in differentiating segments in the central, fairly straight segment).
Eamon Nerbonne
@Eamon: Thanks for the second derivative idea. I knew I was being lazy with the center points, but I really like the generalization to the second derivative.
tom10