Page 3 of 10

Re: "Sigmoidal" minimization of resampling filter haloing

Posted: 2012-07-15T17:27:49-07:00
by anthony
magick wrote:We'll restore the expanded sigmoidal contrast definition assuming Anthony does not object.

I do object. Especially in a theoretical discussion like this.

This is only an exploration of sigmoidal contrast.

It is important that the + form is the inverse of the - form. I am not certain what the difference between the two functions are, but don't change things until we know if it is right or not.

Re: "Sigmoidal" minimization of resampling filter haloing

Posted: 2012-07-15T17:45:55-07:00
by anthony
NicolasRobidoux wrote:
fmw42 wrote:...What is the functional difference?...

Code: Select all

#define sigmoidal(a,b,x)  (1/(1+exp((a)*((b)-(x)))))
#if 0
        /* Simpilified function scaling,
         * with better 'contrast=0' or 'flatline' handling (greyscale)
         */
        double
          u0 = sigmoidal(contrast,QuantumScale*midpoint,0.0),
          u1 = sigmoidal(contrast,QuantumScale*midpoint,1.0);
        sigmoidal_map[i]=(MagickRealType) ScaleMapToQuantum(
           (MagickRealType)(MaxMap*(
               (sigmoidal(contrast,QuantumScale*midpoint,(double)i/MaxMap)
                  -(u0+u1)/2.0)/(u1-u0+MagickEpsilon)+0.5)   ));
#else
        /* Scaled sigmoidal formula...
             (1/(1+exp(a*(b-u))) - 1/(1+exp(a))) /
                     (1/(1+exp(a*(b-1)))/(1+exp(a)))) */
        sigmoidal_map[i]=(MagickRealType) ScaleMapToQuantum((MagickRealType)
          (MaxMap*((1.0/(1.0+exp(contrast*(midpoint/(double) QuantumRange-
          (double) i/MaxMap))))-(1.0/(1.0+exp(contrast*(midpoint/
          (double) QuantumRange)))))/((1.0/(1.0+exp(contrast*(midpoint/
          (double) QuantumRange-1.0))))-(1.0/(1.0+exp(contrast*(midpoint/
          (double) QuantumRange)))))+0.5));
#endif
        continue;
      }
#if 0
    {
      /* Inverse -- See
         http://osdir.com/ml/video.image-magick.devel/2005-04/msg00006.html
      */
      double
        min = sigmoidal(contrast,1.0,0.0),
        max = sigmoidal(contrast,QuantumScale*midpoint,1.0),
        xi  = min+(double)i/MaxMap*(max-min);
      sigmoidal_map[i]=(MagickRealType) ScaleMapToQuantum(
         (MagickRealType)(MaxMap*(
             QuantumScale*midpoint-log((1-xi)/xi)/contrast) ));
    }
#else
    /* expanded form of the above */
    sigmoidal_map[i]=(MagickRealType) ScaleMapToQuantum((MagickRealType)
      (MaxMap*(QuantumScale*midpoint-log((1.0-(1.0/(1.0+exp(midpoint/
      (double) QuantumRange*contrast))+((double) i/MaxMap)*((1.0/
      (1.0+exp(contrast*(midpoint/(double) QuantumRange-1.0))))-(1.0/
      (1.0+exp(midpoint/(double) QuantumRange*contrast))))))/
      (1.0/(1.0+exp(midpoint/(double) QuantumRange*contrast))+
      ((double) i/MaxMap)*((1.0/(1.0+exp(contrast*(midpoint/
      (double) QuantumRange-1.0))))-(1.0/(1.0+exp(midpoint/
      (double) QuantumRange*contrast))))))/contrast)));
#endif
The "#if 0"s above were "#if 1"s until today, so what you are using right now are actually the first version of each of the two functions, which appear to have been put together so that things don't break down when contrast = 0, in which case u0=u1. The bad news for me is that the sigmoidal map which is supposed to be an inverse is then fairly far from being an inverse even when far from contrast=0.

The two functions should be the same. If they aren't then something went wrong.

The reason the change was made was because Fred insisted that a '0' (and non-sensical, default is 1) contrast handling produces a flat pure gray image, rather than pure black.

