Color calibration in PTB

Hi everyone,


I'm new to this forum, so please excuse if I'm not posting things in the right way - my apologies!

I setting up a new experiment and I'm not sure about some technical details of color calibration in Psychtoolbox, so I would appreciate your input.

I'm interested in monetary choices, so the main setup is to present two options as text on the screen (DrawFormattedText), waiting for the response of the participant and show a new pair of option in the next trial.

Now I want to study pupil dilation in response to the decision process. This is heavily confounded with the luminance of the text stimuli I show (normally white text on black background), so I want to equalize the luminance of the text and the background. The background could be rgb [128 128 128] and I present text in color with the same luminance as the background. The text will still be readable by color contrast.


Two problems arise:

1) How to best pick colors that are iso-luminant to [128 128 128]? I used matlab's rgb2gray to calculate luminance for RGB values. For example, [144 144 0] gives a similar gray value as [128 128 128]. Is this the way to do or is there a more elegant solution?


2) How can I be sure that the luminance later on the screen is really equal? To account for this, I calibrated the screen with an "X rite MonacoEZcolor" device. This screen calibration ccreated an ICC profile. I load it to matlab with the function iccread, i.e.

prof = iccread('profile.icm');

is it correct to use

table = [prof.MatTRC.RedTRC ./ 65535 prof.MatTRC.GreenTRC ./ 65535 prof.MatTRC.BlueTRC ./ 65535];

and then

Screen('LoadNormalizedGammaTable', windowPtrOrScreenNumber, table); ?


I hope I am not too mistaken. I'm new to many technical details about color and I highly appreciate every comment!

Best,
Antonius




Some technical details:
- AMD FirePro V3900 (driver rev. 15.201.2401.0).
- Windows 7 64bit professional
- Matlab R2016b
- PTB-3 Version 3.0.12
HI Antonius,

See my comments below in bold.

Hi everyone,


I'm new to this forum, so please excuse if I'm not posting things in the right way - my apologies!

I setting up a new experiment and I'm not sure about some technical details of color calibration in Psychtoolbox, so I would appreciate your input.

I'm interested in monetary choices, so the main setup is to present two options as text on the screen (DrawFormattedText), waiting for the response of the participant and show a new pair of option in the next trial.

Now I want to study pupil dilation in response to the decision process. This is heavily confounded with the luminance of the text stimuli I show (normally white text on black background), so I want to equalize the luminance of the text and the background. The background could be rgb [128 128 128] and I present text in color with the same luminance as the background. The text will still be readable by color contrast.


Would you be able to use an auditory set of cues/instructions for these two options, as opposed to using text? That way you can eliminate the confound of the potentially different amounts of retinal stimulation on pupil dilation.



Two problems arise:

1) How to best pick colors that are iso-luminant to [128 128 128]? I used matlab's rgb2gray to calculate luminance for RGB values. For example, [144 144 0] gives a similar gray value as [128 128 128]. Is this the way to do or is there a more elegant solution?


2) How can I be sure that the luminance later on the screen is really equal? To account for this, I calibrated the screen with an "X rite MonacoEZcolor" device. This screen calibration ccreated an ICC profile. I load it to matlab with the function iccread, i.e.

Dealing with question 1 is tricky, as there are potentially millions of isoluminant combinations of R, G, and B values. If you accurately characterize the luminance function of your display (how luminance changes as a function of gray level), and it has good white point balance along the whole grayscale level (i.e. the chromaticity - which can be thought of as color independent of luminance - remains the same across all gradations between black and white), you could write a function that calculates the luminance of any given combination of R, G and B, and have it run through a loop and output all the combinations that are isoluminant. You could then test these combinations using HCFR (see below).

An easier solution, however, might be to write some code in matlab that allows you to do a luminance matching experiment, using method of adjustment. Here, you use the meter as the observer, and the procedure would go something like this:

The goal here is to find two colors that are isoluminant (one for the background, and one for the text).

