Levels¶
Adjusts brightness, contrast, and gamma. This is done using the following transfer function:
input_low
andinput_high
determine what input pixel values are treated as pure black and pure white.output_low
andoutput_high
determine what output values are treated as pure black and pure white.gamma
controls the degree of non-linearity in the conversion.
This is one of those filters for which it would really be nice to have a GUI. Since we can't offer a GUI (though AvsPmod does), we at least make this filter compatible with VirtualDub's when the clip is RGB. In that case you should be able to take the numbers from VirtualDub's Levels dialog and pass them as parameters to the Levels filter and get the same results. Unlike VirtualDub's filter however, the input and output parameters can be larger than the maximum value of the pixel format (for example, in 8-bit it can be greater than 255, see table below).
When processing data in YUV mode, Levels only gamma-corrects the luma
information, not the chroma. Gamma correction is really an RGB concept, and is
only approximated here in YUV. If gamma=1.0
(unity), the filter should have
the same effect in both RGB and YUV modes. For adjusting brightness or contrast
in YUV mode, it may be better (depending on the effect you are looking for) to
use Tweak or ColorYUV, because Levels changes the chroma of
the clip.
Note in AviSynth+, the parameters input_low
, input_high
, output_low
and output_high
:
are float instead of int.
are not autoscaling – they are relative to the current bit depth:
Bits
Min.
Max.
8
0
16
128
235
255
10
0
64
512
940
1023
12
0
256
2048
3760
4095
14
0
1024
8192
15040
16383
16
0
4096
32768
60160
65535
32
0
16/255
128/255
235/255
1.0
Syntax and Parameters¶
Levels (clip input, float input_low, float gamma, float input_high, float output_low, float output_high,
bool "coring", bool "dither")
- clip
Source clip; all color formats supported.
- input_low
- Input values at
input_low
or lower are treated as black, and lighter colors are darkened proportionally.Therefore, raisinginput_low
darkens the output.
- gamma
- input_high
- Input values at
input_high
or higher are treated as white, and darker colors are brightened proportionally.Therefore, loweringinput_high
brightens the output.
- output_low
Dark values brighten to gray as
output_low
becomes larger.
- output_high
Light values darken to gray as
output_high
becomes smaller.
- coring
For RGB this parameter is ignored and internally set to false. For Y and YUV, when true (default),
input clip is clamped to limited range (e.g. in 8-bit, 16-235 for luma and 16-240 for chroma);
this clamped input is scaled from limited range back to full range,
the conversion takes place according to the transfer function above, and then
output is scaled back to limited range.
When false, the conversion takes place according to the transfer function, without any scaling.
Note
coring
was created for VirtualDub compatibility, and it remains true by default for compatibility with older scripts.In the opinion of some, you should always use coring=false if you are working directly with luma values (whether or not your input is limited range).
Limited range video can be correctly processed with
coring=false
; for example:Levels(0, 1.6, 255, 0, 255, coring=true)
Produces the same result as:
Levels(16, 1.6, 235, 16, 235, coring=false)
Except that the output is not clipped to limited range. Black and white levels are preserved while adjusting
gamma
, unlike:Levels(0, 1.6, 255, 0, 255, coring=false)
- dither
When true, ordered dithering is applied to combat banding.
Default: false
Examples¶
# does nothing on a [16,235] clip, but it clamps (or rounds) a [0,255] clip to [16,235]:
Levels(0, 1, 255, 0, 255)
# the input is scaled from [16,235] to [0,255],
# the conversion [0,255]->[16,235] takes place (accordingly to the formula),
# and the output is scaled back from [0,255] to [16,235]:
# (for example: the luma values in [0,16] are all converted to 30)
Levels(0, 1, 255, 16, 235)
# gamma-correct image for display in a brighter environment:
# example: luma of 16 stays 16, 59 is converted to 79, etc.
Levels(0, 1.3, 255, 0, 255)
# invert the image (make a photo-negative):
# example: luma of 16 is converted to 235
Levels(0, 1, 255, 255, 0)
# does nothing on a [0,255] clip; does nothing on a [16,235]:
Levels(0, 1, 255, 0, 255, coring=false)
# scales a [0,255] clip to [16,235]:
Levels(0, 1, 255, 16, 235, coring=false)
# note both luma and chroma components are scaled by the same
# amount, so it's not exactly the same as ColorYUV(levels="PC->TV")
# scales a [16,235] clip to [0,255]:
Levels(16, 1, 235, 0, 255, coring=false)
# note both luma and chroma components are scaled by the same
# amount, so it's not exactly the same as ColorYUV(levels="TV->PC")
# makes a clip 100% black
Levels(0, 1.0, 255, 0, 0)
# apply fading on gamma corrected source (same holds for resizing and smoothing)
clip = ...
gamma = 2.2
clip.Levels(0, gamma, 255, 0, 255) # undo gamma (also called gamma correction)
FadeOut(n)
Levels(0, 1.0/gamma, 255, 0, 255) # redo gamma
## use bit depth >= 10 to avoid banding in dark areas
Changelog¶
Version |
Changes |
---|---|
AviSynth+ r2542 |
Added 32 bit float support. |
AviSynth+ r2487 |
Added 10-16 bit support for YUV(A) and planar RGB(A) formats.
Added support for RGB48/64 formats.
|
AviSynth 2.6.0 |
Added
dither parameter.Added support for Y8, YV16, YV24 and YV411 formats.
|
AviSynth 2.5.3 |
Added |
$Date: 2022/04/17 08:19:32 $