In both cases (except the flatline case) the function should be scaled so that black maps to black and white to white. The difference is the 'center' for scaling is a mid-point rather than zero. That mid-point scaling complication, ment the introduction of macros, which simplified the otherwise very complex calculation,

BOTH versions should produce the same results (within quantum rounding) except when near the degenerate '0' or flat line case. If the two versions are not the same then there is an error.

I do not believe the + version was modified. (scale around 0 rather than mid-point). The only inverse difference should be again near the degenerate 'flatline' case, as information loss takes effect.

NOTE; I was against this change as I considered the degenerate flatline case to be something that should never be used. However Fred insisted that it be handled.

I now remove my objection to reverting back. OR better still -- Why are the two not equivalent? At least for non-degenerate cases.

Re: "Sigmoidal" minimization of resampling filter haloing

Posted: 2012-07-15T18:48:35-07:00
by fmw42
The reason the change was made was because Fred insisted that a '0' (and non-sensical, default is 1) contrast handling produces a flat pure gray image, rather than pure black.
I don't recall all the details, but as I recall, my issue was that it was originally limited to a minimum value of 1. Values below were treated as if 1. It was stated that at that value of 1, it was unchanged from the original. But I could measure via compare significant differences. Thus I asked that it be allowed to go nearer to zero. However at zero it becomes degenerate.

Re: "Sigmoidal" minimization of resampling filter haloing

Posted: 2012-07-15T20:47:22-07:00
by fmw42
Just wondering if the problem might be that the change was made to -sigmoidal-contrast, but not to +sigmoidal-contrast

Re: "Sigmoidal" minimization of resampling filter haloing

Posted: 2012-07-15T21:13:45-07:00
by anthony
If the results of the two -sigmoidal-contrast formulas are the same (any they should be) then +sigmodial contrast should work fine. as mentioned the two should only differ as you get close to the degenerate case, as image color starts to become lost due to quantum rounding errors.

The plus version is not something we should play with. It works.

So Nickolas... How does the two formulas differ? Because that is a bug!

Re: "Sigmoidal" minimization of resampling filter haloing

Posted: 2012-07-15T22:12:50-07:00
by fmw42
If the results of the two -sigmoidal-contrast formulas are the same (any they should be) then +sigmodial contrast should work fine. as mentioned the two should only differ as you get close to the degenerate case, as image color starts to become lost due to quantum rounding errors.
Have you checked the code to see if the + form was actually changed to correspond to the - form change?

Fred

Re: "Sigmoidal" minimization of resampling filter haloing

Posted: 2012-07-16T04:45:22-07:00
by NicolasRobidoux
I'll try to help sorting things out.

Re: "Sigmoidal" minimization of resampling filter haloing

Posted: 2012-07-16T06:42:49-07:00
by NicolasRobidoux
I may as well add the sigmoidal result with a scheme that I like a lot, EWA Lanczos 3 with deblur fixed so the radius of the EWA disk is exactly equal to the number of lobes:

Code: Select all

magick rose: -set colorspace sRGB -colorspace RGB +sigmoidal-contrast 10,80% -filter Lanczos -define filter:blur=.9264075766146068 -distort resize 800x -sigmoidal-contrast 10,80% -colorspace sRGB lanczosRadius3TenEightyLinear.png
I'm actually starting to think that this should replace Robidoux as the EWA default. (Despite Anthony's initial misgivings RE: the derivation of this family of EWA schemes.)
Image
The jaggies suppression is just top notch given how sharp the scheme is. Would you believe that this is an enlargement by almost 12 times of viewtopic.php?f=22&t=21415&start=15#p87638?
(Warning: If you want to try this at home, you must have a days old version of ImageMagick.)

Re: "Sigmoidal" minimization of resampling filter haloing

Posted: 2012-07-16T13:33:14-07:00
by NicolasRobidoux
Given that I am not so sure that "worst case scenarios" are prevented by moving the midpoint from 50% (when in linear light), here is a very sharp version with unmoved midpoint:

Code: Select all