1) Display a full screen image of the color you want to use for the background (pick a color at random if you like). We'll call this the reference patch.
2) Measure the luminance of this color, write it down
3) Display a full screen image of a different random color. We'll call this the test patch.
4) Now use three keys to finely adjust the R G B levels of this test patch, and with each adjustment, measure the luminance. Continue until you have found a test patch that reads the same luminance as the reference patch, but is a different color.

Note that the Monaco Optix XR is relatively slow, so you'll have to wait a couple seconds between each adjustment to see the change in luminance.

There are instructions on how to use the Monaco Optix XR (aka DTP-94) in my guide here. I'd recommend reading the first part of the introduction, as it will introduce you to some basic background concepts about color science. Then you can skip ahead to the "setting up the software" section. You won't need IrfanView, but you will need HCFR and ArgyllCMS (the latter for the drivers). The last part of that section explains how to use HCFR in free measure mode. Also read the sentences that occur just before the "WinDAS WPB steps", and look at the screenshots for examples of the HCFR output.

https://hardforum.com/threads/windas-white-point-balance-guide-for-sony-trinitron-crts.1830788/

Finally, note that there is variation in how humans perceive luminance (technically, they're spectral sensitivity functions are all slightly different). Thus, just because two colors are isoluminant measured by one observer (or instrument), doesn't mean that those same two colors will be isoluminant for another. Depending on how sensitive pupil dilation is to changes in luminance (vs. how sensitive it is to the cognitive influences you're hoping to measure), this may or may not be a problem.

Also, displays are rarely uniform - so the same color may measure slightly different luminance depending upon where on the screen you're measuring. Again, this may or may not be a problem depending on how much variation your experiment can tolerate.

cheers,
Marwan


prof = iccread('profile.icm');

is it correct to use

table = [prof.MatTRC.RedTRC ./ 65535 prof.MatTRC.GreenTRC ./ 65535 prof.MatTRC.BlueTRC ./ 65535];

and then

Screen('LoadNormalizedGammaTable', windowPtrOrScreenNumber, table); ?

I hope I am not too mistaken. I'm new to many technical details about color and I highly appreciate every comment!

Best,
Antonius


Some technical details:
- AMD FirePro V3900 (driver rev. 15.201.2401.0).
- Windows 7 64bit professional
- Matlab R2016b
- PTB-3 Version 3.0.12


Hi Antonius,

It's been a while since I've interacted with this stuff, but to the best of my knowledge:

As far as I understand, for most purposes, an icm profile is only useful when you want to implement gamma correction. If you're using color aware applications that can use 3D lookup tables to transform color spaces (which involves, for example, remapping the display primaries) or want to preserve colors across different devices, like cameras, scanners, printers, and displays, then icc/icm profiles become more powerful, but this is not relevant to your, nor most people's situation).

So in your case, when you calibrated your display and created that profile, what it did was measure the luminance function of the display, for each color channel, and then calculated a 1D lookup table for each color channel that, when implemented, will achieve a target luminance function. In your case, the target function was probably one associated with BT.1886 or sRGB (so roughly, a gamma of between 2.2 and 2.4). Or perhaps your target function was a linear gamma.

When you implement this lookup table, it brings each of the red, green, and blue channels to that target function. (incidentally, note that if each of the channels is adjusted so that each channel has the same luminance function, then the chromaticity should be stable across all values of gray, from black to white).

So that's fine and dandy, but you still have to figure out which RGB combinations are isoluminant, right? Simply implementing 1D LUT to achieve a desired gamma function isn't going to magically solve that. So I'm not sure why you think this is the same as finding isoluminant colors empirically through the trial and error method. Perhaps you assumed that after gamma correction, 50% red would be the same luminance as 50% green and 50% blue. If so, this is incorrect.

In my first response, I outlined how, if you had access to the luminance function of each channel, you could write some code that extracts all equiluminant combinations of R, G, and B, but then suggested the easier empirical method, which has nothing to do with profiling or calibrating or using ICCs. Now if you want to take the first approach, rather than the empirical approach, you certainly can, but keep in mind you'll need to go through a few steps:

1) figure out what the actual target function of the display is. I've never used or interacted directly with icm files, so I'm not sure if the TRC (tone reproduction curve?) represents the target luminance function itself (desired "gamma"), or whether it represents the 1DLUTs which, when applied to your display, will gamma correct your display. My guess is the latter.

