View Full Version : Gamma settings - in YUV with preservation of saturation
Stormborec
15th March 2019, 23:55
How to set gamma correctly in YUV, without convert to RGB (less rounding errors, without banding)
levels(0,1.32,255,0,255)
tweak(sat...)
dark parts are desaturated, light ones are oversaturated...
The right way but converting to RGB:
converttorgb32
levels(0,1.32,255,0,255)
converttoyv12
or the same:
converttorgb32
RGBAdjust(rg=...,gg =...,bg=...)
converttoyv12
There are 2 ways:
1) convert to "deeper bit" (or float) RGB -> change gamma -> convert back to YUV (slow)
2) make it all "in one step" = stay in YUV:
a) change gamma in luma
b) change "saturation" of chroma "adaptively", in relation to each pixel value of luma (lower luma means higher saturation lost by gamma change)
something like this (but it's still not ok):
y = converttoy8()
u = utoy8()
v = vtoy8()
y_adjusted = mt_lut("x 16 - 219 / 1 1.32 / ^ 219 * 16 +", chroma="copy")
y_scaled = y.bilinearresize(width(u),height(u))
u_adjusted = mt_lutxy(u,y_scaled,"x 128 - y 16 - 219 / 1 1.32 / ^ 219 * 16 + y / * 128 +")
v_adjusted = mt_lutxy(v,y_scaled,"x 128 - y 16 - 219 / 1 1.32 / ^ 219 * 16 + y / * 128 +")
ytouv(u_adjusted,v_adjusted,y_adjusted)
In a nutshell:
We take the gamma adjusted luma value of each pixel and divide it by the original luma value of each pixel.
This gives a coefficient for each pixel to multiply the saturation adjustment according to the gamma change.
The greater the luma change, the greater the saturation lost.
LemMotlow
16th March 2019, 03:22
converttorgb32
RGBAdjust(rg=...,gg =...,bg=...)
converttoyv12
Above is the only example that affects chroma's gamma. The others affect only luma's gamma. gamma_u and gamma_v have no effect -- which is clearly stated in the system documentation for ColorYUV:
gamma adjusts gamma of the specified channel. A value of 0 is the same as gamma 1.0. When the value is set to 256 it is the same as gamma 2.0. The value is valid down to -256, where it is the same as gamma 0.0. Note: gamma for chroma is not implemented (gamma_u and gamma_v are dummy parameters).
So, which gamma are you trying to work with? luma in YUV or chroma in RGB? In YUV, luma and chroma are stored separately. In RGB, "color" and "brightness" are integral.
Stormborec
16th March 2019, 09:47
So, which gamma are you trying to work with? luma in YUV or chroma in RGB?
In YUV (thus without color space conversion) but with the same result like in RGB...
StainlessS
16th March 2019, 11:38
Well I know that you are familiar with ColorYUV2 (as you have posted about it before), but here anyways in case you forgot:- https://forum.doom9.org/showthread.php?t=156774&highlight=colorYUV2
Groucho also has 64 bit build of it, in his stuff.
https://s20.postimg.cc/e05bqbhq5/Coloryuv2_Graf.jpg (https://postimg.cc/image/r4aw309rt/)
Also RgbAdapt has RPow/SPow stuff. https://forum.doom9.org/showthread.php?t=170642&highlight=RgbAdapt
https://s20.postimg.cc/wxyq8spkt/Fishv3_zpsfjmoyerr.jpg (https://postimg.cc/image/yd0axiqnt/)
EDIT: And demo of the iMin, iMax, OMin, OMax stuff (mask creation or whatever) [EDIT: Grid turned off].
https://s20.postimg.cc/xxtmi8u4d/Frog_Min_Max_zpsbb2x9pld.jpg (https://postimg.cc/image/yal0ofce1/)
EDIT: Also, VirtualDub2 has some kind of 6 axis RGB adjustment function thingy.
EDIT:
In YUV (thus without color space conversion) but with the same result like in RGB...
Nobody knows how to do it properley in YUV, Gamma is an RGB concept.
Stormborec
16th March 2019, 12:13
These tools can calculate proper values e.g. from RGBAdjust to ColorYUV ?
StainlessS
16th March 2019, 12:20
Nobody knows how to do it properley in YUV, Gamma is an RGB concept.
SuperLumberjack
4th September 2022, 00:56
Hello,
I don't know if I am on the right topic, but I want to change the input levels of a video (don't ask why please, because you don't want to know :D ), but I would like the exact same result than the VirtualDub filter "levels" with "operate in luma instead of RGB" checked.
Apparently, the AviSynth version only expects to have an RGB source and scales the chroma too, not only the luma with YUV sources (the result is colors that are too saturated).
How can I avoid this with YUV sources please?
Thanks for your help! Sorry, I know that I am an eternal noob :p
lollo2
4th September 2022, 08:50
Not sure if it helps, but http://avisynth.nl/index.php/Ylevels processes only luma
SuperLumberjack
4th September 2022, 11:10
OK. Thank you very much! :)
I will try this.
SuperLumberjack
4th September 2022, 17:35
I don't understand how to use YLevels :o
I donwloaded the MaskTools2 plugin as it's written, but VirtualDub show me this :
Script error: There is no function named 'Ylevels'.
In fact, I'm always a bit lost when there is no DLL for a plugin. I just thought that we can use the "YLevels" function the same way that we use the "Levels" function.
Reel.Deel
4th September 2022, 18:34
Script error: There is no function named 'Ylevels'.
Aside from the required plugin you also need the script. You can either save it as an avsi file and put it in the autoload folder. You can also save it and load it manually with Import("ylevels.avs") or you can copy the entire script and put it in the script you are working in.
SuperLumberjack
4th September 2022, 19:08
OK! Thanks! :)
So this one?
function Ylevels(clip clp, int a, float gamma, int b, int c, int d)
{ wicked="x "+string(a)+" - "+string(b)+" "+string(a)+" - / 1 "+string(gamma)+" / ^ "+string(d)+" "+string(c)+" - * "+string(c)+" +"
# Reminder: Yexpr = "x a - b a - / 1 gamma / ^ d c - * c +"
# return( clp.subtitle(wicked) )
return( clp.YV12LUT(Yexpr = wicked, U=2,V=2) )
}
function YlevelsG(clip clp, int a, float gamma, int b, int c, int d)
{ wicked = gamma > 1.0
\ ? "x "+string(a)+" - "+string(b)+" "+string(a)+" - / 1 "+string(gamma)+" / ^ "+string(d)+" "+string(c)+" - * "+string(c)+" + x * x 255 x - * + 255 /"
\ : "x "+string(a)+" - "+string(b)+" "+string(a)+" - / 1 "+string(gamma)+" / ^ "+string(d)+" "+string(c)+" - * "+string(c)+" + 255 x - * x x * + 255 /"
return( clp.YV12LUT(Yexpr = wicked, U=2,V=2) )
}
function YlevelsS(clip clp, int a, float gamma, int b, int c, int d)
{ wicked="x "+string(a)+" - "+string(b)+" "+string(a)+" - / 1 "+string(gamma)+" / ^ "+string(d)+" "+string(c)+" - * "+string(c)+" + x 162,97466 / sin 255 * * x 255 x 162,97466 / sin 255 * - * + 255 /"
return( clp.YV12LUT(Yexpr = wicked, U=2,V=2) )
}
SuperLumberjack
4th September 2022, 19:22
It's better but I have this now :scared:
Script error: There is no function named 'YV12LUT'.
(C:\Program Files (x86)\AviSynth+\plugins+/YLevels.avsi, line 5)
EDIT : No, it's cool! :) My version of MaskTools was too recent.
Thank you a lot! :p
Reel.Deel
4th September 2022, 19:35
It's better but I have this now :scared:
Script error: There is no function named 'YV12LUT'.
(C:\Program Files (x86)\AviSynth+\plugins+/YLevels.avsi, line 5)
EDIT : No, it's cool! :) My version of MaskTools was too recent.
Thank you a lot! :p
You're using an ancient version of YLevels. Use the script from here: http://avisynth.nl/images/YLevels_mt.avsi. Delete the old Masktools and use the latest version.
Here's a link to the wiki: http://avisynth.nl/index.php/Ylevels
SuperLumberjack
4th September 2022, 20:41
Thank you so much! ;)
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.