Page 1 of 1

Sigmoidal equation(bug?) of image magick

Posted: 2013-01-19T06:49:16-07:00
by stereoMatching
According to this page
http://www.imagemagick.org/Usage/color_mods/#sigmoidal

The equation of the sigmoidal should be
(1/(1+exp(β*(α-u))) - 1/(1+exp(β))) / (1/(1+exp(β*(α-1)))/(1+exp(β)))

In general, the Beta is 10 and the alpha is 0.5, IM give us a simple
command "-fx" with default Beta and alpha (Beta = 10, alpha = 0.5)

The value of the equation listed on the page looks like this

(1/(1+exp(10*(.5-u)))-0.0066928509)*1.0092503

From the equation, I find out that

A : 1 / (1+exp(β)) == 0.0066928509 when β == 10
B : 1 / (1+exp(β*(α-1))) / (1+exp(β)) == 1.0092503 when β == 10, α = 0.5

I try to implement this by C++ and find out the value is weird

Code: Select all

std::cout << 1 / (1 + std::exp(10)); //output 4.53979e-05 
The "correct Beta" is 5 but not 10

Code: Select all

std::cout << 1 / (1 + std::exp(5)); //output 0.0066928509
About B, I do it like this

Code: Select all

float temp = 1 / (1 + std::exp(10));
std::cout<<(1 / (1 + std::exp(10 * (0.5 - 1)))) * temp; //output 4.5094e-05 
This is not a correct equation or my program has bug?Thanks

Re: Sigmoidal equation(bug?) of image magick

Posted: 2013-01-19T10:41:32-07:00
by NicolasRobidoux
The following formula, from the Examples,
(1/(1+exp(β*(α-u))) - 1/(1+exp(β))) / (1/(1+exp(β*(α-1)))/(1+exp(β))))
is indeed incorrect. The last "/" should be a "-1/".
What's in the code is correct:

Code: Select all

#if defined(MAGICKCORE_HAVE_ATANH)
#define Sigmoidal(a,b,x) ( tanh((0.5*(a))*((x)-(b))) )
#else
#define Sigmoidal(a,b,x) ( 1.0/(1.0+exp((a)*((b)-(x)))) )
#endif
...
#define ScaledSigmoidal(a,b,x) (                    \
  (Sigmoidal((a),(b),(x))-Sigmoidal((a),(b),0.0)) / \
  (Sigmoidal((a),(b),1.0)-Sigmoidal((a),(b),0.0)) )
Thank you very much for pointing this out. BTW, the code, e.g. http://trac.imagemagick.org/browser/Ima ... /enhance.c has pretty clear comments that explain what's actually done.
Note: For HDRI, I'll modify the code further when I have a minute. I want to deal with out of gamut values by extending the sigmoidal with straight lines. (I already do that in the GEGL library. The LoHalo resampler uses sigmoidization extended with straight lines: http://git.gnome.org/browse/gegl/tree/g ... r-lohalo.c. Just no time yet to do that for ImageMagick, it's irrelevant with Q8 and Q16, and then using LUTs is not really an option.)

Re: Sigmoidal equation(bug?) of image magick

Posted: 2013-01-20T01:17:20-07:00
by stereoMatching
Thanks, the result are much more closer to the equation --(1/(1+exp(10*(.5-u)))-0.0066928509)*1.0092503

Although the last one has some different(precision problem?But double also give the same answer).

exponential version

Code: Select all

inline float sigmoidal(float contrast, float threshold, float signal)
{
    return 1 / (1 + std::exp(contrast * (threshold - signal)));
}

float const threshold = 0.5;
float const contrast = 10;
float const signal = 0.5;   
std::cout << 1 / (sigmoidal(contrast, threshold, 1) - sigmoidal(contrast, threshold, 0)); //answer is  1.01357
tanh version

Code: Select all

inline float sigmoidal_tanh(float contrast, float threshold, float signal)
{
    return (1 + std::tanh(0.5 * contrast * (signal - threshold))) / 2;
}

float const threshold = 0.5;
float const contrast = 10;
float const signal = 0.5;   
std::cout << 1 / (sigmoidal_tanh(contrast, threshold, 1) - sigmoidal_tanh(contrast, threshold, 0)); //answer is  1.01357 too
For HDRI, I'll modify the code further when I have a minute.
I beg for your pardon, what is HDRI(High Dynamic Range Imaging)?

