Log in

View Full Version : Understanding YUV, Luma, Luminance


Kuukunen
2nd January 2011, 03:34
A guy wanted help with making a script figure out most of the frame is white. That's when I noticed that Avisynth's Grayscale is stupid: in YUV mode it just sets chromas to 128, in essence, just selecting the luma channel. This can be problematic, since full luma does not mean white. White is the brightest colour on computer screens, and should be the only one to have full brightness in grayscale. I figured I never thought deeply about these things either, so I made some tests.

Note: I will use "YUV" as a shorthand to mean YCbCr here, since most people here seem to do it without a second thought. I'm using Rec. 601, because that's what (I assume) color_yuv in blankclip works in and as far as I know, most videos people here run into are in Rec. 601. Also, everything is in PC range. (So if the white spot in the middle of the last frame in video is a lot bigger than in the pictures, blame your player. :P) Thos things are a separate topic and I'll mostly ignore them here.

So I made a video that sweeps through all YUV values. I also added grayscale vs. luma comparison. "Grayscale" is done by first converting to RGB, THEN using Grayscale() and converting back.

Here's the video:
http://kuukunen.net/misc/yuv.mkv

Here are some frames from the video:

http://kuukunen.net/misc/yuv0.png

http://kuukunen.net/misc/yuv125.png

http://kuukunen.net/misc/yuv255.png

Here's what I used to render it:

global res=8
function vfun(clip c, int y, int u, int v) {
c = c.overlay(blankclip(1,res,res,"YV12",color_yuv=y*$10000+u*$100+v),u,v)
v = v + res
v<$100?vfun(c,y,u,v):c
}
function ufun(clip c, int y, int u) {
c = vfun(c,y,u,0)
u = u + res
u<$100?ufun(c,y,u):c
}
function subs(clip c, int y) {
c.subtitle("Luma: " + string(y),100,120)
}
c=blankclip(64,256,256,"YV12")
subclip=c.animate(0,64,"subs", 0,260)
subclip=subclip.subtitle("YUV", 10,10)
subclip=subclip.subtitle("Grayscale", 10,235)
subclip=subclip.subtitle("Luma", 200,10)
yuv=c.animate(0,64,"ufun",0,0,255,0)
grayyuv=yuv.grayscale()
grayrgb=yuv.converttorgb(matrix="PC.601").grayscale().converttoyv12(matrix="PC.601")
stackvertical(stackhorizontal(yuv,grayyuv),stackhorizontal(grayrgb,subclip))

Yes yes, Avisynth is not really the best way for making a video like that, (Especially using only internal filters. :P) but meh, with it I had the best chances at getting it right. If you want a less blocky version, adjust the variable res. For me 4 ran out of memory and was slow as hell to render anyway. Also, having the blocks there makes it easier to see the steepness of the gradient and flat areas. (Because human eyes are too stupid for that on their own.)

Anyway, the main conclusion here is:

Luma channel can be very bad estimation for brightness. Just look at the green corner in the full luma picture for example.

In theory, there's no need for luma channel to actually match luminance, (luma != luminance, by the way) but it's beneficial for video encoding. Not to mention the Rec. 601 uses the same method for determining luma as the NTSC colourspace which was made with analog stuff in mind. Including, I assume, the possibility of using only the luma as grayscale tv picture. Meaning, it's meant to match human perception of brightness as well as possible.

Although, that was optimized for the displays back in the 50s, and that's why we now have Rec. 709 with different formulas to match current displays better.

But the catch is, by default the grayscale function is actually using precisely the same method as the luma channel. (And the matrix can be even specified) So what gives?

This is all because YUV is a very bad colourspace match for RGB. Look at how much the extreme magenta edge changes especially in the later frames. Not much! Scared yet? If not, how about this: according to the Rec. 601 conversions, the YUV 255,255,255 translates into RGB 433,121,480. That's Almost TWICE the maximum of 255, and they will simply get clamped, causing wasted colourspace. (Since displays etc work in RGB, it has to be converted at some point.)

In fact, earlier I made a simple program that converted all possible YUV values into RGB and checked the results. It turns out, all possible YUV values only give you 25% of RGB space. Most of the YUV values are outside RGB colourspace and can't be presented on displays that only understand RGB. This is why YUV causes banding much more than RGB.

If you look at the video frame-by-frame, you will see that in the "Grayscale" there is a triangular area that starts small, then grows until halfway, then shrinks again. That is the part of YUV that translates into RGB without clamping. In theory the luma channel should correspond to the actual luminance, but because of this clamping, using luma channel as grayscale doesn't work too well.

I talked about some of these things in IRC and Manao mentioned some of the colours at the extreme ends might be invalid anyway. Or in fact since the video is practically never produced in YUV anyway, there shouldn't be those problematic YUV values.

But on the other hand, by the time you're grayscaling the video, it is very likely it's been processed in some way. For example, if you or someone before you adjust the colours to add brightness or contrast or whatever, you might end up with having some of the values that won't turn into RGB without clamping, thus causing the luma not to work as actual luminance.

********

So it turns out once again that colour is pretty complex. I don't claim to be any kind of expert on it. In fact, the main reason I wrote this thing is to sum up my findings for myself. I probably made mistakes and misunderstood stuff, so feel free to correct me. I'm sorry if this is just old stuff to people, but if someone else finds it useful too. Good.

Here's a helpful read explaining concepts of luma/luminance/brighntess etc most people totally misunderstand and mix up, most of which I didn't even touch here:
http://www.poynton.com/notes/colour_and_gamma/GammaFAQ.html

IanB
2nd January 2011, 08:55
See this thread "U and V ranges for valid RGB".

ConverttoRGB() simply clamps out of gamut values to 0 or 255

Kuukunen
2nd January 2011, 09:19
See this thread "U and V ranges for valid RGB".

ConverttoRGB() simply clamps out of gamut values to 0 or 255
Heh, well, that was kinda my point.

And it's not just ConvertToRGB that clamps the values, it's something you have to do with any kind of conversion, in effect making all YUV outside of that invalid.

What I started wondering about while doing this is how much of RGB space is "invalid" in terms of YUV. In effect, which colours are lost when converting a video from RGB to YUV.

I guess I'll do that next time.....

jmac698
2nd January 2011, 09:25
You need 10 bits precision to convert rgb->yuv->rgb again, so yeah there can be banding issues. Don't give up on yuv though, the new standard xvYcc makes use of this fact to display an extended gamut. There is more than rgb output actually, there's tv's with 4 phosphors like an additional yellow, that you can buy in stores today.
I think that if you filtered the yuv to only contain valid rgb values, you would throw away some abilities like adjusting colors before conversion to rgb. That's a good question and it would take a long time to get you an answer.
I'm curious if animation videos ever contain non-rgb colors.

Update: yes they do! This is fantastic. A point I made in other thread about 10bit video, is what is the use of these invalid yuv colors? My answer is that they give you extended abilities to color correct the video before conversion to rgb. For example if you can saturate the color in yuv then convert to rgb to access "hidden" information in your video. It's wrong to think of non-valid values as something to just "throw away" - they have a real use!

Kuukunen
2nd January 2011, 10:38
What I started wondering about while doing this is how much of RGB space is "invalid" in terms of YUV. In effect, which colours are lost when converting a video from RGB to YUV.