2) scale the values for each channel. I'm guessing that the TRC values are normalized between 0 and 1 for each channel (or 0 and 65536). But you'll need to figure out the peak luminance for each of the three channels so you can find the actual luminance function for each channel, and not the normalized luminance functions.

3) write code that extracts all possible equiluminant combinations

4) ultimately test some of these combinations, with your instrument in free measure mode. Assuming the TRC values represent the 1DLUTs, they were likely created by measuring only a few out of the 256 values for each channel, and then interpolating, so there's no guarantee that all of the values are correct. You'll need to actually verify that whatever combinations you have chosen are indeed equiluminant, or close to equiluminant. And to test this, you'll need to use your colorimeter in free measure mode to do so.

Finally, unless your graphics card and software environment allow for 10 bit LUT precision (that is, for each channel, allows you to choose from a palette of 1024 values to construct your table which consists of 256 values), AND your display is either a CRT or accepts 10 bit digital input , any gamma correction will inevitably result in "crushing" levels together, resulting in less than 256 unique values for each channel, and this will limit the number of possible color combinations to explore. The RAMDACs on Nvidia cards are 10 bit, so if you have a CRT you can do moderate amounts of gamma correction without losing unique values. I think the AMD firepro allows 10 bit color for digital, so if you have a display that accepts 10 bit input, you might be ok. I'm not sure whether the RAMDAC on the firepro is 8 bit or 10 bit, but I seem to remember learning that some AMD cards only have an 8 bit RAMDAC, so if you have a CRT, Nvidia might be better.

So to me, it makes way more sense not to worry about profiling/calibrating/gamma correction, and just go ahead and use the empirical trial and error method.

Another idea is to maybe explore texture defined stimuli. So, for example, your text and background could be filled with black and white diagonal lines, where the text has diagonal lines going one way, and the background has diagonal lines going the other way. That way, the average luminance of the stimuli (averaged across text and background) should be the same across all font sizes and string lengths.

Marwan

Hi Marwan,
Thanks for your reply! It took me a bit to read all resources, but it was very, very helpful.

I understand that auditory stimulation could be an elegant way to avoid many problems, but it is not possible for other reasons.

Finding isoluminant colours "empirical" as you described it, makes a lot of sense. However, I'm a bit confused how this is different from the calibration process when an ICC profile is generated. I thought of it as the exactly the same process, but probably I'm mistaken there. Could you help me to understand what the differences are? Thank you!

I'm aware that the colour luminance perception could be slightly different between participants. I'm expecting the targeted effect to be larger, so I hope I we are good with randomising colours between participants.

Again, thank you for your help!

Best,
Antonius


On 16 Dec 2016, at 19:07, Marwan Daar marwan.daar@... [PSYCHTOOLBOX] <PSYCHTOOLBOX@yahoogroups.com> wrote:

HI Antonius,

See my comments below in bold.

Hi everyone,


I'm new to this forum, so please excuse if I'm not posting things in the right way - my apologies!

I setting up a new experiment and I'm not sure about some technical details of color calibration in Psychtoolbox, so I would appreciate your input.

I'm interested in monetary choices, so the main setup is to present two options as text on the screen (DrawFormattedText), waiting for the response of the participant and show a new pair of option in the next trial.

