Log in

View Full Version : Boosted Y levels causing posterisation - any advice?


wonkey_monkey
10th December 2009, 19:04
Hi,

My source is a commercial DVD which has a very dark picture, which I've corrected with a gamma correction to the Y channel only (it's also oversaturated, and this helps compensate nicely for that too).

The downside is that this results in large steps in brightness at the black end of the scale. For instance, pixel values go from:

0 -> 0
1 -> 5
2 -> 8
3 -> 11
4 -> 14
5 -> 16

And so on. So I've added some dithering to the plugin I wrote, so an originally black pixel now takes on a random rounded value between roughly 0 and 2.5, a "1" pixel ranges from 2.5 to 6.5, and so on.

This makes the blacks look a lot nicer than they did before I added dithering, but am I just making things harder for a codec by introducing this noise, especially at such a low level where it probably won't be seen by a viewer anyway?

What else could I do to tidy these blacks up before I compress? There are some slight colour variations - would desaturating these very dark blocks be of any help to the codec (which will probably be Xvid).

David

StainlessS
19th December 2009, 06:47
Hi David, Am a liitle confused.

You say:-
0 -> 0
1 -> 5
2 -> 8
3 -> 11
4 -> 14
5 -> 16

Are you saying that the levels are way below the BT 601
lower limit of 16. I think that you need to ConvertToYV12()
if necessary and use "Histogram(mode="levels")"
to view histogram. Scan through the clip looking for
the lowest (prominent) Y level (you can ignore real
dark stuff where there are any kind of CGI eg titles.
Use before Histogram eg:-

ColorYUV(off_y=0,gain_y=0,gamma_y=0,cont_u=0,cont_v=0)

If lowest Y level is less than 16, set off_y to (16 - Low Y),
this is effectively altering the brightness. Using Gamma will
as you say result in posterizing if excessively used. After
doing this, you can alter gain_y until the highest Y levels
reach up to the upper allowable level (marked in the Histogram) at 235.
This will give you maximum (allowable)dynamic range of the
luma. It is possible that at this point the majority seems over
bright, in this case you may need to
set gamma_y to a -ve value, perhaps this is the reason the
clip was dark to begin with, the creators could not alter
gamma or did not know how to. Once happy with Y levels,
then you can alter chroma saturation using the cont_u and
cont_v levels, -ve to decrease saturation, and keep both
identical or it will skew the chroma. Also Note, you cannot
alter the chroma gamma, last time I looked, it is not actually
implemented within the ColorYUV() function, it is taken
as an argument and stored somewhere, but after that, it is
not ever referenced, so it dont work, despite the example
in the Avisynth docs.


EDIT:-
Tried below in Avisynth v2.5

coloryuv(gamma_u=1000,gamma_v=1000).stackhorizontal(a,last)

Dont do anything I can see


Also note, messing with the gamma_y
will also mess with the lower Y level, the low Y level you
have already set will raise if gamma_y raised and vise versa.
I personally hate this gamma_y working relative to zero
instead of lower limit 16, and so modified my own version
of ColorYUV2() so that gamma_y works relative to limit
16, so I dont have to keep messing with the off_y I've already set.

You can remove the ConvertToYV12() after using Histogram.

Hope this helps a little.

By the way, take a look at "23->25 woes Euro Pulldown",
Have used your initial post in that thread to produce a little
bit of code I wrote to convert
23->24, 24->25 and 23->25 FPS.

Be Gud :)

StainlessS
19th December 2009, 07:52
Hi again, as an afterthought, (never tried this).

If you are indeed trying to produce a full range XVID,
it is probably that the DCT blocks are the problem, when
originally rendered, the mpeg renderer deemed that part
of the (dark) vid imperceptable to the human eye and so did
not care too much about "invisible" blocking artifacts,
however, in lightening them, you make them now visible. You
might wanna try clamping everything below the LIGHTEST level
that should be black, to the LIGHTEST black level, after that,
you can then lower to real black and the blocking should not
appear (as prominent) as it did before. Then after this is done,
you can stretch the dynamic range, gamma etc.
Cant remember offhand if Levels() can do this but I suspect
it can.

Just had a look through my filters, there is a filter called
Threshold() that looks like it can squash some of your blocks.
Give it a try.

Be Gud :)