need explicitly linear and nonlinear GRAY colorspaces

Questions and postings pertaining to the development of ImageMagick, feature enhancements, and ImageMagick internals. ImageMagick source code and algorithms are discussed here. Usage questions which are too arcane for the normal user list should also be posted here.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: need explicitly linear and nonlinear GRAY colorspaces

Post by fmw42 »

-grayscale rec709luminance was specially created to produce a linear equivalent of rec709luma so that there was some way to generate linear grayscale images. Same for -grayscale rec601luminance vs rec601luma. These are not really listed colorspaces but just argument names.
Dabrosny
Posts: 111
Joined: 2013-10-02T10:49:39-07:00
Authentication code: 6789
Location: New York, US

Re: need explicitly linear and nonlinear GRAY colorspaces

Post by Dabrosny »

-grayscale rec709luminance was specially created to produce a linear equivalent of rec709luma so that there was some way to generate linear grayscale images. Same for -grayscale rec601luminance vs rec601luma. These are not really listed colorspaces but just argument names.
The problem with the -grayscale options is that (according to the documentation) their result is independent of the current colorspace. So you have to make sure you understand what colorspace you need to start in, in order for the particular -grayscale to produce the expected output.

For example if you are in RGB (linear) colorspace and you apply -grayscale Rec601Luma, I don't think you will will end up with correct Rec601 Luma values (linear combination of *nonlinear* RGB). But if, instead of using -grayscale, you simply issue a -colorspace Rec601Luma command, this makes much more sense because (I presume) you will end up with correct Rec601 Luma values regardless of which colorspace you start out in.

I think we are relying too much on these specialized -grayscale operator options when 99% of the time we should just be able to specify a target -colorspace and IM should know a good default way to transform to it from the current colorspace. If the colorspaces are adequately identified, there is normally only one exactly-correct way to get from one colorspace to another (otherwise we would need to choose myriad options when transforming from one icc profile to another), and there may be other ways that are computationally less-expensive approximations to the exact transformation.

This is one reason we need a LinearGray colorspace, which should be interpreted as Luminance in the sense of the linear Y in the CIE XYZ colorspace, because this is the only linear Luminance that is used in the sRGB standard, ICC profiles, etc. For example the sRGB standard specifies the exact transformation from sRGB to this linear luminance so there is no doubt about what it should be, and in fact I've verified that the -grayscale Rec709Luminance operation (applied when the current colorspace is sRGB) performs this transformation numerically correctly today -- except that it doesn't label and treat the resulting colorspace as linear, so some further operations end up being incorrect.

In other words, we should simply be able to do
-colorspace LinearGray
and the result should be the linear luminance (identified as such for further transformations and operations and perhaps file output when applicable), which, if the current colorspace is sRGB, should be calculated as specified in the sRGB standard. The end user should not necessarily have to know which of four or more options will give the correct LinearGray result for sRGB (or for another colorspace).

-Dabrosny

