Sigmoidized Ginseng (pronounced "Jinc-Sinc") resampling

Questions and postings pertaining to the usage of ImageMagick regardless of the interface. This includes the command-line utilities, as well as the C and C++ APIs. Usage questions are like "How do I use ImageMagick to create drop shadows?".
NicolasRobidoux
Posts: 1944
Joined: 2010-08-28T11:16:00-07:00
Authentication code: 8675308
Location: Montreal, Canada

Re: Sigmoidized Ginseng (pronounced "Jinc-Sinc") resampling

Post by NicolasRobidoux »

Here is a comparison of the enlargements obtained by using standard Lanczos3 through linear RGB (left), a copy of the above sigmoidized Ginseng with contrast = 11.9633 (middle), and standard Lanczos3 directly with the sRGB pixel values (right):
ImageImageImage
Linear RGB clearly loses, but it's not as if the difference between sigmoidized Ginseng and Lanczos 3 directly with sRGB jumps at you.
NicolasRobidoux
Posts: 1944
Joined: 2010-08-28T11:16:00-07:00
Authentication code: 8675308
Location: Montreal, Canada

Re: Sigmoidized Ginseng (pronounced "Jinc-Sinc") resampling

Post by NicolasRobidoux »

Same with the motocross image:
ImageImageImage
Again, Lanczos 3 through linear RGB clearly loses, and this time the difference between sigmoidized Ginseng and Lanczos 3 directly with sRGB is clearer: Less blur and jaggies and a bit less halo with sigmoidized Ginseng. With the motocross image in particular, it's clear that sigmoidized Ginseng is better at "smooth curves"; Lanczos 3 is a bit enslaved by the pixel grid. And yet all three methods are interpolatory. The eye of the frog is more natural with sigmoidized Ginseng as well.
Last edited by NicolasRobidoux on 2012-08-30T11:44:52-07:00, edited 1 time in total.
NicolasRobidoux
Posts: 1944
Joined: 2010-08-28T11:16:00-07:00
Authentication code: 8675308
Location: Montreal, Canada

Re: Sigmoidized Ginseng (pronounced "Jinc-Sinc") resampling

Post by NicolasRobidoux »

Again: Lanczos 3 through linear RGB on the left, sigmoidized Ginseng in the middle, and Lanczos 3 directly with sRGB pixel values on the right:
ImageImageImage
Enlarging through linear RGB loses again, but the difference between sigmoidized Ginseng and "direct sRGB" Lanczos 3 is small: A bit less halo and a smidgeon less blur and jagginess on the Ginseng side, and that's about it.
Note: If you zoom into the images with a decent viewer, the differences jump at you. This means that if I was to enlarge by more than 4, you'd notice the differences without having to scrutinize.
I have no doubt that if I was to enlarge enough (by 10x or more instead of 4x), most people would pick sigmoidized Ginseng over sRGB Lanczos 3. (Linear RGB Lanczos is out of the running.)
Last edited by NicolasRobidoux on 2012-08-30T11:41:09-07:00, edited 3 times in total.
NicolasRobidoux
Posts: 1944
Joined: 2010-08-28T11:16:00-07:00
Authentication code: 8675308
Location: Montreal, Canada

Re: Sigmoidized Ginseng (pronounced "Jinc-Sinc") resampling

Post by NicolasRobidoux »

Interestingly, passing all images through pngcrush (thank you Glenn Randers-Pehrson), the sigmoidized Ginseng images are always the smallest, the Lanczos 3 through linear RGB the largest (by a minuscule amount).
NicolasRobidoux
Posts: 1944
Joined: 2010-08-28T11:16:00-07:00
Authentication code: 8675308
Location: Montreal, Canada

Re: Sigmoidized Ginseng (pronounced "Jinc-Sinc") resampling

Post by NicolasRobidoux »

