HDRI tonemapping to [0,1]

Magick.NET is an object-oriented C# interface to ImageMagick. Use this forum to discuss, make suggestions about, or report bugs concerning Magick.NET
Post Reply
Alakanu
Posts: 3
Joined: 2016-04-24T10:28:25-07:00
Authentication code: 1151

HDRI tonemapping to [0,1]

Post by Alakanu » 2016-04-24T10:31:52-07:00

Hello, I am using magick.net HDRI 16 AnyCpu and I was struggling to find a magick.net built in way to convert my freshly loaded from .hdr file MagickImage into another MagickImage with colors in range of [0,1]. Is there any? I know that if i write back my image as filename.jpg it gets automatically tonemapped to 0-255 8bit depth rgb image so I hope it's just that I don't know where to look for.

[SOLUTION]
I was mistaken thinking I should upload a [0,1] Texture. The right techinque consists in rendering in high dynamic range to a FBO and then tonemap with a chosen techinique with another couple of vertex/fragment shaders.This is what helped me a lot. As a matter of fact, this is not related anymore to Magick.net, so if you want to delete it, go on.
Last edited by Alakanu on 2016-04-26T05:03:00-07:00, edited 1 time in total.

User avatar
magick
Site Admin
Posts: 11077
Joined: 2003-05-31T11:32:55-07:00

Re: HDRI tonemapping to [0,1]

Post by magick » 2016-04-24T15:36:46-07:00

ImageMagick support clamping with the -clamp option which calls the MagickCore method ClampImage(). Does Magick.NET support a Clamp() method? If not, hopefully it will get added for the next release.

Alakanu
Posts: 3
Joined: 2016-04-24T10:28:25-07:00
Authentication code: 1151

Re: HDRI tonemapping to [0,1]

Post by Alakanu » 2016-04-25T00:06:50-07:00

Hi, thanks for the answer. I am worried that clamping is not what I am looking for, since if it really just clamps values between 0 and quantum range that not a very good tonemapping and it will result in a very white image or a very black one (but please, correct me if I'm wrong).

snibgo
Posts: 12303
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: HDRI tonemapping to [0,1]

Post by snibgo » 2016-04-25T09:09:55-07:00

I don't understand what you want to do. Pixel values are stored in memory, and written to files, as values between zero and QuantumRange, where QuantumRange is 255 or 65535 or whatever. If you want them in the range 0.0 to 1.0, you can divide by QuantumRange, eg:

Code: Select all

convert in.tiff -evaluate Divide 65535 -define quantum:format=floating-point out.tiff
I don't know the magick.NET equivalent.
snibgo's IM pages: im.snibgo.com

Alakanu
Posts: 3
Joined: 2016-04-24T10:28:25-07:00
Authentication code: 1151

Re: HDRI tonemapping to [0,1]

Post by Alakanu » 2016-04-26T01:23:02-07:00

Hi, I want to load an opengl texture, and I read that opengl works with values normalized in [0,1] ( I am planning to use a rgb32f format for the texture). Normalization apart, I see you are suggesting that tonemapping in IM should be basically done converting the .hdr file in .tiff, am I supposing right?
I tried what you suggested, (hoping not to have missed anything), but I didn't achieve my goal. Basically there are channel values over Quantum.Max even after i convert in .tiff. My code is here:

Code: Select all

                MagickImage myhdr = new MagickImage(path);
                float maxR = 0, maxG= 0, maxB = 0, minR = 0, minG = 0, minB = 0;
                PixelCollection pixels = myhdr.GetPixels();
                for (int y = 0; y < myhdr.Height; y++)
                {
                    for (int x = 0; x < myhdr.Width; x++)
                    {
                        MagickColor p = pixels.GetPixel(x, y).ToColor();
                        if (maxR < p.R) maxR = p.R;
                        if (maxG < p.G) maxG = p.G;
                        if (maxB < p.B) maxB = p.B;
                        if (minR > p.R) minR = p.R;
                        if (minG > p.G) minG = p.G;
                        if (minB > p.B) minB = p.B;
                    }
                }
                Console.WriteLine(maxR + " " + maxG + " " + maxB + " " + minR + " " + minG + " " + minB);
                myhdr.Write(@"../../Cubemaps/try.tiff");
                MagickImage tf = new MagickImage(@"../../Cubemaps/try.tiff");
                tf.Evaluate(Channels.All, EvaluateOperator.Divide, Quantum.Max);
                pixels = tf.GetPixels();
                for (int y = 0; y < myhdr.Height; y++)
                {
                    for (int x = 0; x < myhdr.Width; x++)
                    {
                        MagickColor p = pixels.GetPixel(x, y).ToColor();
                        if (maxR < p.R) maxR = p.R;
                        if (maxG < p.G) maxG = p.G;
                        if (maxB < p.B) maxB = p.B;
                        if (minR > p.R) minR = p.R;
                        if (minG > p.G) minG = p.G;
                        if (minB > p.B) minB = p.B;
                    }
                }
                Console.WriteLine(maxR + " " + maxG + " " + maxB + " |" + minR + " " + minG + " " + minB);
And the output is:
1,055114E+07 1,3107E+07 5242800 | 0 0 0
1,055114E+07 1,3107E+07 5242800 | 0 0 0

So basically nothing changed.

EDIT: I also tried myhdr.Evaluate(Channels.All, EvaluateOperator.Divide, Quantum.Max) before that, but without results.

snibgo
Posts: 12303
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: HDRI tonemapping to [0,1]

Post by snibgo » 2016-04-26T07:30:59-07:00

You initialise minR etc to zero. Unless your pixels have negative values, minR etc will never be adjusted, and will always show zero.

You calculate min and max twice, with an evaluate between them. But you don't re-initialise minR, maxR etc. Why not?
snibgo's IM pages: im.snibgo.com

Post Reply