Levels

From Avisynth wiki
(Difference between revisions)
Jump to: navigation, search
m (add cat.)
(clarify, hopefully)
Line 1: Line 1:
 
{{Template:FuncDef|Levels(clip ''input'', int ''input_low'', float ''gamma'', int ''input_high'', int ''output_low'', int ''output_high'' [, bool ''coring''] [, bool ''dither''])}}
 
{{Template:FuncDef|Levels(clip ''input'', int ''input_low'', float ''gamma'', int ''input_high'', int ''output_low'', int ''output_high'' [, bool ''coring''] [, bool ''dither''])}}
  
The Levels filter adjusts brightness, contrast, and gamma. The ''input_low'' and ''input_high'' parameters determine what input pixel values are treated as pure black and pure white; the ''output_low'' and ''output_high'' parameters determine the output values corresponding to black and white; and the gamma parameter controls the degree of nonlinearity in the conversion. To be precise, the conversion function is:
+
The '''Levels''' filter adjusts brightness, contrast, and gamma. The ''input_low'' and ''input_high'' parameters determine what input pixel values are treated as pure black and pure white (; the ''output_low'' and ''output_high'' parameters determine the output values corresponding to black and white (that is, they set the maximum black-to-white range); and the gamma parameter controls the degree of nonlinearity in the conversion. To be precise, the '''transfer function''' (when coring=false) is:
  
:output = [(input - ''input_low'') / (''input_high'' - ''input_low'')]^(1/gamma) * (''output_high'' - ''output_low'') + ''output_low''
+
:<tt>output = ((input-input_low)/(input_high-input_low))^(1/gamma)*(output_high-output_low)+output_low</tt>
  
This is one of those filters for which it would really be nice to have a GUI. Since I can't offer a GUI (though [http://forum.doom9.org/showthread.php?t=153248 AvsP] does), I decided I could 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. However, the input and output parameters can be larger than 255.  
+
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 [http://forum.doom9.org/showthread.php?t=153248 AvsP] does), we at least make this filter '''compatible with [[VirtualDub|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 however, the input and output parameters can be larger than 255.  
  
When processing data in YUV mode, Levels only gamma-corrects the luma information, not the chroma. Gamma correction is really an RGB concept, and I don't know how to do it properly in YUV. However, if gamma = 1.0, the filter should have the same effect in RGB and YUV modes. For adjusting brightness or contrast it is better to use [[Tweak]] or [[ColorYUV]], because Levels also changes the chroma of the clip.
+
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'', the filter should have the same effect in RGB and YUV modes. For adjusting brightness or contrast 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.
  
In v2.53 an optional coring = true/false (true by default, which reflects the behaviour in older versions) is added.
+
;input_low
 +
:higher values darken the output; the darkest tones are ''clipped'', that is, they are lost.
  
''coring'' = true/false (true by default): When set to true: input luma is clamped to [16,235] (and the chroma to [16,240]), this result is *scaled* from [16,235] to [0,255], the conversion takes place according to the formula above, and output is *scaled* back from [0,255] to [16,235]. When set to false, the conversion takes place according to the formula above.
+
;gamma
 +
:values larger than 1.0 brighten the middle tones; values smaller than 1.0 darken them.
  
''dither'' = true/false (false by default): When set to true, [[ordered dithering]] is applied when doing the adjustment.
+
;input_high
 +
:lower values brighten the output and the brightest values are clipped.
  
'''Examples:'''
+
;output_low
 +
:dark tones brighten to gray as ''output_low'' becomes larger.
 +
 
 +
;output_high
 +
:light tones darken to gray as ''output_high'' becomes smaller.
 +
 
 +
;coring
 +
:when ''true'' (the default), input luma is ''clamped'' to [16,235] and the chroma to [16,240]; this clamped input is scaled from [16,235] to [0,255], the conversion takes place according to the transfer function above, and then output is scaled back from [0,255] to [16,235]. When ''false'', the conversion takes place according to the transfer function, without any scaling.
 +
<blockquote>''Coring'' was created for VirtualDub compatibility, and it it remains true by default for compatibility with scripts written for AviSynth prior to version 2.53. In the opinion of some, you should [http://forum.doom9.org/showthread.php?p=1722885#post1722885 always use ''coring=false''.] if you are working directly with luma values (whether or not your input is [16,235]).</blockquote>
 +
 
 +
;dither
 +
:when ''true'', [[ordered dithering]] is applied to combat [http://en.wikipedia.org/wiki/Colour_banding banding]. Default is ''false''.
 +
 
 +
===== Examples:=====
  
 
  # does nothing on a [16,235] clip, but it clamps (or rounds) a [0,255] clip to [16,235]:
 
  # does nothing on a [16,235] clip, but it clamps (or rounds) a [0,255] clip to [16,235]:
Line 47: Line 63:
 
{|border=1 cellspacing=1 cellpadding=4
 
{|border=1 cellspacing=1 cellpadding=4
 
  | v2.53
 
  | v2.53
  | added coring
+
  | added coring (true by default, which reflects the behaviour in older versions)
 
  |-
 
  |-
 
  | v2.60
 
  | v2.60

Revision as of 23:13, 15 September 2015

Levels(clip input, int input_low, float gamma, int input_high, int output_low, int output_high [, bool coring] [, bool dither])

The Levels filter adjusts brightness, contrast, and gamma. The input_low and input_high parameters determine what input pixel values are treated as pure black and pure white (; the output_low and output_high parameters determine the output values corresponding to black and white (that is, they set the maximum black-to-white range); and the gamma parameter controls the degree of nonlinearity in the conversion. To be precise, the transfer function (when coring=false) is:

output = ((input-input_low)/(input_high-input_low))^(1/gamma)*(output_high-output_low)+output_low

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 AvsP 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 however, the input and output parameters can be larger than 255.

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, the filter should have the same effect in RGB and YUV modes. For adjusting brightness or contrast 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.

input_low
higher values darken the output; the darkest tones are clipped, that is, they are lost.
gamma
values larger than 1.0 brighten the middle tones; values smaller than 1.0 darken them.
input_high
lower values brighten the output and the brightest values are clipped.
output_low
dark tones brighten to gray as output_low becomes larger.
output_high
light tones darken to gray as output_high becomes smaller.
coring
when true (the default), input luma is clamped to [16,235] and the chroma to [16,240]; this clamped input is scaled from [16,235] to [0,255], the conversion takes place according to the transfer function above, and then output is scaled back from [0,255] to [16,235]. When false, the conversion takes place according to the transfer function, without any scaling.
Coring was created for VirtualDub compatibility, and it it remains true by default for compatibility with scripts written for AviSynth prior to version 2.53. 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 [16,235]).
dither
when true, ordered dithering is applied to combat banding. Default is 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)

Changes

v2.53 added coring (true by default, which reflects the behaviour in older versions)
v2.60 added dither
Personal tools