Loading RAW images in Magick++ with linear colourspace

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?".
Post Reply
creasechris
Posts: 5
Joined: 2016-03-18T08:07:07-07:00
Authentication code: 1151

Loading RAW images in Magick++ with linear colourspace

Post by creasechris »

Hi guys,

Question: I'm starting to do some (computational, mathematical) research on images, and I need to be sure that the colour space is loaded from my NEF files "linearly". This is causing me some difficulty, so any help would be hugely appreciated.

Here is the output of convert -version:

Code: Select all

Version: ImageMagick 6.8.9-9 Q16 x86_64 2015-08-06 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2014 ImageMagick Studio LLC
Features: DPC Modules OpenMP
Delegates: bzlib djvu fftw fontconfig freetype jbig jng jpeg lcms lqr ltdl lzma openexr pangocairo png tiff wmf x xml zlib
At the moment I'm rather naively using C++ commands that look like:

Code: Select all

image.read( filename );
image.write(thisx*3+3,thisy*3+3,3,3,"I",ShortPixel,array);
I've read on these forums that it is read by default as linear in the dcraw delegate (link: https://imagemagick.org/discourse-serve ... 183#p35981 ), but strangely, my delegates.xml file doesn't mention dcraw at all. I know it is using dcraw, since it threw up these errors relating to dcraw, and only worked after I installed dcraw:

Code: Select all

sh: 1: dcraw: not found
Magick: "dcraw" -c -w "all_nef/00001.NEF" > "/tmp/gmO8GYNt".
Caught exception: Magick: Delegate failed ("dcraw" -c -w "%i" > "%o") reported by magick/delegate.c:908 (InvokeDelegate)
This seems to imply that it is using "dcraw" -c -w as the delegate, but I'm confused as to why this does not appear in delegates.xml. Also, contrary to the above linked post, these do not appear to be linear settings - linear would be "-4" in dcraw notation.

What I'm aiming for is as follows:
  • When using intensities, like "I" in my C++ code above, we have as little interpolation as possible - I simply want raw, linear values;
  • When using colours, like "R" instead of "I" above, we simply use only the red pixels - I don't need any interpolation at all.
Is this the default behaviour in Magick++? Is it possible to specify the correct dcraw parameters?

Thanks very much!

Chris


EDIT: I'm considering running a pass of dcraw -h -4 to TIFF, and then using ImageMagick to separate the colour channels, and finally loading only the processed images in Magick++ rather than doing it "all at once". Would this be a more elegant solution?
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Loading RAW images in Magick++ with linear colourspace

Post by snibgo »

creasechris wrote:I've read on these forums that it is read by default as linear ...
Well, things have changed in the last 8 years.

You can create your own entry in delegates.xml with whatever dcraw options you want.
creasechris wrote:... we simply use only the red pixels - I don't need any interpolation at all
So you don't want to de-Bayer (demosaic) the image? No problem, dcraw can do that. See also my "Demosaicing" page.

EDIT:
Would this be a more elegant solution?
Yes, that's how I would do it.
snibgo's IM pages: im.snibgo.com
creasechris
Posts: 5
Joined: 2016-03-18T08:07:07-07:00
Authentication code: 1151

Re: Loading RAW images in Magick++ with linear colourspace

Post by creasechris »

Great, thanks a ton! I think that's all I need :)
creasechris
Posts: 5
Joined: 2016-03-18T08:07:07-07:00
Authentication code: 1151

Re: Loading RAW images in Magick++ with linear colourspace

Post by creasechris »

snibgo wrote:
creasechris wrote:I've read on these forums that it is read by default as linear ...
Well, things have changed in the last 8 years.

You can create your own entry in delegates.xml with whatever dcraw options you want.
creasechris wrote:... we simply use only the red pixels - I don't need any interpolation at all
So you don't want to de-Bayer (demosaic) the image? No problem, dcraw can do that. See also my "Demosaicing" page.

EDIT:
Would this be a more elegant solution?
Yes, that's how I would do it.
Hi again, I'm having a few unexpected difficulties with this processing.

Essentially I need as close as possible to linear intensities in each of red, green, blue, but also overall intensity (so getting linear numbers back from the Magick++ code above, with settings "R","G","B","I").

Am I thinking at all along the right lines with a pass of dcraw, with the following settings:

Code: Select all

dcraw -d -w -o 0 -4 -v -h -T "$f"
(for linear overall intensities, "I" in ImageMagick) and

Code: Select all

dcraw -d -r 1 1 1 1 -o 0 -4 -v -h -T "$f"
(for linear R, G, B individually)

...then use the resulting TIFFs with ImageMagick to read "I" (from the first quarter-size TIFF) and RGB (from the second quarter-size TIFF)?

Thanks a lot! :)
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Loading RAW images in Magick++ with linear colourspace

Post by snibgo »

That looks good, with a couple of qualifications.

1. I'm not sure exactly what you want.

2. You have "-d" without "-D", but I'm not sure what that does. I think it combines the values from each group of four sensor pixels (each of which records only one of red, green or blue), multiplies each of the four colour values, averages the two green values, and puts the results into the three channels of one pixel.

