Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion. Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules. |
18th July 2004, 18:23 | #1 | Link |
Registered User
Join Date: Apr 2002
Location: Germany
Posts: 5,389
|
Some finger exercises with image levels
Lately, the discussion about the different gamma curves of TV sets and PC monitors came up again. This reminded me of some gamma tricks I'm used to occasionally apply in image processing. And now I even found time set it up in Avisynth
The most-faced problem is: video appears "too dark" on PC monitors. The usual solution is: raise black level, or slope-up the gamma curve. Both make the details in very dark areas better visible - but both create the usual ugly "washed-out" effect at the same time. A more pleasing solution is, to adjust the gamma curve for dark areas more strongly than for bright areas. Functions: (MaskTools.dll is needed. >= v1.5.5 is recommended.) edit 07 dec 2004: all functions updated to latest MaskTools' semantics (currently v1.5.5) Code:
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) ) } Ylevels() is a simple replacement for Avisynth's internal levels() command, with a few neat differences: - processes only luma --> faster, better preservation of color saturation - no clipping: Ylevels(40,1.0,220, 40, 220) will not clip the output to [40,220] as levels() does. Values below 40 / above 220 will be scaled accordingly to the correct vales. This means, one can use any values for IN_LOW, IN_HIGH as "control points" without getting the input clipped at those values. But that's not the deal. YlevelsG() and YlevelsS() apply the given levels conversion by 100% @ Luma==0, by 0% @ Luma=255, and accordingly in-between. YlevelsG() does a linear sweep (G = Gradient) YlevelsS() does a sine sweep (S = yes, exactly ) Try those with gamma values 1.5 ~ 4.0. I suppose some will like them. YlevelsG (not YlevelsS) does "inverse" scaling for gamma values < 1.0, but that's not that great. It's just for completeness. But that's not all, yet. While building the LUT expression for the sine sweep , at one point I accidentially swapped some things, and the result was ... YlevelsC() For this one, 2.0 < gamma < 16.0 is reasonable. No, I won't explain it - just try & enjoy it Code:
function YlevelsC(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)+" + 255 x 162,97466 / cos 255 * - * x x 162,97466 / cos 255 * * + 255 /" return( clp.YV12LUT(Yexpr = wicked, U=2,V=2) ) } If these functions should be used for encoding or not, depends on the source. I would be carefully, at least ... But: These functions are pretty fast! (Manao: thankyouthankyouthank...) - So they can be nicely used in the "Avisynth" section of ffdshow ... Have fun - Didée
__________________
- We´re at the beginning of the end of mankind´s childhood - My little flickr gallery. (Yes indeed, I do have hobbies other than digital video!) Last edited by Didée; 7th December 2004 at 11:53. |
18th July 2004, 20:25 | #3 | Link |
Registered User
Join Date: Apr 2002
Location: Germany
Posts: 5,389
|
I'll post it when it's ready to be posted
- Didée
__________________
- We´re at the beginning of the end of mankind´s childhood - My little flickr gallery. (Yes indeed, I do have hobbies other than digital video!) |
18th July 2004, 20:51 | #4 | Link |
Registered User
Join Date: Feb 2004
Posts: 156
|
Hey Didee, I like YlevelsG very much, except my CRT is kinda old, and the gamma is skewed. I set fddshow's luma offset from 50 to 60 just to watch vids. I even tried YlevelsG and Ylevels together, and I still get real time decoding. Not bad at all. But the full effect of YlevelsG is missed that way. Anyways, I can still use fddshow luma offset and YlevelsG together for a more brilliant picture. I'm about to try Ylevels first then YlevelsG to see if this option works...
There's so many options... hehe |
21st July 2004, 15:23 | #5 | Link |
Guest
Posts: n/a
|
Didée, thank you very much
i'm caming from http://forum.doom9.org/showthread.ph...0&pagenumber=3 (picture too dark with avisynth script thread),i'm testing the results. for who need the link to download masktools: http://jourdan.madism.org/~manao/ |
23rd July 2004, 20:40 | #6 | Link |
Guest
Posts: n/a
|
@ Didée and all :
no luck here, the image still dark and changing the matizes(more green) comparing with the dvd(cartoon) source. anyone had good results? Didée, suggestions or differents adjusts in the scrip? thanks!....i lost my will to encode, we're loosing quality! ...waiting good solutions or hints. |
24th July 2004, 14:05 | #7 | Link |
Registered User
Join Date: Apr 2002
Location: Germany
Posts: 5,389
|
Speaking of above functions, perhaps you'd need it to "bite" more in the darks only. Technically no problem, the distribution can be made at free will.
However, the following is YlevelS() with still careful settings: To my eyes, that's effective. - Didée
__________________
- We´re at the beginning of the end of mankind´s childhood - My little flickr gallery. (Yes indeed, I do have hobbies other than digital video!) |
24th July 2004, 18:03 | #9 | Link |
Registered User
Join Date: Jan 2002
Location: France
Posts: 2,856
|
No, it wouldn't be faster, and it would lose all the tweakability of YV12LUT. Didee's functions are wrappers to make the use of YV12LUT easier in these kind of levels filtering, and for that, avs scripts are perfectly fit.
|
24th July 2004, 19:01 | #11 | Link |
Guest
Posts: n/a
|
thank you boys....i did more tests.
differents results and reasons: from vob in vdubmod: http://img20.exs.cx/img20/6633/a105.jpg using .avs script (source only)from dvd2avi project: http://img20.exs.cx/img20/802/b98.jpg little differences cos here was with xvid decompressor in vdub mod! now here,big differences: from vobs in vdubmod: http://img34.imageshack.us/img34/5236/vobs.jpg using .avs script (source only)from dvd2avi project: http://img39.imageshack.us/img39/7083/pcscale.jpg great differences cos was using ati decompressor in vdubmod(file information). then,(correct me please) the differences in vdub depend of the decompressor used to show the pictures (like in vdub file informations). now my doubt: if i'm using the ati the image is dark,if using xvid "seems" equal ..... what is working when encoding in CCE(D2S)? |
24th July 2004, 19:52 | #12 | Link | |
Registered User
Join Date: Apr 2002
Location: Germany
Posts: 5,389
|
Quote:
What I see here, is: One picture where detail in dark areas is clearly visible, but that suffers from contrast over the full range, making the overall appearance somewhat dull, and one picture where detail in dark areas is clearly visible, and that has good contrast over the full range, making the overall appearance vivid. q.e.d. - Didee [edit] *damnit* Sorry for the misspelling, LigH.
__________________
- We´re at the beginning of the end of mankind´s childhood - My little flickr gallery. (Yes indeed, I do have hobbies other than digital video!) Last edited by Didée; 24th July 2004 at 19:56. |
|
25th July 2004, 12:16 | #13 | Link |
German doom9/Gleitz SuMo
Join Date: Oct 2001
Location: Germany, rural Altmark
Posts: 6,753
|
Well - a little tweaking of the Levels(gamma) and Tweak(sat,cont) parameters may lead to even better results than my default ones. But finally: If your Ylevels or the Levels/Tweak combo are more or less successful, is beyond my ability of recognition. Other people may be more trained in spotting differences.
|
25th July 2004, 18:57 | #14 | Link |
Registered User
Join Date: Apr 2002
Location: Germany
Posts: 5,389
|
It gets clearer with some curves. The following curves are not mathematically exact - they're quickly free-handed, but give the idea.
A plain gamma correction looks like this: We get a strong brightening effect over the full range. But from about 35% of the available range, we start loosing contrast (steepyness of curve gets < 1). Ylevels simply blends the normal gamma curve, weightened with the inverse of the input's brightness. The result is similar to this: By this weightening, the brightening of the dark areas is still achieved. But here, the cost of the additional levels that were assigned to the darks is distributed more equally over the remaining ranges: the curve's steepyness goes only a little below '1', plus the curve's overall deviation from y=x is much smaller. You can tweak your levels().tweak() - combo until you get blue in the face: you'll never get the same effect. Starting with normal levels(), contrast in the upper 65% is lost. Then, you can get it back - if at all, only with loss. Expanding the compressed ranges again will lead to posterization, because actually values got lost during gamma correction - not at all with tweak() - (not really), since its contrast parameter works symetrically to Y=127. Hey, I don't want to sell anything here But the difference is really easy to spot, in my opinion: interleave( levels(...).tweak(...), Ylevels(...) ) Flip this back 'n forth, and don't say you see no difference - Didée
__________________
- We´re at the beginning of the end of mankind´s childhood - My little flickr gallery. (Yes indeed, I do have hobbies other than digital video!) Last edited by Didée; 25th July 2004 at 19:10. |
25th July 2004, 19:24 | #15 | Link |
brainless
Join Date: Mar 2003
Location: Germany
Posts: 3,653
|
hehe, I was using Photoshops curves to build a curve, that improved the image, and then used RGBLut
(the curves mostly seem to be similar to your one)
__________________
Don't forget the 'c'! Don't PM me for technical support, please. |
25th July 2004, 19:52 | #16 | Link |
Registered User
Join Date: Apr 2002
Location: Germany
Posts: 5,389
|
RGBLUT ony a YUV souce ... didn't you get some banding effects in areas of low luma? You're getting gaps through the YUV->RGB conversion (look at the histogram in Photoshop before-after), are spreading these gaps through gamma adjustment, and are left with the gaps after backconversion (again look at the histogram).
I don't pretend this springs to the eye obviously, but generally it's just like that. - Didée
__________________
- We´re at the beginning of the end of mankind´s childhood - My little flickr gallery. (Yes indeed, I do have hobbies other than digital video!) |
7th December 2004, 12:13 | #18 | Link |
Registered User
Join Date: Apr 2002
Location: Germany
Posts: 5,389
|
All Ylevels()-functions updated to the latest MaskTools' semantics (needs to specify "U=2,V=2" to carry the original color planes through).
__________________
- We´re at the beginning of the end of mankind´s childhood - My little flickr gallery. (Yes indeed, I do have hobbies other than digital video!) |
6th November 2006, 05:55 | #19 | Link |
Didée Fan
Join Date: Feb 2006
Location: Canada
Posts: 1,079
|
Didée,
I notified the FFdshow developers that the FFdshow Levels tab uses your code wrong. That it doesn't work as you've shown in this thread. Here's the link: Link I asked them to look at this thread and implement the Levels you made in this thread into FFdshow properly. |
Thread Tools | Search this Thread |
Display Modes | |
|
|