I guess I'll do that next time.....
Actually, scratch that, RGB seems to be completely inside YUV space.

Kuukunen
2nd January 2011, 10:49
You need 10 bits precision to convert rgb->yuv->rgb again, so yeah there can be banding issues.
I considered talking about the 10-bit thing, but since it wasn't about banding, I figured rather not mix up yet another concept there. I've done some 10-bit banding tests with x264 before and results are very promising.

But you're sort of wrong there... You only need 9 bits. Ok, fine, you don't all the values, but at least according to my tests, you get 99.59% of 8-bit RGB values with 9 bit YUV, which is enough.

On the other hand odd number of bits might not make that much sense and since it doesn't hurt video compression anyway, it's better to just use 10. (Which is why it was added to x264 lately.)

jmac698
2nd January 2011, 10:55
I happen to know this because I noticed it when converting yellow, so that's one of your .41% of colors :)
It's good to know, however, that modern AVCHD camcorders are encoding from more than 8bit rgb from the camera sensor.
Like I said, the errors you are seeing are probably just a precision problem, not an inherent flaw of YUV. After all, this is a mathematic transform, it has to work in theory.

Gavino
2nd January 2011, 11:51
If you want a less blocky version, adjust the variable res. For me 4 ran out of memory and was slow as hell to render anyway.
Much faster (and simpler) than using repeated Overlay is to use mt_lutspa from masktools, as I did in the "U and V ranges for valid RGB" thread.

There are a couple of minor bugs in your script:
subclip=c.animate(0,64,"subs", 0,260) should be (0, 63, ..., 255)
and yuv=c.animate(0,64,"ufun",0,0,255,0) should be (0, 63, ...)

Heh, well, that was kinda my point.

And it's not just ConvertToRGB that clamps the values, it's something you have to do with any kind of conversion, in effect making all YUV outside of that invalid.
I'm not sure what your point is.
For all 'valid' YUV combinations, Grayscale gives the same result as you would get by ConvertToRGB().Greyscale().ConvertToRGB().
What are you suggesting that Greyscale should do differently?

Kuukunen
2nd January 2011, 17:42
I happen to know this because I noticed it when converting yellow, so that's one of your .41% of colors :)
You were dealing with 9-bit YUV? O_o

Kuukunen
2nd January 2011, 17:49
Much faster (and simpler) than using repeated Overlay is to use mt_lutspa from masktools
I know...
In fact, I messed with your script a bit.
But the thing is... I've always wanted to make a meaningful video using only internal filters. :>
There are a couple of minor bugs in your script:
subclip=c.animate(0,64,"subs", 0,260) should be (0, 63, ..., 255)
and yuv=c.animate(0,64,"ufun",0,0,255,0) should be (0, 63, ...)
Technically it's not a bug since it's working just as it's supposed to. :P
It wasn't working properly first and I fixed it in a funny way since it was closer to the cursor. :P
The real bug is that I forgot to fix the second one too.
I'm not sure what your point is.
For all 'valid' YUV combinations, Grayscale gives the same result as you would get by ConvertToRGB().Greyscale().ConvertToRGB().
What are you suggesting that Greyscale should do differently?
Of course I know that. In fact, that's what I said in the post. My point is (as I said) that you can't trust that the YUV values are valid. (Or to be precise, they're valid, they're just not valid RGB after conversion.) I think Grayscale() should clamp the values just as ConvertToRGB() does, because otherwise it's not grayscale. If you simply want the luma channel, there should be ShowLuma() or something to easily reset chroma or something.

Gavino
2nd January 2011, 18:17
I think Grayscale() should clamp the values just as ConvertToRGB() does, because otherwise it's not grayscale. If you simply want the luma channel, there should be ShowLuma() or something to easily reset chroma or something.
In Avisynth, Greyscale for a YUV clip is defined to preserve the luma value and set chroma to 128.

For RGB clips, it is defined in terms of a (notional) conversion to YUV with a specified matrix (default Rec.601).

To my mind, that is a simple and consistent scheme which maximises implementation efficiency.

Kuukunen
2nd January 2011, 19:03
In Avisynth, Greyscale for a YUV clip is defined to preserve the luma value and set chroma to 128.

For RGB clips, it is defined in terms of a (notional) conversion to YUV with a specified matrix (default Rec.601).

To my mind, that is a simple and consistent scheme which maximises implementation efficiency.
.....the whole POINT is that it's defined like that.

I KNOW.

I didn't claim at any point the implementation is broken.

What I was talking about is that it shouldn't be like that. There should be something for selecting luma channel and something for actual grayscaling.

Besides, first and foremost, I wrote this thread for myself.
Secondly, it's to warn people about the pitfalls in using luma as luminance.
And only third it's me thinking the Grayscale() function being broken. It's easy to go around, you just need to know how to do it. (See the second part.)

Gavino
2nd January 2011, 19:51
I KNOW.
I know you know. :) And it's a valid viewpoint.
I was stating my view that the way it is defined is simple, consistent and efficient.
There should be something for selecting luma channel and something for actual grayscaling.
But what is the meaning of 'actual grayscaling' for 'invalid' YUV values?
Again I argue that Avisynth's definition is the most sensible. If you want to clamp them to 'valid' RGB, use ConvertToRGB().Greyscale().ConvertToRGB() (all with the appropriate matrix).

Wilbert
2nd January 2011, 19:59
I think Grayscale() should clamp the values just as ConvertToRGB() does, because otherwise it's not grayscale.
Just curious, why do you say "... because otherwise it's not grayscale"? It seems you are saying that it is a RGB concept, and for YCbCr it is meaningless. There is not a clear definition of greyscale in that famous poyton link. To me it is just some mixture of white and black.

This can be problematic, since full luma does not mean white. White is the brightest colour on computer screens, and should be the only one to have full brightness in grayscale. I figured I never thought deeply about these things either, so I made some tests.

The problem is that full luma (assuming you mean Y=255) can mean white. This is the case when the full luma range YCbCr [0,255] is used for actual data (like for DV). Most of the times this is not the case and then you are right (white Y=235 gets converted to R=G=B=235 when greyscaling, and that's not white; well it's actually white in studio RGB). So when greyscaling a YCbCr clip you need to know if the full luma range contains actual data or not, and expand the luma range in the latter case.

Of course if people read the documentation they shouldn't be confused about what happens in which case.

Kuukunen
2nd January 2011, 22:20
Just curious, why do you say "... because otherwise it's not grayscale"? It seems you are saying that it is a RGB concept, and for YCbCr it is meaningless. There is not a clear definition of greyscale in that famous poyton link. To me it is just some mixture of white and black.
I'm naively assuming here that when people use Grayscale(), they want, well... a grayscale version of the video.

