Color profile from Tiff file

'ere y’go:

wavelength (nm),r,g,b
400,0.0896,0.0670,0.3044
405,0.0806,0.0676,0.3484
410,0.0715,0.0710,0.3920
415,0.0625,0.0744,0.4360
420,0.0535,0.0789,0.4795
425,0.0467,0.0879,0.5293
430,0.0393,0.0981,0.5779
435,0.0371,0.1105,0.6259
440,0.0354,0.1235,0.6711
445,0.0342,0.1484,0.7214
450,0.0326,0.1727,0.7700
455,0.0303,0.2032,0.7796
460,0.0292,0.2326,0.7881
465,0.0269,0.2778,0.7864
470,0.0246,0.3236,0.7841
475,0.0269,0.3648,0.7497
480,0.0292,0.4055,0.7152
485,0.0258,0.4519,0.6649
490,0.0235,0.5016,0.6135
495,0.0258,0.5756,0.5479
500,0.0292,0.6508,0.4880
505,0.0326,0.7214,0.4055
510,0.0359,0.7937,0.3304
515,0.0399,0.8593,0.2699
520,0.0439,0.9226,0.2123
525,0.0439,0.9604,0.1727
530,0.0439,0.9966,0.1337
535,0.0416,0.9972,0.1049
540,0.0405,0.9960,0.0766
545,0.0331,0.9678,0.0591
550,0.0263,0.9407,0.0422
555,0.0444,0.8977,0.0286
560,0.0636,0.8553,0.0150
565,0.1371,0.7915,0.0133
570,0.2128,0.7276,0.0133
575,0.3671,0.6615,0.0134
580,0.4999,0.5960,0.0134
585,0.6208,0.5349,0.0135
590,0.7434,0.4694,0.0135
595,0.8130,0.3976,0.0136
600,0.8779,0.3247,0.0136
605,0.8909,0.2722,0.0137
610,0.9000,0.2207,0.0137
615,0.8983,0.1863,0.0138
620,0.8955,0.1529,0.0139
625,0.8949,0.1388,0.0122
630,0.8949,0.1247,0.0125
635,0.8796,0.1117,0.0128
640,0.8632,0.0992,0.0167
645,0.8373,0.0947,0.0184
650,0.8113,0.0913,0.0201
655,0.7892,0.0947,0.0213
660,0.7683,0.0987,0.0235
665,0.7542,0.1066,0.0235
670,0.7406,0.1184,0.0235
675,0.7237,0.1320,0.0258
680,0.7056,0.1461,0.0292
685,0.6886,0.1648,0.0303
690,0.6728,0.1840,0.0309
695,0.6570,0.2026,0.0297
700,0.6406,0.2213,0.0280
2 Likes

Not on my microscope, but the same software can be used on motorized ones. I did it manually. There is also a vertical axis multishot mode to improve depth of field. I haven’t tested neither.

I agree, I suspect the camera to process the image internally before sending it to the computer. I have a contact at Zeiss, I can ask him about the SSF data you found.

Here the L* values comparison between the experimental and the theoretical gray patches. As you can see, the input picture is not at all normalized. I am testing how using a TRC curve improves the color profile.

Have a good day.

Unless you can get raw sensor data in the CZI somehow, it doesn’t really matter. If you can get raw sensor data, or at least “camera native color space”, aka “demosaiced without any colorspace conversions” then the SSFs are EXTREMELY useful.

Either a TRC issue, or possibly the glare you were concerned about and/or maybe contrast loss from stray light entering the optics directly?

The changes I made to my Python script that I linked are a bit rough, but at least should convert your CZIs to linear high-bit-depth TIFFs. (I might rework things to do DNG output at some point since that would allow me to specify a white point instead of just scaling everything by 16.). I don’t know what the best method for assembling a full chart would be. It does appear that roundtripping a properly tagged linear 16-bit TIFF through GIMP doesn’t mangle anything obvious color wise.

Interestingly, if your focus is specifically on color rendering, it looks like the AxioCams are designed to attach to a microscope (not, as I originally thought, integrated with it), so depending on your exact application it might be easier to just attach an APS-C camera to the microscope instead of the AxioCams, unless there’s some sort of additional microscope integration (automatic focus adjustment?) I’m missing here.

1 Like

Interesting ! I will contact Zeiss and let you know.

Using a linear TRC from origin 10.239/0 to end 93.200/100 before DcamProf, I was able to strongly improve the profile to deltaE avg 2.26, max 5.19 :grinning:. If I could be below deltaE=2, it would be perfect.