@Anthony: I'd add Quadratic to the list of recommended windowing functions (in the plot, for example). Not sure if it's commonly used/recommended, but back of the envelope says that with lots of lobes (4+) it may work well, and that it may work OK with really sharp images with 3 lobes. (I've not tried it.) And it kind of fits nicely into the collection: Halfway between Bartlett (linear spline) and Parzen (cubic spline).
NicolasRobidoux
Posts: 1944
Joined: 2010-08-28T11:16:00-07:00
Authentication code: 8675308
Location: Montreal, Canada

Re: Sigmoidized Ginseng (pronounced "Jinc-Sinc") resampling

Post by NicolasRobidoux »

Let me illustrate with 10x enlargements. Top is sigmoidized Ginseng. Bottom is sRGB Lanczos 3.
Image
Image
You will see the differences better if you download both images and flip between them in a viewer.
Given that both schemes are interpolatory, there is no question which one is better. The most obvious spots are the top of the helmets and the fenders.
P.S. See the red colour bleed at the top of the top left light helmet in the sigmoidized version, at the edge, just to the right of the red stripe. Not noticeable when using the "safe" contrast value (which is not shown).
Last edited by NicolasRobidoux on 2012-09-01T05:25:49-07:00, edited 5 times in total.
NicolasRobidoux
Posts: 1944
Joined: 2010-08-28T11:16:00-07:00
Authentication code: 8675308
Location: Montreal, Canada

Re: Sigmoidized Ginseng (pronounced "Jinc-Sinc") resampling

Post by NicolasRobidoux »

Scrutinizing the motocross image makes me think that, actually, sticking to the safer contrast value (or something between the safer value and the not so safe value) may be better.
But these examples certainly do not point to a gigantic improvement over sRGB Lanczos 3 in any case. Clearly, but by any means not stunningly, better.
Last edited by NicolasRobidoux on 2012-09-01T06:10:53-07:00, edited 1 time in total.
NicolasRobidoux
Posts: 1944
Joined: 2010-08-28T11:16:00-07:00
Authentication code: 8675308
Location: Montreal, Canada

Re: Sigmoidized Ginseng (pronounced "Jinc-Sinc") resampling

Post by NicolasRobidoux »

I am going to replace the scaled sigmoidal by a scaled hyperbolic sine in my private version of ImageMagick 7 and see what that does.
This is not an arbitrary choice: The logic of sigmoidization suggests that one wants exponential growth away from the midpoint, and I want this growth to start faster and I also do not want a hard limit (so that we can deal with negative transparency and the like without worrying about being on the wrong side of the "population" min and max). The odd part of the exponential does the trick.
NicolasRobidoux
Posts: 1944
Joined: 2010-08-28T11:16:00-07:00
Authentication code: 8675308
Location: Montreal, Canada

Re: Sigmoidized Ginseng (pronounced "Jinc-Sinc") resampling

Post by NicolasRobidoux »

What I mean is that I'll replace the scaled sigmoid function by the scaled arcsinh, and the inverse of the scaled sigmoid function by the scaled sinh (hyperbolic sine).
I'm hoping that this will "tighten" interfaces more uniformly across colour values than the current version does, and yet lead to less "colour bleed".
NicolasRobidoux
Posts: 1944
Joined: 2010-08-28T11:16:00-07:00
Authentication code: 8675308
Location: Montreal, Canada

Re: Sigmoidized Ginseng (pronounced "Jinc-Sinc") resampling

Post by NicolasRobidoux »

Dead end: Using the inverse hyperbolic sine for sigmoidization does not work well. Here is the modified enhance.c code for reference:

Code: Select all

  /*
    Sigmoidal with inflexion point moved to b and "slope constant" set to a.
  */
#if 0
#define Sigmoidal(a,b,x) ( 1.0/(1.0+exp((a)*((b)-(x)))) )
#else
#define Sigmoidal(a,b,x) ( \
  log( ((a)*((x)-(b))) + sqrt( ((a)*((x)-(b)))*((a)*((x)-(b))) + 1.0 ) ) )
