Using HSV colour space to compute luminance of an RGB value

Started by
17 comments, last by jollyjeffers 18 years, 5 months ago
Quote:Original post by jollyjeffers
Quote:Original post by python_regious
Did you try the simple magnetude one? Would be interesting to just see what that looks like...

Yeah, seems I forgot that one [headshake]



I was expecting it to be about the same as the max() one, but it seems to look a little better/different to me [smile]

Cheers,
Jack


The difference is enormous - you are avoiding saturation nearly everywhere, and it looks like a different scene (actually: a readable scene [smile]). It is far better.

The thing I don't understand is that I was expecting this kind of results with the L version - it should be softer than the magnitude version. L = (max(r,g,b) + min(r,g,b))/2 is smaller than the magnitude of the vector (r,g,b). This is easily seen in your small luminance maps in fact (magnitude ones are far brighter than the L ones). This is where my undertsanding is choked: it seems that the source HDR frame is not identical among the screenshots. Thus, I don't know how I can compare the results.

Or am I dunb? (please, do not answer this question [smile])
Advertisement
If you want a proper luminance measurement from an RGB color (with a relatively simple formula), you need to convert it to YCrCb color space. The Y component is a very good approximation of the luminance. You might need to apply a gama adjustment after the calculation to get it to look right.
"Walk not the trodden path, for it has borne it's burden." -John, Flying Monk
Quote:Original post by Emmanuel Deloget
The difference is enormous - you are avoiding saturation nearly everywhere, and it looks like a different scene (actually: a readable scene [smile]). It is far better.

Hmm, on double checking things.. there is a pretty good reason why it's better - I changed a load of stuff!

I'm going through fixing/tweaking/correcting loads of small things, so the sample isn't necessarily in the same state for very long. My mistake for forgetting about said changes before posting the 5th screenshot.

Quote:it seems that the source HDR frame is not identical among the screenshots. Thus, I don't know how I can compare the results.

The 4 pictures I originally posted are definitely equal - even down to rotation and camera properties. You can, if you wanted, run a "difference" operator against those 4 and get valid results

One of things I changed (you can see it in the sliders on the RHS if you look closely) is the default configuration of the pipeline. In particular theres a higher bright-pass threshold and higher SD for the gaussian.

If I change the parameters to be the same as the original four:


Luminance computed using the magnitude operator

Not quite so amazing now is it [headshake]

The problem I've noticed now is that I can tweak the parameters (as seen) to reduce the saturation on the bright parts of the image; but getting the dark parts to show up properly is a real pain.

I was hoping (expecting?) that when there is *no* HDR data in the source frame the "normal" 0.0 - 1.0 scale data is very dark:


No HDR Data, Same exposure as above images.


No HDR Data, 4x higher exposure.

Cheers,
Jack

<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]</small>

Quote:Original post by Extrarius
If you want a proper luminance measurement from an RGB color (with a relatively simple formula), you need to convert it to YCrCb color space. The Y component is a very good approximation of the luminance. You might need to apply a gama adjustment after the calculation to get it to look right.

Thanks for the suggestion. I just dropped in some default values (from the wiki page) and tested it - the only noticeable difference was that it brought out some of the dark colours better. Still very over-saturated on the bright areas though. If I get time I might look into computing Kr and Kb coefficients properly and doing the gamma correction.

Cheers,
Jack

<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]</small>

why can't you use an exponential drop off?

given r,g,b do

r' = 1-e^-c*r
g' = 1-e^-c*g
b' = 1-e^-c*b

with an appropriate chosen constant c. this formula is highly sensitive to c. I think this is reasonably standard for hdr stuff isn't it? I'm surprised no one has mentioned it. there are many more advanced techniques of gamma correction but this is common and produces reasonable results. certinally better then a vector magnitude. more advanced approach's take a look at the scene in it's entirity and make decisions based on that. obviously not real time, but I'm by far an expert in the field of tone mapping.