I can confirm that I can unscrew the camera from the microscope, but a standard APS-C camera can not be attached as is. There is a specific adapter on the microscope.

Interesting - is that with the converted CZI, or the high-bit-depth (16 bit) linear TIF?

You may want to reduce the saturation setting so that you don’t get gamut clipping, and potentially have a wider gamut representable.

To see if it’s an optics issue or a camera issue, try taking a shot with the camera removed from the microscope and capped.

Looks like the Axiocam has a C-mount thread, plus the microscope already has a C-mount adapter.

You can get C-mount adapters for the camera side such as Amazon.com - although based on Microscope C-Mount Adapters and Camera Chip Sensors and Microscope C-Mounts and Image Sensors , the microscope-to-C adapter already there probably will have too small of an image circle to fully cover an APS-C sensor.

1 Like

Hi @Entropy512,
It was with the 8-bit gamma encoded pictures, converted to 16 bits linear with RT before Gimp assembling. I’ll try without saturation.
What do you mean by capping the camera? I will have black only, won’t I? Moreover, there is no lens in front of the camera and I will have blur only without light control.
The C-mount is good to know I didn’t realize that.
Have a good day.

That’s the idea - to see if the camera has a black level offset that isn’t being properly corrected. Ideally, a dark frame (camera with cap on it, short exposure) will have black at 0 in an image that has already had processing applied like this. Raw sensor data often has a black level offset to help with noise reduction algorithms due to the statistical properties of sensor noise. For example, in most Sony cameras, black lands at 512 and not 0.

Although I would definitely start first with trying a 16-bit linear TIF derived directly from the CZI file from the script that I posted. Or maybe both - sanity-check the CZI-derived files with a black frame. You’ll need Python and a few modules which I need to document a bit better. I’ll update the documentation later today.

Yep, my Nikon Z 6 requires subtracting 1008 from every measured value, or the rendition has a horrid purple cast. It’s a fundamental characteristic of digital sensors, you can’t get a true zero out of 'em…

Some sensors do have a true zero for black, but in general those are older ones, as a result of my previous comments about noise reduction. Some of the noise sources that are internal to the sensor can basically cause negative below-black values. Older sensors would mirror these values or clip them which caused problems for noise reduction. Hence everything recent having a black level offset.

But we’re kinda getting into the weeds. TBH since the CZI data seems to be demosaiced AND colorspace-converted, black level SHOULD already be subtracted. So it may be an optical artifact, or just an issue stemming from using the 8-bit nonlinear files. Taking a CZI in a configuration that is “as black as possible” helps narrow down where the offset might be.

1 Like

Hi everybody,
Thank you for all your input. I didn’t have time to do the black picture test. I was preparing a spring school for scientists, which is taking place this week. That’s a lot of interesting presentations on complex topics :writing_hand:, taking place near the sea in Corsica, France :sunglasses:. I’ll keep you in touch next week.
Best,
Guillaume

2 Likes

Hi @ggbutcher,
I tested your program under Linux and there is no error. However, the encoded values are not modified. The output file has the same behavior than the input file. Do you have an idea how to make it work ? Moreover, how can I compile it under Windows ?
Regards

Edit:
I downloaded littlecms2 and tried using MSYS2/UCRT64, according to this page

gcc -c lcms2.h -o lcms2.o
ar rcs liblcms2.a lcms2.o
gcc -static trcswap.cpp -I. -L. -llcms2 -o trcswap.exe

But I got

C:/msys64/ucrt64/bin/../lib/gcc/x86_64-w64-mingw32/13.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: .\liblcms2.a: error adding symbols: archive has no index; run ranlib to add one
collect2.exe: error: ld returned 1 exit status

Post the input and output .icc files here, I’ll take a look…

Okay, you have MSYS2, so it’s not too hard. LittleCMS2 can be installed from the MSYS2 package library, so you don’t have to compile it:

$ pacman -S mingw-w64-ucrt-x86_64-lcms2
$ gcc -o trcswap trcswap.cpp -llcms2

Thanks, I was able to compile the program under Windows.

Here are the input and output profiles of your program. These are not the final ICC profiles, as I still need to make some corrections. When using either one of them in RawTherapee as an input profile on a 2.2 gamma encoded TIFF, the result is identical, namely too bright, as expected for a 1.0 gamma.
input_g10.icc (212.5 KB)
output_g22.icc (212.6 KB)