Multiplying the three colour values is for "colour balance", to correct for (a) the relative transmissions of the colour filters over the sensor and (b) the colour of the light source in the photographed scene. Correction (a) is constant for a given camera. Correction (b) will vary between photographs, and attempts to mimic human vision, and is somewhat subjective. For correction (b), cameras assume the brightest part of the scene has a neutral white balance. This may not be true, eg the photo includes a stage spotlight with a red gel over it.

When using a camera as a measuring instrument, a scientific tool, to measure how much light of the three colours is reflected or emitted by an object, you probably don't want correction (b).
snibgo's IM pages: im.snibgo.com
creasechris
Posts: 5
Joined: 2016-03-18T08:07:07-07:00
Authentication code: 1151

Re: Loading RAW images in Magick++ with linear colourspace

Post by creasechris »

snibgo wrote:That looks good, with a couple of qualifications.

1. I'm not sure exactly what you want.

2. You have "-d" without "-D", but I'm not sure what that does. I think it combines the values from each group of four sensor pixels (each of which records only one of red, green or blue), multiplies each of the four colour values, averages the two green values, and puts the results into the three channels of one pixel.

Multiplying the three colour values is for "colour balance", to correct for (a) the relative transmissions of the colour filters over the sensor and (b) the colour of the light source in the photographed scene. Correction (a) is constant for a given camera. Correction (b) will vary between photographs, and attempts to mimic human vision, and is somewhat subjective. For correction (b), cameras assume the brightest part of the scene has a neutral white balance. This may not be true, eg the photo includes a stage spotlight with a red gel over it.

When using a camera as a measuring instrument, a scientific tool, to measure how much light of the three colours is reflected or emitted by an object, you probably don't want correction (b).
Thanks very much for your reply. Essentially what I'm after is: with the setting "I", to obtain a RAW file that mimics a black and white camera, simply recording the linear intensity of light hitting each pixel. With the setting "R", "G" or "B", it's as if the black and white camera has this colour filter in front of it.

For the precise details of why I want this: I'm doing mathematical research. I need to extract high-contrast 3x3 patches, normalise them onto a 7-dim sphere (so multiplying by constant factors makes no difference), then do some computational topology. I already have this working for a monochrome dataset, which has linear intensities (like in my setting "I" above - originally this was done at Stanford), but I want to find the same patterns in each colour component of RAW images. Hence, I'm using dcraw and Magick++ to sample these patches.

I'm not sure I quite understand what you mean by "multiplies each of the four colour values". If you mean they get multiplied by the same constant in some way, this is not an issue, as I normalise anyway. However the colour correction may have an impact on the "I" result. Would you suggest -D rather than -d?

Thanks again,

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

Re: Loading RAW images in Magick++ with linear colourspace

Post by snibgo »

creasechris wrote:I'm not sure I quite understand what you mean by "multiplies each of the four colour values".
If you supply "-r", such as "-r 1 1 1 1", the values from the RGBG sensors are multiplied by those values. Exiftool can give you the multipliers that are stored in the file's metadata, in RBGG order, eg

Code: Select all

WB RB Levels : 1.93359375 1.39453125 1 1
If you don't care about the ratio of values between the channels because you will normalise them anyway, then ignore my ramblings about the multipliers.

Yes, they are relevant to the Intensity result. Perhaps you can calibrate your camera with whatever light source you use. Take a photo of a Gray Card, or anything that you know to have a neutral colour. Then choose your multipliers such that the pixels in the image of the gray card has equal values in all channels.

For example, on a scale of 0 to 100, the graycard pixels might have RGB values (60,70,80). 70/60=1.1667; 70/80=0.875. So the RGBG values to dcraw will be "1.1667 1 0.875 1". This might clip the red channel (because some values may already be close to 100%), so you might want to divide these by 1.1667, so the maximum factor becomes 1.0.
snibgo's IM pages: im.snibgo.com
creasechris
Posts: 5
Joined: 2016-03-18T08:07:07-07:00
Authentication code: 1151

Re: Loading RAW images in Magick++ with linear colourspace

Post by creasechris »

snibgo wrote:
creasechris wrote:I'm not sure I quite understand what you mean by "multiplies each of the four colour values".
If you supply "-r", such as "-r 1 1 1 1", the values from the RGBG sensors are multiplied by those values. Exiftool can give you the multipliers that are stored in the file's metadata, in RBGG order, eg

Code: Select all

WB RB Levels : 1.93359375 1.39453125 1 1
If you don't care about the ratio of values between the channels because you will normalise them anyway, then ignore my ramblings about the multipliers.

Yes, they are relevant to the Intensity result. Perhaps you can calibrate your camera with whatever light source you use. Take a photo of a Gray Card, or anything that you know to have a neutral colour. Then choose your multipliers such that the pixels in the image of the gray card has equal values in all channels.

For example, on a scale of 0 to 100, the graycard pixels might have RGB values (60,70,80). 70/60=1.1667; 70/80=0.875. So the RGBG values to dcraw will be "1.1667 1 0.875 1". This might clip the red channel (because some values may already be close to 100%), so you might want to divide these by 1.1667, so the maximum factor becomes 1.0.
Okay, fantastic. So -d and -D are equivalent for the "R", "G", "B" cases, but not for "I". :) Brill!

I'm actually using the RAISE dataset for now but will move on to taking my own pictures in a week or so, so thanks for the tip on that too!
Post Reply