to convert to grey scale just take the weighed average after this transformation.

like

//edit
grey = sum(1/3*r' + 1/3*b' + 1/3*g');

if this is to much chop off the range again

grey' = 1 - e^-b*grey

where b is another constant



or perhaps a combonation of brightening and dimming

grey' = t*grey + (1-t)*sqrt(grey)

one possible t value could obviously be
t = grey

I'm likeing this one, if you try it show me.

for t = grey youd have

grey' = grey^2 + (1-grey)*sqrt(grey)

this would have the effect of dampening bright and stuff and boosting dim stuff best of both worlds.

perhaps a cubic interpolant would work too.

Tim

[Edited by - timw on November 14, 2005 7:33:58 AM]
Quote:Original post by jollyjeffers
[...]Thanks for the suggestion. I just dropped in some default values (from the wiki page) and tested it - the only noticeable difference was that it brought out some of the dark colours better. Still very over-saturated on the bright areas though. If I get time I might look into computing Kr and Kb coefficients properly and doing the gamma correction.[...]
Did you make sure to do gamma adjustment on each end of the calculation? I'm not sure its possible to do it efficiently in shaders, but if so it should make some significant difference:
http://www.poynton.com/GammaFAQ.html
http://scanline.ca/ycbcr/

-Extrarius
Thanks for all the ideas everyone - v. useful [smile]

@timw - I tried implementing your idea, but I exploded the ps_2_0 limits (>65 arithmetic instructions) [sad]

Given that I need to get this thing tidied up and shipped off today I don't think I'll be able to spend the time optimizing it in order to get it working. I'll keep a note of it should I get time later on though!

Quote:Did you make sure to do gamma adjustment on each end of the calculation?

Nope, I just plugged in a couple of the values from that wiki article. Apparently for computer displays and the like:

Kb = 0.0722
Kr = 0.2126

I shall look into the gamma correction, but for the same reasons as posted above I might simply end up running out of time [headshake]

I'll post back here if I get anything else worth showing...

Cheers,
Jack

<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]</small>

jollyjeffers: Essentially, gamma adjustment is just a way to adjust for the way different devices respond to, record, or display colors. The adjustment is usually a power function at it's core, but the exact formula depends on the standard and exactness desired.

To simplify to the specific case of 'typical, properly-adjusted CRT monitors' and ignore standards to simplify the math:

Gamma = number between 2.35 and 2.55 (just selecting

R' = R ^ (1 / Gamma)
G' = G ^ (1 / Gamma)
B' = B ^ (1 / Gamma)

//Convert (R', G', B') -> (Y', Cb, Cr)
//Gamma doesn't affect Cb or Cr, only Y'
Y = Y' ^ Gamma
"Walk not the trodden path, for it has borne it's burden." -John, Flying Monk
Quote:Original post by Extrarius
jollyjeffers: Essentially, gamma adjustment is just a way to adjust for the way different devices respond to, record, or display colors. The adjustment is usually a power function at it's core, but the exact formula depends on the standard and exactness desired.

To simplify to the specific case of 'typical, properly-adjusted CRT monitors' and ignore standards to simplify the math:

Gamma = number between 2.35 and 2.55 (just selecting

R' = R ^ (1 / Gamma)
G' = G ^ (1 / Gamma)
B' = B ^ (1 / Gamma)

//Convert (R', G', B') -> (Y', Cb, Cr)
//Gamma doesn't affect Cb or Cr, only Y'
Y = Y' ^ Gamma

Thanks for that [smile] Sounds pretty close to what I was thinking of...

Anyway, I'll look into experimenting with it when I get the time.

I fixed most of the problems I was talking about in the latter half of this thread due to realising I made a real dumbass mistake (forgetting to set the luminance to GxxRxxF instead of the original RxxF [headshake]). It looks pretty sweet now.

Cheers,
Jack

<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]</small>

This topic is closed to new replies.

Advertisement