magick rose: -set colorspace sRGB -colorspace RGB +sigmoidal-contrast 9,50% -filter Lanczos -define filter:blur=0.88549061701764 -distort resize 800x -sigmoidal-contrast 9,50% -colorspace sRGB lanczossharpestNineFiftyLinear.png
Image
It is as sharp (sharper?) as regular (orthogonal) Lanczos but better antialiased.
But I suspect that this scheme is too sharp (hence my fondnesss for the "Radius3" version).
P.S. Still not sure, but I think lanczossharpest is too sharp. lanczosradius3 is still my top "sharp" (but not too sharp) contender.

Re: "Sigmoidal" minimization of resampling filter haloing

Posted: 2012-07-17T12:52:47-07:00
by NicolasRobidoux
A lot of settings work well, but this one is probably close to a "safe" but sharp all around setting:

Code: Select all

magick rose: -set colorspace sRGB -colorspace RGB +sigmoidal-contrast 6,50% -filter Lanczos -define filter:blur=.9264075766146068 -distort resize 800x -sigmoidal-contrast 6,50% -colorspace sRGB lanczosRadius3SixFiftyLinear.png
Image
The big question, which I have not had time to look into at all, is whether such methods work well when downsampling. Given that haloing is less of an issue, and that "physical heuristics" as well as much experience suggest that one should downsample through linear light, I would tend to think "no". But I am far from sure that this would always hold, esp. if the result of downsampling shows too much haloing.

Re: "Sigmoidal" minimization of resampling filter haloing

Posted: 2012-07-17T17:16:57-07:00
by magick
FYI, '-set colorspace sRGB' is unnecessary. Rose is already in the sRGB colorspace.

Re: "Sigmoidal" minimization of resampling filter haloing

Posted: 2012-07-17T18:35:16-07:00
by NicolasRobidoux
Magick: Thank you.

Re: "Sigmoidal" minimization of resampling filter haloing

Posted: 2012-07-17T19:27:30-07:00
by NicolasRobidoux
There is starting to be quite a bit of evidence that optimal is something like 8,50%. For one thing, contrast 8 more or less minimizes the difference between EWA Lanczos Radius 3 and tensor (orthogonal) Lanczos 3 in max norm when checked with the "chip" test image.
Here is an example, with orthogonal Lanczos 3 this time:

Code: Select all

magick input_small.png -colorspace RGB +sigmoidal-contrast 8,50% -filter Lanczos -resize 400% -sigmoidal-contrast 8,50% -colorspace sRGB RegularLanczosEightFiftyLinear.png
Image
Again: It has the sharpness expected of a Lanczos method, but the halos are almost completely gone. You'd never get that by applying sharpening or contrast enhancement post-enlargement.

Re: "Sigmoidal" minimization of resampling filter haloing

Posted: 2012-07-17T21:59:02-07:00
by anthony
I am not certain if any of this is any better than the original resize!
See the new example section (give it a couple of hours)
http://www.imagemagick.org/Usage/resize ... _sigmoidal


I think I'll remove the use of the integer support sized 3 lobe lancoz in these examples.
Or add it as a separate 'resize technique'.

Re: "Sigmoidal" minimization of resampling filter haloing

Posted: 2012-07-18T02:04:04-07:00
by henrywho
Seems sigmoidal-downsizing increases the brightness of all interpolated areas.

Try it on http://www.dcfever.com/phones/viewsampl ... cture=7234, the buildings over the other side of the harbour looks brighter and the tall building on the left looks more "cooked".

Code: Select all

convert.exe 755_1340939905483.jpg -colorspace RGB +sigmoidal-contrast 8,50% -define filter:filter=Jinc -define filter:window=Jinc -define filter:lobes=3 -define filter:blur=0.9264075766146068 -distort resize 1280x720 -sigmoidal-contrast 8,50% -colorspace sRGB -quality 95% 755_1340939905483_jj3r_sig.png

convert.exe 755_1340939905483.jpg -colorspace RGB -define filter:filter=Jinc -define filter:window=Jinc -define filter:lobes=3 -define filter:blur=0.9264075766146068 -distort resize 1280x720 -colorspace sRGB -quality 95% 755_1340939905483_jj3r_lin.png