(P.S. - The four options seem to me to be even more problematic when setting -intensity since this setting will continue to be in effect for various operations that you may perform on images that are in different colorspaces, for some of which a given -intensity setting may make very little sense. But maybe I'm misunderstanding how this works.)
-Dabrosny [Using IM7.0.6 or higher, Q16 HDRI x64 native executable, command line, often invoked from cygwin bash/sh (as of Aug. 2017)]
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: need explicitly linear and nonlinear GRAY colorspaces

Post by snibgo »

Dabrosny wrote:The problem with the -grayscale options is that (according to the documentation) their result is independent of the current colorspace. So you have to make sure you understand what colorspace you need to start in, in order for the particular -grayscale to produce the expected output.
I would say the results from -grayscale are DEPENDANT on the current colorspace. The transformations are very simple. For example, the following commands create different g*.png images:

Code: Select all

%I%convert hald:8 h8.png

%I%convert h8.png -grayscale Rec601Luma g1.png
%I%convert h8.png -colorspace RGB -grayscale Rec601Luma g2.png
%I%convert h8.png -colorspace Lab -grayscale Rec601Luma g3.png
Contrast this with "-colorspace", which does take existimg colorspace into accout, producing results which are independant of the colorspace. Thus, results from these are identical (within rounding error):

Code: Select all

%I%convert h8.png -colorspace Rec601Luma g1.png
%I%convert h8.png -colorspace RGB -colorspace Rec601Luma g2.png
%I%convert h8.png -colorspace Lab -colorspace Rec601Luma g3.png
This behaviour of "-grayscale" reinforces my preference that it should not modify the internal colorspace flag.
snibgo's IM pages: im.snibgo.com
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: need explicitly linear and nonlinear GRAY colorspaces

Post by snibgo »

It occurs to me that I may be using the word dependant/independant in a different sense from the documentation. "-grayscale" is indeed independant in the sense that a certain colour pixel value will translate to a fixed gray pixel value, whatever the original colourspace was. In contract, "-colourspace XX" will translate a certain colour pixel value to different gray pixels value, depending on the original pixel values.
snibgo's IM pages: im.snibgo.com
Dabrosny
Posts: 111
Joined: 2013-10-02T10:49:39-07:00
Authentication code: 6789
Location: New York, US

Re: need explicitly linear and nonlinear GRAY colorspaces

Post by Dabrosny »

I misspoke -- what I should have said is that the operation performed by -grayscale is independent of the initial colorspace, so that the result does depend on the initial colorspace as you point out.

To see why this is confusing, just look at your example:

Code: Select all

%I%convert h8.png -grayscale Rec601Luma g1.png
%I%convert h8.png -colorspace RGB -grayscale Rec601Luma g2.png
%I%convert h8.png -colorspace Lab -grayscale Rec601Luma g3.png
I presume that the first command does indeed produce the Rec601 Luma corresponding to the original sRGB values. (Or at least an approximation unless it first transforms sRGB to linear RGB, then calculates Rec601 R'G'B' (nonlinear), which are only approximately equal to sRGB values, and then combines those to get Rec601 Luma.)

Then the 2nd and third command simply do not produce a Rec601 Luma as their result, so I'm not sure why anyone would use them, except by mistake.

What -grayscale Rec601Luma actually does is perform certain fixed operations, which, if they were applied to an input encoded in just the right colorspace, would indeed produce Rec601 Luma.

If someone really wants to produce a Rec601 Luma (frankly, I'm not sure why, unless they're constructing a Y'CbCr by hand), they can instead do -colorspace Rec601Luma, which will do so for *any* input.

Similarly, I would like to be able to do

Code: Select all

      -colorspace Luminance
(or CieY or LinearY or RelativeLuminance or LinearGrayscale or what ever we want to call it) in order to produce the standard linear luminance from *any* initial colorspace. And to ensure that any further operations and transformations will be able to tell that the image is not gamma-encoded. Right now, in general (in order to work on an initial image in any colorspace) I would have to issue this very ugly command (so non-obvious that after reading the documentation I still only came up with it after some trial-and-error):

Code: Select all

      -colorspace sRGB -grayscale Rec709Luminance -set Colorspace RGB
which works very well, and doesn't fool further processing (such as a -colorspace sRGB coming later after some other operations) into treating the image as already gamma-encoded, but of course I'm sweeping the single-channelness of the result under the rug (not so bad in IM6 where it uses 3 channels anyway).
-Dabrosny [Using IM7.0.6 or higher, Q16 HDRI x64 native executable, command line, often invoked from cygwin bash/sh (as of Aug. 2017)]
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: need explicitly linear and nonlinear GRAY colorspaces

Post by fmw42 »

-colorspace sRGB -grayscale Rec709Luminance -set Colorspace RGB
I am not sure about the -colorspace sRGB. That may be needed if -grayscale works on whatever colorspace is presented without convert to sRGB first. I believe that was by design according to what Anthony requested. But I may be wrong. Many colorspace management operations in IM rely upon the user's control with -colorspace or -set colorspace and do the try to over automate, since that may lead to something undesired by the user.

The -set colorspace RGB should no longer be needed once 6.8.7.1 is released or if you use the beta. The gamma issue has been fixed.
Dabrosny
Posts: 111
Joined: 2013-10-02T10:49:39-07:00
Authentication code: 6789
Location: New York, US

-colorspace b4 -grayscale Re:need explicitly lin.&nonlin GR

Post by Dabrosny »

The -grayscale operator does not convert the input to a particular colorspace before performing its operation. See the last couple of posts in this topic. For example the -grayscale Rec709Luminance only in fact produces a Luminance (i.e. linear) if the initial colorspace of its input is sRGB (or similar).

Code: Select all

convert "$1" -grayscale Rec709Luminance  ...
If the input is RGB (linear) then it will apply an sRGB-->RGB transformation to it anyway, which in effect puts it into an indecipherable colorspace whose gamma runs in the opposite direction from all other nonlinear colorspaces.

That's why, if I want my script or command to work on a variety of input files that might be in different colorspaces, I have to pre-convert to the colorspace that will produce the expected result when acted on by a given -grayscale type. That's why I have:

Code: Select all

convert "$1" -colorspace sRGB -grayscale Rec709Luminance  ...
-Dabrosny [Using IM7.0.6 or higher, Q16 HDRI x64 native executable, command line, often invoked from cygwin bash/sh (as of Aug. 2017)]
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: need explicitly linear and nonlinear GRAY colorspaces

Post by fmw42 »

Yes, that is what I was trying to say. -grayscale work on whatever colorspace is presented (by design). Thus to be safe you do need to add -colorspace sRGB before -grayscale. All I was trying to say was that -set colorspace RGB following -grayscale rec709luminance should not be needed once the bug is fixed as per IM 6.8.7.1.
Dabrosny
Posts: 111
Joined: 2013-10-02T10:49:39-07:00
Authentication code: 6789
Location: New York, US

Re: need explicitly linear and nonlinear GRAY colorspaces

Post by Dabrosny »

The -set colorspace RGB should no longer be needed once 6.8.7.1 is released... The gamma issue has been fixed.
I don't see that setting the gamma property in itself solves the problem within IM processing.

All I want to do is read in an sRGB photo, perform various operations on its linear luminance values and then save this luminance information in some form within an 8-bit (preferably single-channel) png file so that I can use it later.

I want the resulting PNG file to be nonlinear (via the usual sRGB gamma compression), just like most png files would be.

I think this is a pretty straightforward use case, so I'm not sure why it can't be done easily today.

(Why not linear coding? in most cases it isn't a good idea to store a visual image in linear encoding in low-resolution integers (especially 8-bit), since the loss of dynamic range and especially visible tonal resolution at the dark end could be extreme. Even saving in 16bit linear can lose an awful lot if you've been processing the image internally linearly but using floats as in im6hdri. Secondarily, some software will assume sRGB gamma compression regardless of whether there is a single channel or three, and not necessarily handle gamma=1.0 correctly, and of course some other formats may be presumed to be sRGB because they have no way to indicate otherwise.)

CIE Luminance--Y in the XYZ (linear tristimulus) colorspace--is pretty much the most basic building block in terms of which sRGB, most other colorspaces, and ICC profiles themselves are defined, so why would it be difficult to produce?

The only way I could find to do this transformation was to use "-grayscale Rec709Luminance"* and even then, the conversion back to sRGB gamma-compression for output to the png fails because -colorspace sRGB does nothing since it treats Gray as already being nonlinear like sRGB:

Code: Select all

convert mysrgb.png -grayscale Rec709Luminance ....other ops.... -colorspace sRGB mygray.png
Even with the new patch (setting gamma=1 from -grayscale Rec709Luminance) I don't think this will do what I want, unless -colorspace sRGB looks at the image->gamma==1 and realizes that it does indeed need to transform the data values from linear to sRGB.

Can somebody tell me what effect image-> gamma has on internal processing within IM -- does anything different actually happen other than attempting to store the gamma value in the file when saving to a file format that supports this?

(P.S. -- The "-grayscale Rec601Luminance" operator in IM apparently applies the Rec601 nonlinear Luma coefficients when calculating linear Luminance, which is not what those coefficients are intended to be used for. The only reason applying the Rec709 Luma coefficients to linear RGB works is that they are numerically identical to the original linear CIE RGB->Y coefficients. Rec 709 arbitrarily chose to apply these pre-existing CIE linear coefficients to their nonlinear R'G'B' to get their Luma encoding for transmission and storage, which they were free to do because you can define a transmission and storage encoding any way you please, so long as you don't lose too much info and there's a way to decode it. You can't define Luminance (or even gamma-compressed luminance) just any way you please -- luminance is based on psychophysical measurements of how real humans perceive the brightness of different colors of light; linear CIE Y is the one and only Luminance that sRGB and ICC profiles themselves and just about everything else uses.)
Last edited by Dabrosny on 2013-10-07T15:22:39-07:00, edited 1 time in total.
-Dabrosny [Using IM7.0.6 or higher, Q16 HDRI x64 native executable, command line, often invoked from cygwin bash/sh (as of Aug. 2017)]
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: need explicitly linear and nonlinear GRAY colorspaces

Post by fmw42 »

Here are the results of processing the rose: image with the fix for gamma in IM 6.8.7.1

Image

nonlinear grayscale:
imbh convert rose: -colorspace sRGB -grayscale rec709luma rose_luma.png
Image

linear grayscale (darker):
imbh convert rose: -colorspace sRGB -grayscale rec709luminance rose_luminance.png
Image


Do these clarify what you are asking and do they achieve what you desire?
Dabrosny
Posts: 111
Joined: 2013-10-02T10:49:39-07:00
Authentication code: 6789
Location: New York, US

Re: need explicitly linear and nonlinear GRAY colorspaces

Post by Dabrosny »

It does look like it produces a gamma=1 png, but it already did, before the fix, right?

What I'm more interested in is this:

imbh convert rose: -colorspace sRGB -grayscale rec709luminance -colorspace sRGB rose_luminance.sRGB.png
(edited typo above)

I want to see if that gives us a correct sRGB-gamma-compressed png (whether it's one channel or three -- either way).

I.e. does it do the same as this does (or the same as this did in the previous version anyway, which was correct give or take whether it was 3 identical chans instead of 1):

imbh convert rose: -colorspace sRGB -grayscale rec709luminance -set colorspace RGB -colorspace sRGB rose_luminance.sRGB.png
(edited typo)
What I don't like is having to do -set colorspace RGB every time to get it to work.

Another interesting thing is how awful the rec709luma one looks (which is the same as the default -colorspace gray i believe!) -- I'm pretty sure I know why it's so bad, but that's that's a nonlinear gray issue; i'm trying to focus on the linear issue first. (The rec601luma should be at least slightly closer to being correct, but it may very well still not look quite right.) But for *linear* we should stick to the rec709.
-Dabrosny [Using IM7.0.6 or higher, Q16 HDRI x64 native executable, command line, often invoked from cygwin bash/sh (as of Aug. 2017)]
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: need explicitly linear and nonlinear GRAY colorspaces

Post by fmw42 »

It does look like it produces a gamma=1 png, but it already did, before the fix, right?
No, that was the bug. The IM gamma was 0.4545, but the PNG: meta data had gamma=1. IM processing sees the IM gamma as 0.4545 and that was why your stuff was not working, I suspect. Now with the fix, both gamma values are 1.

At one point since its inception -grayscale rec709luminance was doing it right. But at some point it got messed up.
imbh convert rose: -colorspace sRGB -grayscale rec709luminance -colorspace sRGB rose_luminance.sRGB.png
This should convert it back to non-linear sRGB values. Perhaps you need

imbh convert rose: -colorspace sRGB -grayscale rec709luminance -set colorspace sRGB rose_luminance.sRGB.png

That would keep the values as linear but think it is non-linear.

See if any of these are what you want (though I am surprised that the first is the same as the second, as I would have thought it would be the same as the third):


imbh convert rose: -colorspace sRGB -grayscale rec709luminance -colorspace sRGB rose_luminance.sRGB1.png
Image

imbh convert rose: -colorspace sRGB -grayscale rec709luminance -set colorspace sRGB rose_luminance.sRGB2.png
Image


To properly convert to non-linear grayscale, it appears you really need to add -set colorspace RGB to tell IM that it is linear before the -colorspace change:
imbh convert rose: -colorspace sRGB -grayscale rec709luminance -set colorspace RGB -colorspace sRGB rose_luminance.sRGB3.png
Image

Another interesting thing is how awful the rec709luma one looks (which is the same as the default -colorspace gray i believe!)
No, it should not. -colorspace gray is the same as -colorspace rec709luma and -grayscale rec709luma
What I don't like is having to do -set colorspace RGB every time to get it to work.
With IM 6.8.7.1 you should not. If trying to convert it back to sRGB, it seems that you still will as in my rose_luminance.sRGB3.png example above.
Dabrosny
Posts: 111
Joined: 2013-10-02T10:49:39-07:00
Authentication code: 6789
Location: New York, US

Re: need explicitly linear and nonlinear GRAY colorspaces

Post by Dabrosny »

Another interesting thing is how awful the rec709luma one looks (which is the same as the default -colorspace gray i believe!)
No, it should not. -colorspace gray is the same as -colorspace rec709luma and -grayscale rec709luma
Sorry, what should not what?
-Dabrosny [Using IM7.0.6 or higher, Q16 HDRI x64 native executable, command line, often invoked from cygwin bash/sh (as of Aug. 2017)]
Dabrosny
Posts: 111
Joined: 2013-10-02T10:49:39-07:00
Authentication code: 6789
Location: New York, US

Re: need explicitly linear and nonlinear GRAY colorspaces

Post by Dabrosny »

imbh convert rose: -colorspace sRGB -grayscale rec709luminance rose_luminance.png
Also, when my 6.8.7-0(hdri) identify -verbose reads in your png from above, it seems to recognize gAMA=1 but nonetheless shows the image->gamma as 0.454545:

Code: Select all

    png:gAMA: gamma=1
  Gamma: 0.454545
Is this a part of the bug that's fixed in the beta?
-Dabrosny [Using IM7.0.6 or higher, Q16 HDRI x64 native executable, command line, often invoked from cygwin bash/sh (as of Aug. 2017)]
User avatar
glennrp
Posts: 1147
Joined: 2006-04-01T08:16:32-07:00
Location: Maryland 39.26.30N 76.16.01W

Re: need explicitly linear and nonlinear GRAY colorspaces

Post by glennrp »

Yes, the PNG reader now sets image->gamma=1.0 when it reads a gAMA chunk with gamma==1.0.
Post Reply