I just ran exiftool against the profiles, and the program did just what it was designed to do: replace the TRCs of the input profile with a gamma 2.2 curve. Of note, the input profile (from dcamprof, I assume) does a LUT color transform and contains no TRC tags (assumes image is linear, so no tone curve), so trcswap just added them.

I grabbed the first .tif you posted in the thread (hope it provides the right input conditions), opened it in rawproc, and assigned in turn each of the two profiles you just posted, and confirmed the behavior in the display transform. For giggles, I then assigned a regular sRGB profile, and the image display-transformed normally.

I can’t confirm it right now, but it appears LittleCMS isn’t using the TRCs inserted in a LUT-based profile. So then, if that’s the case, the display transform would assume the input image is encoded linear (which it’s not), so it would leave tone alone in transforming to linear XYZ. Then, in the output side of the transform, it’d be taking a gamma 2.2-encoded image and converting it from linear XYZ to gamma-encoded display. That’s what’s making the images look too light…

Interesting! I’m trying to say it with my own words: trcswap updated the metadata but Little CMS is ignoring it when the profile is using LUT. Correct?

I was able to process another dataset shot under the stereo microscope without saturation. I obtained good results: deltaE avg 1.89, max 4.38 :grinning:.

I am currently using an intermediate image file in RT:

  • gamma image → gamma profile → TRC curve → linear profile → linear image,
  • linear image → LUT linear profile → gamma profile → gamma image.

Is there a way to apply LUT in RT without an intermediate file ?

  • gamma image → gamma profile → TRC curve → LUT linear profile → gamma profile → gamma image.

Have a good day.

Appears so. I need to dig a bit on this…

Hi all,
I have an enigma for you: why are these two profiles different?

gamutvision

You will find in this ZIP all the involved files. I obtained the test1 profile a while ago and I am unable to repeat it with the test2. You will find the original TIFF files, the normalized linear ones, the RT pp3 files, the script I am using, and the ICC profiles.

I may have made some changes in the linear TIFF file, but the Lab values I checked were similar. The pp3 files are almost identical, as shown with diff.txt. I suspect some kind of illuminant shift.

Any clues ?

Hello Guillaume

I was away yesterday, I see your message, intriguing.

I looked at all your files and compared them one by one, either for pp3 with “kDiff3”, or for TIF with Photoshop (layer - differences - aplatir - niveaux).

  • Test1.tif and Test2.tif are strictly identical.
  • test1-norm-lin.tif and test2-norm-lin.tif are differents with a delta in Lab values about 0 to 2 (loaded with “no profile”).
    image
    The difference is in the pp3 files, which is significantly greater than that reported by “diff.txt”.

If you compare with kDiff3 (or another utility) the 2 pp3 - test1.tif.pp3 and test2.tiff.pp3, are with some significant differences, and “test1-norm-lin-tif” and “test2-norm-lin.tif” are identicals. Which I will list briefly.
[Exposure] - compensation, ClampOOG, Curve
[White Balance] - enabled or not…and settings
[Color Appearance] - Algorithm
[Directional Pyramid Denoising] - MethodMed
[Crop] X, Y, W, H (small differences)
[Resize] - Scale
[Input profile] : cameraICC or RTv4_Medium.icc, Will, OutputProfile : Rtv4_sRGB & Rtv4_Medium_Linear_g1.0
[Wavelet] - mixMethod, CHromaMethod
[Raw] Darkframe and Flatfielfile (as you mentionned)
[Metadata] Exifkeys, Refoutput

There is a high probability that the discrepancies stem from these differences in the 2 pp3
But maybe it’s something else

Have a nice day, cordially

Jacques

1 Like

Hi @jdc,

Thank you for your message. Actually, Test1.tif.pp3 was modified later without overwriting test1-norm-lin.tif. So the information there is not relevant. You confirmed what I suspected: test1-norm-lin.tif and test2-norm-lin.tif are different.

I found the explanation: I extracted both embedded output profiles with Argyll extracticc. Despite having the same name, they were different. Both were using AdobeRGB primaries, both were linear, but the illuminant was D65 for test1-norm-lin.tif and D50 for test2-norm-lin.tif. I also realized that the RT neutral profile applies a white balance which has a strong impact on the dcamprof profile.

Have a nice evening.

1 Like

Hi @Entropy512,
Following your request, here is the capped camera CZI image. After using your Python script, the black image has RGB values arount 5/255.

As I said earlier, I overcame this by normalizing the output with a tone response curve. L*a*b* lightness values of the ColorChecker gray patches are presented below, before normalization (in blue) and after (in red).

Regards