By the way, I am an amateur about programming and digital image processing.
Which page is the best for me to ask when I have some problems about the source codes of IM?
developer or Digital Image Processing?Thanks

Re: Sigmoidal equation(bug?) of image magick

Posted: 2013-01-20T06:18:39-07:00
by NicolasRobidoux
What's in the Examples is only meant to illustrate the process. Don't obsess about the precision of the results.

With ImageMagick, HDRI means that when intermediate results are stored, they are stored in floating point instead of unsigned integers.

Where to post really depends on the content. >>I<< would have posted this thread in Bugs. On the other hand, your intent is not really to fix ImageMagick. You want to understand what it does and possibly replicate it. For that Users or Digital Image Processing are good choices.

If you had shown up in the totally wrong place, Cristy would have moved you.

Re: Sigmoidal equation(bug?) of image magick

Posted: 2013-01-20T17:30:50-07:00
by anthony
stereoMatching wrote:According to this page
http://www.imagemagick.org/Usage/color_mods/#sigmoidal

The equation of the sigmoidal should be
(1/(1+exp(β*(α-u))) - 1/(1+exp(β))) / (1/(1+exp(β*(α-1)))/(1+exp(β)))

In general, the Beta is 10 and the alpha is 0.5, IM give us a simple
command "-fx" with default Beta and alpha (Beta = 10, alpha = 0.5)
...

This is not a correct equation or my program has bug?Thanks
I have recalculated, and yes you are right. the original calculate was probably using beta=5
I have re-written the Fx formula to be....
-fx '(1/(1+exp(10*(.5-u)))-0.0000453978)*0.999997'

Of course at such a high Beta values the subtraction and multiplier are basically no-ops, so it does not make a lot of difference to the final image. It is at more normal value ranges that it makes a big difference.
NicolasRobidoux wrote:If you had shown up in the totally wrong place, Cristy would have moved you.
I think the bug here is more in documentation (for understanding) rather than a actual code bug.

Of course some of the discussion has gone off topic into other 'pet' sigmoidal curve methods, and that probably should be in a new topic in Digital processing as it is about general image processing and not IM specific. :-)

Re: Sigmoidal equation(bug?) of image magick

Posted: 2013-01-20T17:45:45-07:00
by anthony
However Something else may be wrong...
In Gunplot

Code: Select all

sig(x,a,b) = (1/(1+exp(b*(a-x))) - 1/(1+exp(b))) / (1/(1+exp(b*(a-1))/(1+exp(b))))
plot [0:1] sig(x,0.5,3)
The graph does not go though the 0,0 and 1,1 points which is what those constants are supposed to do to the graph. That is normalize the function. I do not know if this is the case in IM or not.

Re: Sigmoidal equation(bug?) of image magick

Posted: 2013-01-20T18:15:22-07:00
by NicolasRobidoux
Try this:

Code: Select all

sig(x,a,b) = (1/(1+exp(b*(a-x))) - 1/(1+exp(b*a))) / (1/(1+exp(b*(a-1))) - 1/(1+exp(b*a)))
plot [0:1] sig(x,0.5,3)
The example formula found in the Examples is not representative of what's in the code. This is.
What's done in ImageMagick always fixes things so that 0->0 and 1->1. (In GEGL I don't bother normalizing, but this is because I only use the sigmoidal function to perform sigmoidization.)

Re: Sigmoidal equation(bug?) of image magick

Posted: 2013-01-20T23:50:24-07:00
by anthony
Yeap that seems to work.

So the formula should be
( 1/(1+exp(β*(α-u))) - 1/(1+exp(β)) ) / ( 1/(1+exp(β*(α-1))) - 1/(1+exp(β*α)) )

Okay and in the example...
Example
a=0.5; b=10;
offset:
print 1/(1+exp(b*a))
0.00669285092428486
Multiplier:
print 1/( 1/(1+exp(b*(a-1))) - 1/(1+exp(b*a)) )
1.01356730981261

So...
convert test.png -fx '(1/(1+exp(10*(.5-u)))-0.006693)*1.013567' \
sigmoidal.png