Page 1 of 1

Mapping (neg./pos.) float values to a LUT on an absolute scale

Posted: 2019-07-02T01:26:40-07:00
by romangrothausmann
Hi!


How can I apply a LUT (of e.g. 200 colors) to an image containing negative and positive float values (input.tif, scientific image, similar to a distance-map) on an absolute scale? I.e. I would like the first color of the LUT to be mapped to -0.57368 and the last color of the LUT to 0.673743.
Is that possible with IM?
I've been trying some variations of the command below but was so far defeated by the fact that u.p is in [0,1] and I do not know how to map that back to the original pixel values.

Code: Select all

convert -size 10x100 gradient:#f00-#f0f -size 10x100 gradient:#f0f-#00f -append LUT.png
convert input.tif LUT.png  -fx "v.p{0,u.p*(2^`convert input.tif -format '%z' info:`-1) / ( 0.673743--0.57368 ) / 200 }" -transparent black output.png
One step further I would like to map the LUT such that first color of the LUT to be mapped to -0.57368 and the last color of the LUT to 0.673743 and a specific color of the LUT to 0. I.e. for a LUT ranging from red over magenta to blue, red should be mapped to -0.57368, blue to 0.673743 and magenta (#f0f) to 0.

Any help or hints would be very appreciated.

Roman

Re: Mapping (neg./pos.) float values to a LUT on an absolute scale

Posted: 2019-07-02T04:37:40-07:00
by snibgo
romangrothausmann wrote:I would like the first color of the LUT to be mapped to -0.57368 and the last color of the LUT to 0.673743.
Is that possible with IM?
I suppose you mean -0.57368 and 0.673743 of QuantumRange, and these are input colours that you want to apply a LUT ("-clut" or "-hald-clut") to.

First, transform the image to 0.0 to 1.0 of QuantumRange.

You can do this by subtracting (-0.57368) then dividing by (0.673743-(-0.57368)). You must use a version of IM built with HDRI.
romangrothausmann wrote:One step further I would like to map the LUT such that first color of the LUT to be mapped to -0.57368 and the last color of the LUT to 0.673743 and a specific color of the LUT to 0. I.e. for a LUT ranging from red over magenta to blue, red should be mapped to -0.57368, blue to 0.673743 and magenta (#f0f) to 0.
I don't understand. A LUT has an input range which is from zero to QuantumRange. The output, the colours in the pixels of the clut image, can be whatever colours you want.

Re: Mapping (neg./pos.) float values to a LUT on an absolute scale

Posted: 2019-07-02T07:27:38-07:00
by romangrothausmann
Many thanks snibgo for taking a look and for your response.
I suppose you mean -0.57368 and 0.673743 of QuantumRange
I'm not sure about that. The input.tif contains 32-bit float values, in this case the are all within [-1,1] but in general could be outside that range. Isn't QuantumRange limited to the values from 0 to 1?
You can do this by subtracting (-0.57368) then dividing by (0.673743-(-0.57368)). You must use a version of IM built with HDRI.
OK, I'll give that a try.
A LUT has an input range which is from zero to QuantumRange. The output, the colours in the pixels of the clut image, can be whatever colours you want.
Yes, but I would like a specific color for a specific value within the range, e.g. that 0 is mapped to #f0f, basically two differently stretched LUTs, e.g. gradient:#f00-#f0f for the negative values and gradient:#f0f-#00f for the positive values while 0 is not necessarily in the middle of the whole range.

Re: Mapping (neg./pos.) float values to a LUT on an absolute scale

Posted: 2019-07-02T08:27:05-07:00
by snibgo
For Q16 IM, QuantumRange is 65535. So values are typically between 0 and 65535 inclusive. With IM HDRI, values are floating point and can be outside this range.

What does "magick input.tif -verbose info:" say your range is? What are the minimum and maximum values?

Perhaps your values are literally between -0.57368 and 0.673743, or -1.0 to +1.0. That's fine. With "-clut", input values to that operation should be between 0 and QuantumRange. Just do a subtraction and multiplication to get them in that range.
romangrothausmann wrote:Yes, but I would like a specific color for a specific value within the range, e.g. that 0 is mapped to #f0f, basically two differently stretched LUTs, e.g. gradient:#f00-#f0f for the negative values and gradient:#f0f-#00f for the positive values while 0 is not necessarily in the middle of the whole range.
Okay, so you need two different cluts. Scale the negative values to 0 to QuantumRange and apply one clut. Then scale the positive values to 0 to QuantumRange and apply the other clut. Composite the "positive" result over the "negative" result using a mask that is black where the input was negative.

Perhaps it would help if you link to your input.tif.

Re: Mapping (neg./pos.) float values to a LUT on an absolute scale

Posted: 2019-07-03T03:06:57-07:00
by romangrothausmann
Many thanks snibgo for all your feedback. I got it solved with:

Code: Select all

convert-im6.q16hdri input.tif  -fx " ( u - -0.57368) / (0.673743 - -0.57368) "  LUT.png -clut output.png
Your hint to use IM-HDRI was what I had been missing when trying that before. Oddly,

Code: Select all

convert-im6.q16hdri input.tif -evaluate add 0.57368 -verbose info: | egrep 'min|max'
had no effect, i.e. did not move the values above 0.

Concerning the mapping of a specific middle value to the LUT, I had the idea to create the LUT with gradients whose sizes are proportional to the range below and above zero, which seems to do the trick.

Thanks again for all your help.

Re: Mapping (neg./pos.) float values to a LUT on an absolute scale

Posted: 2019-07-03T05:32:09-07:00
by snibgo
romangrothausmann wrote:Oddly, ... -evaluate add 0.57368 ... had no effect, i.e. did not move the values above 0.
Your "-fx" works. "-fx" calculates u as the proportion of 0 to QuantumRange. So this tells us that your values are actually -0.57368 to 0.673743 multiplied by QuantumRange.

So, you can "-evaluate add 57.368%". This is a percentage of QuantumRange.

Re: Mapping (neg./pos.) float values to a LUT on an absolute scale

Posted: 2019-07-03T06:33:53-07:00
by romangrothausmann
I see, thanks for that clarification, something new to learn every day;-)