Now I want to study pupil dilation in response to the decision process. This is heavily confounded with the luminance of the text stimuli I show (normally white text on black background), so I want to equalize the luminance of the text and the background. The background could be rgb [128 128 128] and I present text in color with the same luminance as the background. The text will still be readable by color contrast.


Would you be able to use an auditory set of cues/instructions for these two options, as opposed to using text? That way you can eliminate the confound of the potentially different amounts of retinal stimulation on pupil dilation.



Two problems arise:

1) How to best pick colors that are iso-luminant to [128 128 128]? I used matlab's rgb2gray to calculate luminance for RGB values. For example, [144 144 0] gives a similar gray value as [128 128 128]. Is this the way to do or is there a more elegant solution?


2) How can I be sure that the luminance later on the screen is really equal? To account for this, I calibrated the screen with an "X rite MonacoEZcolor" device. This screen calibration ccreated an ICC profile. I load it to matlab with the function iccread, i.e.

Dealing with question 1 is tricky, as there are potentially millions of isoluminant combinations of R, G, and B values. If you accurately characterize the luminance function of your display (how luminance changes as a function of gray level), and it has good white point balance along the whole grayscale level (i.e. the chromaticity - which can be thought of as color independent of luminance - remains the same across all gradations between black and white), you could write a function that calculates the luminance of any given combination of R, G and B, and have it run through a loop and output all the combinations that are isoluminant. You could then test these combinations using HCFR (see below).

An easier solution, however, might be to write some code in matlab that allows you to do a luminance matching experiment, using method of adjustment. Here, you use the meter as the observer, and the procedure would go something like this:

The goal here is to find two colors that are isoluminant (one for the background, and one for the text).

1) Display a full screen image of the color you want to use for the background (pick a color at random if you like). We'll call this the reference patch.
2) Measure the luminance of this color, write it down
3) Display a full screen image of a different random color. We'll call this the test patch.
4) Now use three keys to finely adjust the R G B levels of this test patch, and with each adjustment, measure the luminance. Continue until you have found a test patch that reads the same luminance as the reference patch, but is a different color.

Note that the Monaco Optix XR is relatively slow, so you'll have to wait a couple seconds between each adjustment to see the change in luminance.

There are instructions on how to use the Monaco Optix XR (aka DTP-94) in my guide here. I'd recommend reading the first part of the introduction, as it will introduce you to some basic background concepts about color science. Then you can skip ahead to the "setting up the software" section. You won't need IrfanView, but you will need HCFR and ArgyllCMS (the latter for the drivers). The last part of that section explains how to use HCFR in free measure mode. Also read the sentences that occur just before the "WinDAS WPB steps", and look at the screenshots for examples of the HCFR output.

https://hardforum.com/threads/ windas-white-point-balance- guide-for-sony-trinitron-crts. 1830788/

Finally, note that there is variation in how humans perceive luminance (technically, they're spectral sensitivity functions are all slightly different). Thus, just because two colors are isoluminant measured by one observer (or instrument), doesn't mean that those same two colors will be isoluminant for another. Depending on how sensitive pupil dilation is to changes in luminance (vs. how sensitive it is to the cognitive influences you're hoping to measure), this may or may not be a problem.

Also, displays are rarely uniform - so the same color may measure slightly different luminance depending upon where on the screen you're measuring. Again, this may or may not be a problem depending on how much variation your experiment can tolerate.

cheers,
Marwan


prof = iccread('profile.icm');

is it correct to use

table = [prof.MatTRC.RedTRC ./ 65535 prof.MatTRC.GreenTRC ./ 65535 prof.MatTRC.BlueTRC ./ 65535];

and then

Screen(' LoadNormalizedGammaTable', windowPtrOrScreenNumber, table); ?

I hope I am not too mistaken. I'm new to many technical details about color and I highly appreciate every comment!

Best,
Antonius


Some technical details:
- AMD FirePro V3900 (driver rev. 15.201.2401.0).
- Windows 7 64bit professional
- Matlab R2016b
- PTB-3 Version 3.0.12