#endif
  /*
    Scaled sigmoidal formula: (1/(1+exp(a*(b-x))) - 1/(1+exp(a*b)))
                              /
                              (1/(1+exp(a*(b-1))) - 1/(1+exp(a*b))).
    See http://osdir.com/ml/video.image-magick.devel/2005-04/msg00006.html and
    http://www.cs.dartmouth.edu/farid/downloads/tutorials/fip.pdf.
  */
#define ScaledSigmoidal(a,b,x) (                    \
  (Sigmoidal((a),(b),(x))-Sigmoidal((a),(b),0.0)) / \
  (Sigmoidal((a),(b),1.0)-Sigmoidal((a),(b),0.0)) )
#if 0
#define InverseScaledSigmoidal(a,b,x) (                                     \
  (b) - log( -1.0+1.0/((Sigmoidal((a),(b),1.0)-Sigmoidal((a),(b),0.0))*(x)+ \
  Sigmoidal((a),(b),0.0)) ) / (a) )
  /* 
    The limit of ScaledSigmoidal as a->0 is the identity, but a=0 gives a
    division by zero. This is fixed below by hardwiring the identity when a is
    small. This would appear to be safe because the series expansion of the
    sigmoidal function around x=b is 1/2-a*(b-x)/4+... so that s(1)-s(0) is
    about a/4.
  */
#else
#define InverseScaledSigmoidal(a,b,x) (                               \
  (b) + sinh( ((Sigmoidal((a),(b),1.0)-Sigmoidal((a),(b),0.0))*(x)+ \
  Sigmoidal((a),(b),0.0)) ) / (a) )
#endif
I left the code alone in the ImageMagick repo. It looks like it's what happens very near the gamut limits that matters. The "middle" is better left alone.
So, sigmoidization is better done... with the sigmoid function.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Sigmoidized Ginseng (pronounced "Jinc-Sinc") resampling

Post by fmw42 »

You may already know this, but the scaled tanh and arctanh produce results similar to the sigmoidal functions, if not identical, due to the similarity in the use of exponentials.
NicolasRobidoux
Posts: 1944
Joined: 2010-08-28T11:16:00-07:00
Authentication code: 8675308
Location: Montreal, Canada

Re: Sigmoidized Ginseng (pronounced "Jinc-Sinc") resampling

Post by NicolasRobidoux »

fmw42 wrote:You may already know this, but the scaled tanh and arctanh produce results similar to the sigmoidal functions, if not identical, due to the similarity in the use of exponentials.
Yes, I know. I wanted something slightly more different. But maybe I'll give tahn and arctanh a try and see if it makes a difference.
There is a collection of "common sigmoidal functions" here: http://en.wikipedia.org/wiki/File:Gjl-t%28x%29.svg
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Sigmoidized Ginseng (pronounced "Jinc-Sinc") resampling

Post by fmw42 »

NicolasRobidoux wrote: There is a collection of "common sigmoidal functions" here: http://en.wikipedia.org/wiki/File:Gjl-t%28x%29.svg

Thanks for the reference.
NicolasRobidoux
Posts: 1944
Joined: 2010-08-28T11:16:00-07:00
Authentication code: 8675308
Location: Montreal, Canada

Re: Sigmoidized Ginseng (pronounced "Jinc-Sinc") resampling

Post by NicolasRobidoux »

Real dirty back of the envelope says that the standard sigmoid function is probably pretty much as good as it gets.
And I think that I'll always stick to the "safer" values.

Quest over.
NicolasRobidoux
Posts: 1944
Joined: 2010-08-28T11:16:00-07:00
Authentication code: 8675308
Location: Montreal, Canada

Re: Sigmoidized Ginseng (pronounced "Jinc-Sinc") resampling

Post by NicolasRobidoux »

I'll give a try to f(x) = x/sqrt(1+x^2) and it's inverse g(x) = x/sqrt(1-x^2), for no other reason that these functions are cheap to compute. (Yes, I know IM uses LUTs to apply sigmoidal-contrast, at least now, even in HDRI mode. I don't only program for IM.)
Post Reply