And at least to me, that means black & white video where each pixel's value tries to be the perceived brightness of the original pixel. You know... like in black & white TVs. If you qualify any black & white video as "grayscale" version of the video, you might as well replace the whole video with black & white noise. :P
The problem is that full luma (assuming you mean Y=255) can mean white. This is the case when the full luma range YCbCr [0,255] is used for actual data (like for DV). Most of the times this is not the case and then you are right (white Y=235 gets converted to R=G=B=235 when greyscaling
That should only happen if you're converting TV ranged YUV assuming incorrectly it's PC ranged YUV. If you have TV ranged video, Y=235 should always be converted into R=G=B=255 (Assuming chromas are 128)

Also, as I mentioned in the beginning of the post, I was ignoring the whole TV/PC range issue here for the sake of simplicity. Since it doesn't really change anything of the things I said.

Didée
2nd January 2011, 22:36
Well ... in physics, there are no concepts like "greyscale" or "luma/chroma separation". Those are artificial concepts. And since there is no "physical truth" behind, there are different such concepts. Going from "color" to "greyscale" looks different in YUV looks different than HSV(HSI) looks different than HSL looks different than Lab looks different than ......

YUV or YCbCr is one concept of luma/chroma separation. Avisynth performas greyscale in exactly the spirit of this particular concept. If you want to blame the concept, that's fine. But you shouldn't blame Avisynth for the shortcomings of the concept. ;)

Gavino
2nd January 2011, 22:51
I'm naively assuming here that when people use Grayscale(), they want, well... a grayscale version of the video.
And at least to me, that means black & white video where each pixel's value tries to be the perceived brightness of the original pixel.
I think we agree that's exactly what you get for 'valid' YUV pixels, ie those that can meaningfully be 'perceived' on a RGB display.
The only area where there can be any debate is what happens to pixels outside that range. Avisynth simply preserves the Y value and sets U=V=128, entirely consistent with its treatment of the 'valid' range, and with the (loose) interpretation of Y as brightness.

This (sensibly in my view) sidesteps any debate about how 'invalid' values should be converted in order to be perceived (clipping R, G and B independently is just one possible approach, and better ones have been proposed).

Kuukunen
2nd January 2011, 23:21
Well ... in physics, there are no concepts like "greyscale" or "luma/chroma separation". Those are artificial concepts. And since there is no "physical truth" behind, there are different such concepts. Going from "color" to "greyscale" looks different in YUV looks different than HSV(HSI) looks different than HSL looks different than Lab looks different than ......

YUV or YCbCr is one concept of luma/chroma separation. Avisynth performas greyscale in exactly the spirit of this particular concept. If you want to blame the concept, that's fine. But you shouldn't blame Avisynth for the shortcomings of the concept. ;)
Yes, from physics point of view, there is no such thing. Which is exactly why thinking from physics point of view is useless and we should concentrate on human perception. (Psychophysics?)

The fact Grayscale() is using the same formula as the Rec. 601 colourspace doesn't even matter here. It's just designed to match human perception of brightness as well as possible and thus, is suited for the job. (For 50s TV sets, tho, I guess.)

'Going from "color" to "greyscale"' should NOT depend on the colourspace. It should always try to be as close as possible to the human perception whether you're using YUV, HSL, Lab, RGB or CMYK. The latter two don't even have a component that try to match brightness, but they still can be converted to grayscale.

I did consider using Rec. 709 matrix for grayscale, since it's supposed to be better match for contemporary displays. But using the Rec. 601 matrix clearly displayed the 'valid' areas and it matched my perception better with a quick glance anyway.

As for the other colourspaces you mentioned... I did some checking. HSL, HSV, HSB and HSI don't seem to be standardized. But I guess based on the definition I found, HSI can be thrown out outright since it's not even trying to match human perception. Apparently HSL sometimes is defined in a way that it does try to. (Although that definition I found in Wikipedia is using the Rec. 601 Y formula for L.)

Also, I found out Lab is pretty much using the Rec. 709 primaries for the L. "Lab color is designed to approximate human vision. It aspires to perceptual uniformity, and its L component closely matches human perception of lightness." So it makes sense, since the Y in YUV is trying to do the same thing.

(Although in Lab, there seems to be some non-linearity in L at one end that's not in YUV. If that makes for a better brightness approximation, that should be used instead.)

So in fact, HSL and Lab ARE pretty much the same as YUV in terms of luma, if you select the Rec. correctly. :P

But as I said, that doesn't even matter. So once again: the fact I used the Y from YUV for grayscale is just coincidental. If I had been talking about converting RGB to grayscale, I would've used the exact same methods. Grayscale version should NOT depend on the colourspace.

Kuukunen
2nd January 2011, 23:35
I think we agree that's exactly what you get for 'valid' YUV pixels, ie those that can meaningfully be 'perceived' on a RGB display.
The only area where there can be any debate is what happens to pixels outside that range. Avisynth simply preserves the Y value and sets U=V=128, entirely consistent with its treatment of the 'valid' range, and with the (loose) interpretation of Y as brightness.

This (sensibly in my view) sidesteps any debate about how 'invalid' values should be converted in order to be perceived (clipping R, G and B independently is just one possible approach, and better ones have been proposed).
But the problem is, Avisynth has no notion or treatment of 'valid' ranges in YUV because the 'invalid' YUV values are in fact valid by themselves, and you might end up having them in your video if you do colour correction etc.

I personally have no idea if this can even realistically be a problem. I'm guessing you'd need some insane colour correction to punch values far into the 'invalid' areas. But it's something that one should be aware of.

Remember, this whole thing started when a guy wanted to check if almost whole frame was white. (And then replace it with actual full white.) So if you have some weird high saturation rainbow frame, you might end up incorrectly assuming it's white if you're blindly using grayscale() without clamping. (Although given his video, it's definitely not too likely to happen.)

Also, as for the debate on methods instead of clipping... I wasn't trying to start a debate on that. :P
Any method used will end up having the same problems anyway. (Unless you do something funny like converting all luma 255 values into white, disregarding the chroma, but that would be just silly.)

Besides, the YUV->RGB conversion is done at the decoding/playing end anyway, so it doesn't really matter what you do in Avisynth. (Unless you're talking about modifying how Grayscale() works, which is what I was suggesting to be modified in the first place.) Afaik clamping is the de facto standard.

Gavino
2nd January 2011, 23:38
Grayscale version should NOT depend on the colourspace.
And in Avisynth, for all valid input, the result is independent of colorspace.

Kuukunen
3rd January 2011, 01:11
And in Avisynth, for all valid input, the result is independent of colorspace.
For the Nth time, the YUV that's invalid RGB is still valid YUV.
And there's really no way of ensuring you only have YUV that can be converted into RGB, so that point is moot.
And even then, it's NOT independent of colourspace. It's just the luma channel, which DEFINITELY depends on what the colourspace is.

jmac698
3rd January 2011, 02:21
So he's saying the arithmetic is always the same, you are saying that operations in yuv space can lead to invalid rgb when it was originally valid?
I would say you have a point. But can't we just say that's the nature of yuv operations? And the result is usually mapped to a reasonable interpretation?

Wilbert
3rd January 2011, 19:47
'Going from "color" to "greyscale"' should NOT depend on the colourspace. It should always try to be as close as possible to the human perception whether you're using YUV, HSL, Lab, RGB or CMYK. The latter two don't even have a component that try to match brightness, but they still can be converted to grayscale.
Am i right that you define greyscale as being brightness here (where luminance is some approximation of brightness and brightness is defined in that FAQ)? I can't speak for others, but i think must of us don't.

I guess that's where the difference in opinion comes from.

IanB
3rd January 2011, 21:40
For the Nth time, the YUV that's invalid RGB is still valid YUV.
Not quite!

YUV that is invalid RGB is undefined YUV. YUV that is valid RGB is defined YUV.

By undefined I mean if you use these values then you better know the explicit behaviour of the explicit downstream processes. In other words that behaviour is not defined in general.

hanfrunz
4th January 2011, 12:45
I repeat myself but it's really good stuff to read and learn:

Tektronix: Understanding Color and Gammut (http://www.tek.com/zh/education/PDF/25W_15618_3.pdf)
http://tech.ebu.ch/docs/techreview/trev_301-gierlinger.pdf
EBU Technical Recommendation R103-2000 Tolerances on "Illegal" colours in television (http://tech.ebu.ch/webdav/site/tech/shared/r/r103.pdf)
Eyeheight: Video Legalizer (product) (http://www.eyeheight.com/FileDownload.asp?filename=tech_sheets/compliance/LE-2U_multi-rate_dual_link_444_legaliser_module_tech_sheet.pdf)
The famous Color FAQ by Charles Poynton (http://www.poynton.com/PDFs/ColorFAQ.pdf)
my allcolors-filters to play with all of them (http://forum.doom9.org/showthread.php?t=104846) :)

Gavino
4th January 2011, 13:12
Also of interest is:
http://downloads.bbc.co.uk/rd/pubs/reports/1987-22.pdf

This provides a numerical method for bringing 'invalid' YUV values into valid RGB range. Interestingly from the point of view of this thread, it suggests the 'best' way is not to saturate R, G and B individually but to preserve luma and hue. This gives an image whose Grayscale counterpart is exactly what you get from Avisynth.

Kuukunen
4th January 2011, 14:12
Am i right that you define greyscale as being brightness here (where luminance is some approximation of brightness and brightness is defined in that FAQ)? I can't speak for others, but i think must of us don't.

I guess that's where the difference in opinion comes from.
By greyscale, I mean a black and white version of a colour video that looks as natural as possible. Which is not what happens with Grayscale().
I was kind of assuming most people define it like that, but I guess I was wrong.
Not quite!

YUV that is invalid RGB is undefined YUV. YUV that is valid RGB is defined YUV.

By undefined I mean if you use these values then you better know the explicit behaviour of the explicit downstream processes. In other words that behaviour is not defined in general.
I don't understand what you mean. YUV that's invalid RGB is invalid RGB. That's a tautology.
As far as I know, YUV is not originally defined based on the current computer RGB model. So the "invalid" areas are very much defined. (or at least some of them, some might fall outside human perception, but that's besides to point.)
There's colours outside of RGB too, you know...

****

I don't even know why you're arguing about that. The point is that YUV that is not defined in RGB is still valid YUV by itself.
Besides, that doesn't even matter. In fact, it's totally outside the whole point I was trying to make. What matters is that you will run into video that has signals that are not defined in RGB space. And you have to deal with them. I'd rather deal with them in a smart way instead of explicitly having to fix everything by hand. And if an YUV video file is meant for RGB displays, you have to deal with it as such.

Yes, I know there are alternatives for just clamping the RGB, but if the video you're working with is not both made by you and meant for viewing only by you on your modified system, it has no importance whatsoever. You have to deal with the video in a way that works with video playback that does clamping, since it seems to be the default.

What I've been trying to say is that while YUV that's outside RGB is valid YUV, displays usually work in RGB so if you're dealing with video that is supposed to be shown on RGB screen, you have to take that into account. And based on the definition of greyscale I mentioned before, greyscale just doesn't happen. I've wondered many times why there's no actual "select luma channel" filter in avisynth.

Gavino
4th January 2011, 15:18
By greyscale, I mean a black and white version of a colour video that looks as natural as possible. Which is not what happens with Grayscale().
But it is, if you accept the conclusions of the BBC paper I quoted above.
I've wondered many times why there's no actual "select luma channel" filter in avisynth.
There is - it's called Greyscale. :)

Kuukunen
4th January 2011, 18:08
But it is, if you accept the conclusions of the BBC paper I quoted above.
Err, what?
That BBC paper has nothing to do with it. The paper is talking about limiting YUV signals.
For the N+1th time, you can't trust the signals have been limited to the RGB range.
There is - it's called Greyscale. :)
Yes I know, but it's named funny, and IMHO incorrectly. :P

pandy
4th January 2011, 18:29
IMO You mixing and confusing many things... eg 16-235 on Y and 16-240 on Cb/Cr means only 0-700mV on Y and -350 - +350mV on Pb/Pr (valid for video without 7.5IRE pedestal, 128 means NO COLOR ie 0mV on Pb/Pr), Grayscale means only on YCbCr pure Y, on RGB it means only that R=G=B. Full luma ie 235 is equal to 700mV on video output and this mean that this is 100% WHITE, in PC Graphics world 100% WHITE is R=G=B=255=700mV(sometimes 1V ie 1000mV) thats all about WHITE - try different calculations with YCbCr - You realize that there is many cases where when Y=16 (0% WHITE ie BLACK) Cb and Cr samples can have 255 or 0 and in RGB space this create NEGATIVE value (how create NEGATIVE GREEN LIGHT?) - From Video point of view such signal is still VALID and produce VALID results at the YPbPr output - there is nothing wrong with this - YCbCr cover partially RGB and RGB cover partially YCbCr space.

Wilbert
4th January 2011, 19:44
By greyscale, I mean a black and white version of a colour video that looks as natural as possible. Which is not what happens with Grayscale().
I don't want to nickpit (although perhaps it sounds like that), but in what sense can a black and white version of a colour video look natural? That's not clear to me. I mean, we aww in a color world, and not a black and white one.

Kuukunen
5th January 2011, 10:24
IMO You mixing and confusing many things... eg 16-235 on Y and 16-240 on Cb/Cr means only 0-700mV on Y and -350 - +350mV on Pb/Pr (valid for video without 7.5IRE pedestal, 128 means NO COLOR ie 0mV on Pb/Pr), Grayscale means only on YCbCr pure Y, on RGB it means only that R=G=B. Full luma ie 235 is equal to 700mV on video output and this mean that this is 100% WHITE, in PC Graphics world 100% WHITE is R=G=B=255=700mV(sometimes 1V ie 1000mV) thats all about WHITE - try different calculations with YCbCr - You realize that there is many cases where when Y=16 (0% WHITE ie BLACK) Cb and Cr samples can have 255 or 0 and in RGB space this create NEGATIVE value (how create NEGATIVE GREEN LIGHT?) - From Video point of view such signal is still VALID and produce VALID results at the YPbPr output - there is nothing wrong with this - YCbCr cover partially RGB and RGB cover partially YCbCr space.
Hum, so you're claiming full luma means white?
But at least on computers that's clearly not the case.
In fact it's pretty much the point I was trying to make.
Look at the shot in the first post that has full luma and changes the chroma. It's clearly not all white.
Also, YCbCr doesn't "partially" cover RGB, RGB is completely inside YCbCr. (As I mentioned in an earlier post.)
I don't want to nickpit (although perhaps it sounds like that), but in what sense can a black and white version of a colour video look natural? That's not clear to me. I mean, we aww in a color world, and not a black and white one.
Of course it can never look natural. I said "as natural as possible". You've watched black&white video before, right? I claim there are worse and better ways to do it.
And as far as I figure, the most natural way would be to convert colours into black-white based on the perceived brightness.

2Bdecided
5th January 2011, 15:49
Look at the shot in the first post that has full luma and changes the chroma. It's clearly not all white.If you have full luma, the only valid chroma is 128. Anything else will just reveal failings in the specific YUV>RGB conversion you use.

You are looking at this completely the wrong way.

Cameras are RGB.
Displays are RGB.
Eyes are (arguably) RGB.

We use YUV because eyes see colour at a lower resolution than luma, so both in analogue and digital video this representation allows a lower bandwidth to be used for the same perceived quality.

Also historically YUV (actually YIQ for NTSC) was chosen because colour was retrofitted to black-and-white TV systems, which already have "Y". (Things could have been quite different: The first colour TV systems were not backwards compatible with black-and-white, didn't make efficient use of bandwidth, and therefore used RGB)


It's a convenient transformation. That's all.

You might as well complain that fiddling with the values of the MDCT coefficients in an mp3 file can give decoded results that clip. Yes, they can. And if you're daft enough (or forced to) process in a domain that's merely a transform of the wanted signal, you'd better make damn sure that you don't mess thing up in the wanted signal domain.

Which, for video, means avoiding some combinations of Y, U and V!

Cheers,
David.

P.S.And as far as I figure, the most natural way would be to convert colours into black-white based on the perceived brightness.Yes, it's called luma. AVIsynth is doing it correctly. An RGB decoder that accepts any old YUV values, performs the conversion, and then clips in the RGB domain is doing it incorrectly (though of course that's the simplest thing to do, and therefore the most common). The papers linked in this thread show the correct approach to get a correct RGB colour image - but if you only want black-and-white, luma already gives it to you. Why is that so difficult to understand?

pandy
5th January 2011, 16:47
Hum, so you're claiming full luma means white?

I mean that 100% WHITE in video world is 700mV (or 714mV) and this is 100IRE when 0%WHITE ie BLACK is 0 IRE - for 8 bit video, code that correspond to 100IRE is 235, for 10 bit video (8.2) it is 940, code for 0 IRE ie BLACK in video world it is 16 for 8 bit and 64 for 10 bit (code as decimal number).

If you want to have values from PC world then you must multiply sample value without headroom (ie 16) by (255/219) that's all.


But at least on computers that's clearly not the case.
In fact it's pretty much the point I was trying to make.
Look at the shot in the first post that has full luma and changes the chroma. It's clearly not all white.
Also, YCbCr doesn't "partially" cover RGB, RGB is completely inside YCbCr. (As I mentioned in an earlier post.)


RGB analog yes, digital RGB 8bit in 8bit YCbCr not.
do not mix PC and video worlds.

Kuukunen
6th January 2011, 03:32
Cameras are RGB.
Displays are RGB.
Eyes are (arguably) RGB.
Indeed! Which is why I wrote the original post in the first place!

Although... Eyes are not exactly RGB. There are two types of cells: cone cells and rod cells. And there's three subtypes of cone cells. It's the cone cells that are RGB. ...Well sorta... I can't speak for every possible "RGB" system, but the best ones should be decided so that the R, G and B activate the cone cells individually, which because of overlap in cone cell sensitivity means not the wave-lengths on which the subtypes are at their most sensitive.
Rod cells pretty much detect luminance. And I'm not sure, but half-assuming that the higher luma resolution of eyes might be because the rod cells are much more sensitive than cone cells. (Which is funny, since you talk about about exact same thing on your next paragraph.) So I guess you could think eyes are ~YRGB.

Which, for video, means avoiding some combinations of Y, U and V!
I don't quite understand what you mean by avoiding the combinations.
Which of these are you saying?:
1) You can safely assume every video you deal with that's not made by you has no "invalid" YUV values? (I don't think you can. And the video is probably made for display on RGB system, meaning it is probably made assuming the clamping conversion, since that's the most common.)
2) You should never use filters that can cause "invalid" YUV values?
3) Filters should be made in such a way they handle these invalid values in a smart way? (No wait, that's what I suggested for grayscale())
4) You should end pretty much every (YV12) Avisynth script, in ConvertToRGB().ConvertToYV12()? ... Well that and also put it in places like before grayscale(). (Or is there a nicer way for doing that, anyway?)
5) If you run into a video that has "invalid" values, you're gonna start complaining how the people who made the video/filters are morons and you refuse to work with it.

For the N+2th time, if you're going to run into these "invalid" values, it doesn't even matter whether they're invalid or valid, you just have to deal with them.
The papers linked in this thread show the correct approach to get a correct RGB colour image - but if you only want black-and-white, luma already gives it to you. Why is that so difficult to understand?
*sigh* I understand everything you said perfectly, but I don't think you understand what I've been saying. As I explained before, the method in the paper doesn't matter if it's not in use in both ends.

If someone is tweaking the colours in a YUV video, he's probably watching it on a system that does the clamping version of RGB conversion... And he should, because that's probably what happens on the other end too. And people (should) tweak the video based on their own eyes, not math. If you're only producing video for yourself to be displayed on your funnily tweaked system, go for it! Although if you're going that far, it would probably be better for you to avoid the "invalid" colours anyway, but I can't trust all my filters do that and that every video not produced by me does that.
I mean that 100% WHITE in video world is 700mV (or 714mV) and this is 100IRE when 0%WHITE ie BLACK is 0 IRE - for 8 bit video, code that correspond to 100IRE is 235, for 10 bit video (8.2) it is 940, code for 0 IRE ie BLACK in video world it is 16 for 8 bit and 64 for 10 bit (code as decimal number).
But that's totally unrelated. We're talking about digital video here. And in digital video: 1) Full luma, be it 235 or 255, does not mean white in most systems. Complain about how that's wrong all you want, but that's the truth. Even if you go to Wikipedia (http://en.wikipedia.org/wiki/Ycbcr) you can see they're doing that. 2) You will run into video that has those values

RGB analog yes, digital RGB 8bit in 8bit YCbCr not.
do not mix PC and video worlds.
Ok, I'm starting to wonder if I'm getting trolled here or something.
So just making it sure: you're claiming digital RGB space is not totally inside digital YCbCr space? (Assuming Rec. 601 here since that's what we've been talking about.)
I made that statement based on a very simple test I made: I made a program that converted every possible 8-bit RGB value into YUV and checked what happens. Every possible RGB value converted invo YUV without going outside 0-255. (And if you do the same thing with TV range, of course you get the same result because of the way it's designed.)
Well ok, if you, for some reason, round the numbers, you end up with two values with 256 chroma (RGB 0,0,255 and 255,0,0), but that's beside the point. Unsurprisingly the conversions are designed so that the extreme RGB values (0, 255) lie on the very edge of the YUV space, but still inside.

What is true, however is that because the YUV space is much bigger and still the same amount of bits, there are multiple RGB values that correspond to one YUV value. I made another very similar test program that gave me the result that every possible YUV value will only result in 25% of possible RGB values. (Because most YUV values are outside of RGB space.) Is that what you mean? But even still, I would certainly say RGB space IS still completely inside the YUV space.

Also, I'm not mixing vide and "PC" worlds (Don't you mean digital? Are you sure you're not mixing "analog" and "TV range" etc?). Also, as I stated in the very beginning, I'm using YUV as a shorthand for YCbCr, because that's what other people seem to be doing too. (Including Avisynth documentation.)

2Bdecided
6th January 2011, 12:27
I wasn't saying any of 1-5.

*sigh* I understand everything you said perfectly, but I don't think you understand what I've been saying. As I explained before, the method in the paper doesn't matter if it's not in use in both ends.If you think you may have a problem, you legalise the video using that method in the YUV domain before it leaves you. Simple.

Really.

It is that simple!

If someone is tweaking the colours in a YUV video, he's probably watching it on a system that does the clamping version of RGB conversion... And he should, because that's probably what happens on the other end too.Depends. A DVD player + Composite or S-video or Component connection + CRT TV won't clamp a thing.

And people (should) tweak the video based on their own eyes, not math.A professional would use a videoscope to ensure things stay in range. Real professionals check for all kinds of things that aren't obvious just by eyeballing your PC screen. e.g. (historically) interlacing twitter and composite cross-colour effects.

I don't expect amateurs to do it properly, and I don't expect amateur tools to help. Of course there are plenty of clueless amateurs who get paid for their work - I wouldn't call them professionals though.

Cheers,
David.

Kuukunen
6th January 2011, 14:52
Depends. A DVD player + Composite or S-video or Component connection + CRT TV won't clamp a thing.
So... are you saying full luma and changing the chroma (even to "invalid") values will always be white?
I wasn't saying any of 1-5.

If you think you may have a problem, you legalise the video using that method in the YUV domain before it leaves you. Simple.
What are you saying then?

What method? The one on the paper? Is there an Avisynth filter for it? As I keep saying, I've been talking about the Avisynth point of view the whole time. This is the Avisynth Usage subforum for crying out loud.

And for the N+3th time, it's not enough if you "legalise" it before it leaves you. If you use things like Grayscale() with Avisynth, you might have to "legalise" it even multiple times, otherwise it won't have the wanted result. Is that what you mean? Based on what you just said, it would match the 4th point pretty well.

2Bdecided
7th January 2011, 13:11
So... are you saying full luma and changing the chroma (even to "invalid") values will always be white?No, on such displays (and quite a lot of displays) the possible range of displayed colours is far wider than the input signal. So you can have a colour that's as bright as 100% luma, and red. And even then you can still add even more red. It's an analogue signal driving an electron gun in a CRT - it saturates quite gently. Of course eventually it does saturate, but it's at quite high levels - not at a single step above the valid range.

If you add chroma to 0% luma, the effect varies - you basically get black, and sometimes you get a kind of ghost of just visible colour on top of it. It depends partly on the setting of the TV's brightness control. Whereas on a PC with convert-then-clip you can force quite bright colours at lume=0% - which is of course wrong.


This is going a bit off topic though - the point isn't what this or that display does - the point is to send video that is legal+valid and hence displays basically the same on all devices.
http://www.poynton.com/notes/video/Confusion.html

If you don't, the result is unpredictable. You've noticed that you get the wrong colour, and even the wrong luminance, by converting-then-clipping. But it's worse than that - when clipping you can reduce areas of luma detail to a single clipped colour - whereas the approach suggested in the paper will maintain the luma detail.

What method? The one on the paper? Is there an Avisynth filter for it? As I keep saying, I've been talking about the Avisynth point of view the whole time. This is the Avisynth Usage subforum for crying out loud.I can't remember if we reached a good solution for AVIsynth in previous threads. If not, maybe someone should write one.

And for the N+3th time, it's not enough if you "legalise" it before it leaves you.It doesn't matter how many times you say something, it doesn't make it right.

When you open your mind to the possibility that you might not be understanding this properly, and that you might actually be wrong, and that other people on this forum might be right, then you'll get a lot more from this thread. ;)

Cheers,
David.

Kuukunen
7th January 2011, 16:17
And for the N+3th time, it's not enough if you "legalise" it before it leaves you.It doesn't matter how many times you say something, it doesn't make it right.
nnnnnngggggghhhhhhh....

That's basic logic. It's just that in this thread people have just misunderstood basic concepts I explained and/or ignored stuff I've written, which is why it's getting somewhat tiring to repeat those things. (I guess I write too long and boring or something, dunno.)

For example, again, you just brushed the thing I said aside and totally ignored it. You're saying repeating something doesn't make something correct. Of course it doesn't! It's called "proof by assertion" and logic doesn't work like that.

But basically by saying that, you implied you thought I was incorrect on that statement. => You are claiming if you have an YUV video made for RGB screens that has "invalid" YUV values you don't have to "legalise" the values before Grayscale(). ... Which is clearly an incorrect statement.
No, on such displays (and quite a lot of displays) the possible range of displayed colours is far wider than the input signal. So you can have a colour that's as bright as 100% luma, and red. And even then you can still add even more red.
Yay, at least we're getting there. That's why I've been putting quotes around "invalid" YUV, because it's not (all) invalid, it just can't be converted to RGB. So at least that thing you're agreeing on:
Full luma does not mean white => If you have video that is meant to be dispayed on RGB screens and has "invalid" YUV values, "grayscale" doesn't actually give you the perceived luminance.
point isn't what this or that display does - the point is to send video that is legal+valid and hence displays basically the same on all devices.
Err, of ..... course? And for the N+4th time, the much related point is: 1) you can't guarantee all video that comes in to you is "valid" 2) you can't guarantee all Avisynth filters produce "valid" video

I can't remember if we reached a good solution for AVIsynth in previous threads. If not, maybe someone should write one.

Kinda why I was asking, since you were talking about "legalising" the video. And as I keep saying, we're talking about Avisynth point of view here and mostly about video meant for RGB display, so it's kind of important.

Based on my tests, if you do converttorgb().converttoyv12() to an YV12 video that only has "valid" values (in Rec. 601), you only get 67.63% of the values back, causing some banding. So that's not a good solution.

So I guess the best solution is to work as basically everyone is doing anyway: if you're working on a video meant for RGB displays, don't "legalise" anything. ...Except if you're not 100% sure about the RGB end and you have some video with crazy values and/or you want to use grayscale().
When you open your mind to the possibility that you might not be understanding this properly, and that you might actually be wrong, and that other people on this forum might be right, then you'll get a lot more from this thread. ;)
In the very first post I said "I probably made mistakes and misunderstood stuff", of course I know it's possible, but you're saying that in a way you have some idea, but "might not be understanding" what properly? Please do explain.

And wrong about what? Most of the things you've said are simply off-topic, obvious or just logically incorrect, but you haven't really explained where I'm wrong about anything. You've just ignored pretty much everything I've said, like many other posters... Which is why I mentioned that trolling comment, because that's the feeling I've gotten.

Sorry for getting a bit rude. I do enjoy a debate much more than your average guy, but I still get annoyed when the other person is not listening to anything I say and I have to keep repeating myself.

poisondeathray
7th January 2011, 16:22
Based on my tests, if you do converttorgb().converttoyv12() to an YV12 video that only has "valid" values (in Rec. 601), you only get 67.63% of the values back, causing some banding. So that's not a good solution.


How are you doing these tests or measuring values ?

Wilbert
7th January 2011, 19:59
That's basic logic. It's just that in this thread people have just misunderstood basic concepts I explained and/or ignored stuff I've written, which is why it's getting somewhat tiring to repeat those things. (I guess I write too long and boring or something, dunno.)

Sometimes you claim something without anything to back it up. I'm still waiting for a satisfactory response to this:

I don't want to nickpit (although perhaps it sounds like that), but in what sense can a black and white version of a colour video look natural? That's not clear to me. I mean, we aww in a color world, and not a black and white one.
Of course it can never look natural. I said "as natural as possible". You've watched black&white video before, right? I claim there are worse and better ways to do it.
And as far as I figure, the most natural way would be to convert colours into black-white based on the perceived brightness.
What do you mean with "as natural as possible"? Before you will repeate last the sentence. What do you mean with "(...) perceived brightness. "? How do you determine the perceived brightness? The famous faq says

"However, brightness is defined formally as the attribute of a visual sensation according to which an area appears to emit more or less light. This definition is obviously subjective, so brightness is an inappropriate description of, or metric for, image data."

2Bdecided
7th January 2011, 23:28
But basically by saying that, you implied you thought I was incorrect on that statement. => You are claiming if you have an YUV video made for RGB screens that has "invalid" YUV values you don't have to "legalise" the values before Grayscale(). ... Which is clearly an incorrect statement.This might be "clear" to you, but since everyone else in the thread is telling you that you don't need to do anything to U or V before calling greyscale()...!

Full luma does not mean white => If you have video that is meant to be dispayed on RGB screens and has "invalid" YUV values, "grayscale" doesn't actually give you the perceived luminance.Actually, greyscale gives the perceived luma on the CRT example I gave. It doesn't give you the perceived luma you get on a covert-then-clip PC RGB display, because that perceived luma is wrong.

Based on my tests, if you do converttorgb().converttoyv12() to an YV12 video that only has "valid" values (in Rec. 601), you only get 67.63% of the values back, causing some banding. So that's not a good solution.No, it's a terrible solution, but not just for the problem you think (which you could reduce greatly just by using matrix="PC.601" on the conversion). It gives you legal and valid YUV video, but clips all luma below 16 and above 235, and potentially generates false colours for all invalid values in the original video. Utterly pointless.

Cheers,
David.

2Bdecided
7th January 2011, 23:34
Sorry for getting a bit rude. I do enjoy a debate much more than your average guy, but I still get annoyed when the other person is not listening to anything I say and I have to keep repeating myself.In short, your fundamental premise is wrong. People keep telling you this, and you don't believe them. That's why you keep repeating yourself.


What it looks like on a convert-then-clip RGB display is wrong.*

greyscale() is right.**

If you don't want to believe this, fine. But don't bother asking any other questions if you won't believe the answers to them.


* - you can prove this with trivial operations. Pick some really wild UV values, fix those, then adjust Y only. In some ranges, increasing Y will make the image darker, and decreasing Y will make the image lighter. Utterly insane. Utterly wrong. It's almost perverse to expect greyscale() to do the same silly thing!

** - well, it should be. It should give you Y. I have a vague recollection of seeing something subtly different in some circumstance, but I can't remember what it was.

Cheers,
David.

Kuukunen
8th January 2011, 13:52
How are you doing these tests or measuring values ?
http://codepad.org/Xdwd42Rs
It's also displaying how bad 8-bit YUV fits 8-bit RGB.
But actually, good thing you asked, since as you can see from the output, there was bug there that caused incorrect results. (Correct values are 99.28% and 99.46% for PC and TV range respectively.)
So in the end, ConvertToRGB().ConvertToYV12() DOES work pretty well.
It was just a quick hack on the existing program, and I WAS kind of shocked about how badly it performed, (I assumed something more similar to the corrected results.) but I was too busy with the main point I was trying to make to double-check everything. Sorry for the panic.

Related:

No, it's a terrible solution, but not just for the problem you think (which you could reduce greatly just by using matrix="PC.601" on the conversion). It gives you legal and valid YUV video, but clips all luma below 16 and above 235, and potentially generates false colours for all invalid values in the original video. Utterly pointless.
Err, what do you mean by using 'matrix="PC.601"'? I think you're misunderstanding something profound here. (Although I assume it was just a small memory lapse.) You can't specify the matrix there just because it would work better. If your video is TV ranged, you use TV range matrix and vice versa. Not to mention, doing that to PC ranged video (with correct matrix) has WORSE results than doing it for TV ranged video. I'll get back to that clipping point later.

Sometimes you claim something without anything to back it up. I'm still waiting for a satisfactory response to this:

What do you mean with "as natural as possible"? Before you will repeate last the sentence. What do you mean with "(...) perceived brightness. "? How do you determine the perceived brightness?
Oh that was the problem? Then it's easy. Ok fine, I didn't want to use "luminance" there because some people might think it's referring to the luma channel, so I used "brightness" in order to avoid confusion, but I guess I only caused some. Although, you yourself said "where luminance is some approximation of brightness".

As I said before, I have no problem with using the luma channel formula from Rec. 601 for approximating perceived brightness. (Or Rec. 708)

Actually in my very first post, about Rec. 601 luma channel: "it's meant to match human perception of brightness as well as possible".

(Oh sorry, those were all repeats from before, but I guess that's what you were after?) NOW can I repeat the previous statement that explains the rest?

What it looks like on a convert-then-clip RGB display is wrong.*
Of course it's "wrong", I never claimed it wasn't. But is it really so hard to believe non-professionals (or even some professionals) create such videos? What you don't seem to understand is that it doesn't even matter if it's wrong, you're still going to have to deal with it. (Well, unless you go with the suggestion 5 from a previous post.)

* - you can prove this with trivial operations. Pick some really wild UV values, fix those, then adjust Y only. In some ranges, increasing Y will make the image darker, and decreasing Y will make the image lighter. Utterly insane. Utterly wrong. It's almost perverse to expect greyscale() to do the same silly thing!
Can you please tell me an example of a range where these utterly insane things happen.
Because... I can't find any.

Kuukunen
8th January 2011, 13:52
Ok, since there seems to be great deal of misunderstandings, I'll try to explain my basic premise here in a short but precise way. In fact, you can pretty much ignore the previous post, it was just details, anyway.

First I will define these words for the sake of simplicity:
invalid YUV: Actually valid or invalid YUV values that cannot be converted into RGB
actually invalid YUV: YUV that doesn't make any sense. (Negative light etc.)
illegal YUV: YUV values outside of the specified range. In 8-bit video: [0,255] I don't know what I should call the values in TV range below 16 etc, but that doesn't matter.
greyscale: Greyscale version is a black & white video where each pixel's value approximates the perceived brightness of the colour version. For the sake of simplicity: let's say greyscale from RGB uses the Rec. 601 luma channel formula.

§1: I'm talking about Avisynth and digital video.
* Have been since the beginning. Not analog video or "professional tools".
§2: There is a subset of YUV video people deal with that is made to be displayed on RGB display.
* Actually, YUV video meant to be displayed on RGB displays is the vast majority of the video I've dealt with.
§3: Some of this video (arguably "incorrectly") has invalid YUV values.
* Or it can be caused by filters you use. Doesn't even matter.
§4: The de facto standard way of dealing with illegal RGB values gotten from invalid YUV is just to clamp each RGB channel individually to [0,255].
§5: Video mentioned in §3 is made with the assumption it will be displayed on an display that is using method mentioned in §4.
* Although, if the maker of the original video is unprofessional enough to have invalid YUV there in the first place, it is probably an implicit assumption rather than an explicit one.
§6: Video mentioned in §3 should be dealt with with an assumption that the maker of the video used his eyes when tweaking colours and working with the video.
* Again, if he is unprofessional enough to have invalid values in the video, I don't think he is using anything fancier.
§7: Because of §6, the "incorrect" conversion of §4 is actually the correct one for videos mentioned in §3.
* Otherwise the video will look different from what it was meant to look like.
§8: Because of §7, Using Grayscale() on a video mentioned in §3, will give results that might be unexpected.

Is there something in that bunch that you disagree with?

Here is an example that pretty much sums up all of the above:
If you have a video that is made/tweaked on RGB display, is meant to be displayed RGB displays and has lots of YUV (255, 255, 255) and YUV (176, 173, 184) in it, those two colours will look exactly the same. And they should, because that is the assumption under which the video was made/tweaked. You can argue it's "incorrect" all you want, but that simply does not matter, because the video was made with the assumption that they look the same. But if you use Grayscale() on it, those two colours will not look the same.

****

Allow me to repeat something I said before. The main reason for starting the thread was for me to learn stuff. (You know the "learn a lot when teaching."-effect.)

The second reason was to present my findings to other people so they might learn too. The very first sentence of this whole thread talked about how a guy wanted to make a script that checks if a frame is mostly white. You can't reliably use AverageLuma() because full luma doesn't mean white, and to his surprise, using Grayscale() before AverageLuma() doesn't help either. (Although of course most likely it would've worked just fine, as two paragraphs down.)

The third and most minor reason was to suggest that Grayscale() might not be working as people expect. Again, I don't even say "it has to changed!!!". I mean if its shortcomings are well known and documented, sure, fine, but I just thought it would be nice to have it worked in a more practical way. Or maybe have it as an option.

That all being said, personally I don't even think it's a big problem either way. I would assume it's not very likely to even run into video that has those extreme colours. Although, it's still possible: say, if you're dealing with a video that has insane, psychedelic computer generated video effects that have been totally overfiltered in YUV space.

Wilbert
8th January 2011, 15:52
Oh that was the problem? Then it's easy. Ok fine, I didn't want to use "luminance" there because some people might think it's referring to the luma channel, so I used "brightness" in order to avoid confusion, but I guess I only caused some. Although, you yourself said "where luminance is some approximation of brightness".

As I said before, I have no problem with using the luma channel formula from Rec. 601 for approximating perceived brightness. (Or Rec. 708)

Actually in my very first post, about Rec. 601 luma channel: "it's meant to match human perception of brightness as well as possible".
You still miss my point. Let me explain it in another way. Suppose i have a YCbCr clip (from a dvd or whatever) and i convert it to RGB using (1) Rec.601 and (2) Rec.709 and (3) some other cooked up coefficients. Finally i apply GreyScale to those three clips. Now, how do i judge which of the three looks more natural?

Kuukunen
8th January 2011, 16:12
You still miss my point. Let me explain it in another way. Suppose i have a YCbCr clip (from a dvd or whatever) and i convert it to RGB using (1) Rec.601 and (2) Rec.709 and (3) some other cooked up coefficients. Finally i apply GreyScale to those three clips. Now, how do i judge which of the three looks more natural?
Again, I think you're misunderstanding something there.
(1), (2), (3): of course you use the colourmatrix that was meant to be used with it. I think at least the vast majority of DVD streams is Rec. 601. The question of how to figure out what is the correct matrix to use for a given video is another story, and can be a complicated or even impossible one.

I'll go ahead (or back) a bit: as for the natural next question: Once you have RGB, what to use as formula for approximating the brightness... Throughout the thread, I've been talking about Rec. 601 for the sake of simplicity. But one might argue for current displays Rec. 709. matches perceived luminance better. If that's what you think... good, use that! Or if there's new scientific breakthrough study that defines new coefficients for luminance... use those! But please, at least try to match human perception.

2Bdecided
10th January 2011, 13:10
§4: The de facto standard way of dealing with illegal RGB values gotten from invalid YUV is just to clamp each RGB channel individually to [0,255].
§5: Video mentioned in §3 is made with the assumption it will be displayed on an display that is using method mentioned in §4.
* Although, if the maker of the original video is unprofessional enough to have invalid YUV there in the first place, it is probably an implicit assumption rather than an explicit one.
§6: Video mentioned in §3 should be dealt with with an assumption that the maker of the video used his eyes when tweaking colours and working with the video.
* Again, if he is unprofessional enough to have invalid values in the video, I don't think he is using anything fancier.
§7: Because of §6, the "incorrect" conversion of §4 is actually the correct one for videos mentioned in §3.
* Otherwise the video will look different from what it was meant to look like.

Is there something in that bunch that you disagree with?Yes - the assumption that, if someone breaks something in a video on the way to a DVD, we shouldn't try to unbreak it, but preserve the worst possible result of the fault. If that's what you believe, I can't see you have much use for AVIsynth.

I also disagree with your assertion that most people who create invalid YUV values are intentionally colour correcting to produce the effect seen on a convert-then-clip RGB PC display.

It's possible that some people push the adjustment to extremes to create some kind of blown-out posterised artistic effect, but it's likely that most people don't notice the problem areas, and those that do see some occasional strange (and unwanted!) effect don't have a clue what to do about them (lacking the tools and/or knowledge).

Here is an example that pretty much sums up all of the above:
If you have a video that is made/tweaked on RGB display, is meant to be displayed RGB displays and has lots of YUV (255, 255, 255) and YUV (176, 173, 184) in it, those two colours will look exactly the same. And they should, because that is the assumption under which the video was made/tweaked. You can argue it's "incorrect" all you want, but that simply does not matter, because the video was made with the assumption that they look the same.Let's assume someone started out with a legal/valid YUV video. That's (almost) what most cameras shoot. In the extreme case the person intended to tweak it to hell and back for artistic effect, making the two different colours exactly the same, then yes, I agree - that's what they should look like. That person, if they had a clue, would do converttorgb().convertyv12() (with appropriate matrix and clipping - see below) to burn the effect irreversibly onto the video.

But it's far more common for the intended result to be "the original video with greater saturation" or "the original video with a bit more red" or "the original video with more sharpness" or whatever. The intended effect of such moderate changes is never ".... with clipping", or "... with weird colours that are the opposite of the intended effect" (e.g. the brightest parts of the image made darker when the rest is being made brighter / more saturated!).

So if you find a disc authored in such a way, it makes sense to try to fix it, not permanently break it.

If you find that transformations you want to apply to your own footage create this problem, then you're free to clip your own footage to death, or fix the problem, or ignore it.


But if you use Grayscale() on it, those two colours will not look the same.But if that's what you really want - you want to see what the video will look like on a convert-then-clip PC RGB display, you can do that quite easily...
converttorgb(matrix="PC.601").levels(16,1.0,235,16,235).converttoyv12(matrix="PC.601").greyscale()
seems to do the trick.

Cheers,
David.