Tweak

From Avisynth wiki
(Difference between revisions)
Jump to: navigation, search
(experiment - definition list for args)
(add link to avs+ documentation)
 
(14 intermediate revisions by 2 users not shown)
Line 1: Line 1:
{{Template:FuncDef|Tweak(clip ''clip'' [, float ''hue''] [, float ''sat''] [, float ''bright''] [, float ''cont''] [, bool ''coring''] [, bool ''sse''] [, float ''startHue''] [, float ''endHue''] [, float ''maxSat''] [, float ''minSat''] [, float ''interp''] [, bool ''dither''])}}
+
<div style="max-width:82em; min-width:42em;" >
 +
{{AvsStarFilter}}<div style="max-width:62em" >
  
This filter provides the means to adjust the ''hue'', ''saturation'', ''brightness'', and ''contrast'' of a video clip. In v2.60, both the saturation and hue can be adjusted for saturations in the range [''minSat'', ''maxSat''] and hues in the range [''startHue'', ''endHue''].  
+
<div {{BlueBox2|40|0|3px solid purple}} >
 +
{{AvsPlusFullname}}<br>
 +
Up-to-date documentation: [https://avisynthplus.readthedocs.io/en/latest/avisynthdoc/corefilters/tweak.html https://avisynthplus.readthedocs.io]
 +
</div>
  
;hue
 
: Adjust the color hue of the image. Positive values shift the image towards red. Negative values shift it towards green. (-180.0 to +180.0, default 0.0)
 
  
;sat
+
Adjust hue, saturation, brightness, and contrast of a video clip.  
: Adjust the color saturation of the image. Values above 1.0 increase the saturation. Values below 1.0 reduce the saturation. Use sat=0 to convert to [[GreyScale]]. (0.0 to 10.0, default 1.0)
+
  
;bright
+
In v2.60, both the saturation and hue can be adjusted for range of saturation from {{FuncArg|minSat}} to {{FuncArg|maxSat}} and a range of hue from {{FuncArg|startHue}} to {{FuncArg|endHue}}.  
: Change the brightness of the image. Positive values increase the brightness (the clip gets brighter). Negative values decrease the brightness (the clip gets darker). If the clip is too dark or too bright you can use this setting to correct it. (-255.0 to 255.0, default 0.0)
+
</div>
  
;cont
+
{{AvsPluscon}} adds new [[#realcalc|{{FuncArg|realcalc}}]] and [[#dstrength|{{FuncArg|dither_strength}}]] parameters. <br>
: Change the contrast of the image. Values above 1.0 increase the contrast (the luma range will be stretched). Values below 1.0 decrease the contrast (the luma range will be contracted). If details can't be seen in dark or bright areas, you can increase the contrast to make those details more visible. (0.0 to 10.0, default 1.0)
+
{{AvsPluscon}} all parameters are [[Autoscale_parameter|autoscaling]] &ndash; they work without changes at all bit depths.
  
;coring
+
__TOC__
: When true (the default), the luma (Y) is clipped to [16,235] and the chroma (U, V) is clipped to [16,240]; when set to false, the luma and chroma are unconstrained. [Added in v2.53].
+
== Syntax and Parameters ==
 +
<div style="max-width:62em" >
 +
{{Template:FuncDef
 +
|Tweak( clip ''clip'' [, <br>
 +
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;float ''hue'', float ''sat'', float ''bright'', float ''cont'', <br>
 +
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bool ''coring'', bool ''sse'', float ''startHue'', float ''endHue'', <br>
 +
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;float ''maxSat'', float ''minSat'', float ''interp'', bool ''dither'' ] )
 +
}}
  
;sse
+
{{Template:FuncDef
: Only available for YUY2 with coring=false and only using the standard ''hue'', ''sat'', ''bright'' and ''cont'' options. It re-enables the SSE code if required. (default false)
+
|Tweak( clip ''clip'' [, <br>
 +
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;float ''hue'', float ''sat'', float ''bright'', float ''cont'', <br>
 +
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bool ''coring'', bool ''sse'', float ''startHue'', float ''endHue'', <br>
 +
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;float ''maxSat'', float ''minSat'', float ''interp'', bool ''dither'', <br>
 +
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bool ''realcalc'', float ''dither_strength'' ] ) {{AvsPluscon}}
 +
}}
  
;startHue, endHue
+
:{{Par2| |clip| |}}
: The hue and saturation will be adjusted for values in the range [''startHue'', ''endHue''] when startHue<endHue. Note that the hue is periodic, thus a hue of 360 degrees corresponds with a hue of zero degrees. If endHue<startHue then the range [''endHue'', 360] and [0, ''startHue''] will be selected (thus anti-clockwise). If you need to select a range of [350, 370] for example, you need to specify startHue=350 and endHue=10, (370-360). Thus when using the default values all pixels will be processed. (both from 0 to 360, given in degrees; default 0, 360)
+
::Input clip. [[YUV]] data only (no [[RGB]]).
  
:As a guide, the following table shows approximate ''startHue'' and ''endHue'' values for the basic colors:
+
:{{Par2|hue|float|0.0}}
 +
::Adjust the color hue of the image.
 +
::* {{FuncArg|hue}}>0.0 shifts the image towards red.
 +
::* {{FuncArg|hue}}<0.0 shifts the image towards green.
 +
::Range -180.0 to +180.0, default 0.0
 +
 
 +
:{{Par2|sat|float|0.0}}
 +
::Adjust the color saturation of the image by controlling gain of the color channels.
 +
::* {{FuncArg|sat}}>1.0 increases the saturation.
 +
::* {{FuncArg|sat}}<1.0 reduces the saturation.
 +
::Use sat=0 to convert to [[GreyScale]].
 +
::Range 0.0 to 10.0, default 1.0
 +
 
 +
:{{Par2|bright|float|0.0}}
 +
::Change the brightness of the image by applying a constant bias to the luma channel.
 +
::*{{FuncArg|bright}}>0.0 increases the brightness.
 +
::*{{FuncArg|bright}}<0.0 decreases the brightness.
 +
:: Range -255.0 to 255.0, default 0.0
 +
 
 +
:{{Par2|cont|float|1.0}}
 +
::Change the contrast of the image by multiplying the luma values by a constant.
 +
::*{{FuncArg|cont}}>1.0 increase the contrast (the luma range will be stretched).
 +
::*{{FuncArg|cont}}<1.0 decrease the contrast (the luma range will be contracted).
 +
::Range 0.0 to 10.0, default 1.0
 +
 
 +
:{{Par2|coring|bool|true}}
 +
::When set to true (the default), the luma (Y) and chroma are clipped to TV-range;
 +
::When set to false, the luma and chroma are unconstrained.
 +
 
 +
:{{Par2|sse|bool|false}}
 +
::Only available for [[YUY2]] with {{FuncArg|coring}}=false and with the default {{FuncArg|hue}}, {{FuncArg|sat}}, {{FuncArg|bright}} and {{FuncArg|cont}} options.
 +
::It re-enables the SSE code if required. (default false)
 +
 
 +
:{{Par2|startHue|float|0.0}}
 +
:{{Par2|endHue|float|360.0}}
 +
::The hue and saturation will be adjusted for image values in the range [{{FuncArg|startHue}}, {{FuncArg|endHue}}] when {{FuncArg|startHue}}<{{FuncArg|endHue}}. Note that the hue is periodic, thus a hue of 360 degrees corresponds with a hue of zero degrees.
 +
 
 +
::Range 0 to 360, given in degrees. Default 0, 360 (all hues).
 +
 
 +
::The following shows some arbitrary {{FuncArg|startHue}} and {{FuncArg|endHue}} values for the basic colors, with a [[Histogram#Color2_mode|Histogram vectorscope]] to illustrate the color circle:
 
::{| class="wikitable" border="1" style="text-align:center"
 
::{| class="wikitable" border="1" style="text-align:center"
  !style="width:6em" | Color  
+
  |style="width:6em" | '''Color'''
  !style="width:6em" | startHue  
+
  |style="width:6em" | '''startHue'''
  !style="width:6em" | endHue
+
  |style="width:6em" | (center)
 +
|style="width:6em" | '''endHue'''
 +
|rowspan="7"| [[File:Labeled-vector-color2.png|right]]
 
  |-
 
  |-
 
  |style="text-align:left" | Red  
 
  |style="text-align:left" | Red  
 
  |style="background:#D926B9; color: #EEEEEE" | 075
 
  |style="background:#D926B9; color: #EEEEEE" | 075
 +
|style="background:#D90000; color: #EEEEEE" | 102
 
  |style="background:#D93B26; color: #EEEEEE" | 115
 
  |style="background:#D93B26; color: #EEEEEE" | 115
 
  |-
 
  |-
 
  |style="text-align:left" | Yellow  
 
  |style="text-align:left" | Yellow  
 
  |style="background:#D99D26; color: #121212" | 150
 
  |style="background:#D99D26; color: #121212" | 150
  |style="background:#D5D926; color: #121212" | 172
+
|style="background:#D9D900; color: #121212" | 176
 +
  |style="background:#D5D926; color: #121212" | 180
 
  |-
 
  |-
 
  |style="text-align:left" | Green  
 
  |style="text-align:left" | Green  
 
  |style="background:#9DD926; color: #121212" | 191  
 
  |style="background:#9DD926; color: #121212" | 191  
 +
|style="background:#00D900; color: #121212" | 230
 
  |style="background:#26D97A; color: #121212" | 258
 
  |style="background:#26D97A; color: #121212" | 258
 
  |-
 
  |-
 
  |style="text-align:left" | Cyan  
 
  |style="text-align:left" | Cyan  
  |style="background:#26D9B9; color: #EEEEEE" | 279  
+
  |style="background:#26D9B9; color: #121212" | 279  
  |style="background:#26B2D9; color: #EEEEEE" | 300
+
|style="background:#00D9D9; color: #121212" | 282
 +
  |style="background:#26B2D9; color: #121212" | 300
 
  |-
 
  |-
 
  |style="text-align:left" | Blue  
 
  |style="text-align:left" | Blue  
 
  |style="background:#2688D9; color: #EEEEEE" | 316  
 
  |style="background:#2688D9; color: #EEEEEE" | 316  
 +
|style="background:#0000D9; color: #EEEEEE" | 000
 
  |style="background:#5026D9; color: #EEEEEE" | 004
 
  |style="background:#5026D9; color: #EEEEEE" | 004
 
  |-
 
  |-
 
  |style="text-align:left" | Magenta  
 
  |style="text-align:left" | Magenta  
 
  |style="background:#9626D9; color: #EEEEEE" | 028
 
  |style="background:#9626D9; color: #EEEEEE" | 028
 +
|style="background:#D900D9; color: #EEEEEE" | 048
 
  |style="background:#D526D5; color: #EEEEEE" | 052
 
  |style="background:#D526D5; color: #EEEEEE" | 052
 
  |}
 
  |}
 +
::If {{FuncArg|endHue}}<{{FuncArg|startHue}} then the range [{{FuncArg|endHue}}, 360] and [0, {{FuncArg|startHue}}] will be selected (thus anti-clockwise). If you need to select a range of [350, 370] for example, you need to specify {{FuncArg|startHue}}=350 and {{FuncArg|endHue}}=10, (370-360). Thus when using the default values, all pixels will be processed.
  
;maxSat, minSat
+
:{{Par2|maxSat|float|150.0}}
: The hue and saturation will be adjusted for values in the range [''minSat'', ''maxSat'']. Practically the percentage saturation of a pixel will be in the range [0,100], since these correspond to valid RGB pixels (100% corresponds to R=255, G=B=0, which has a saturation of 119 in units of chroma). An overshoot (up to 150%) is allowed for non-valid RGB pixels (150% corresponds to U=V=255, which has a saturation of sqrt(127^2+127^2) = 180). Thus when using the default values all pixels will be processed. (both from 0 to 150 with minSat<maxSat, given in percentages; default 150, 0)
+
:{{Par2|minSat|float|0.0}}
 +
::The hue and saturation will be adjusted for image values in the range [{{FuncArg|minSat}}, {{FuncArg|maxSat}}].  
  
;interp
+
::Practically  speaking, the percentage saturation of a pixel will be in the range [0, 100], since these correspond to valid RGB pixels (100% corresponds to R=255{{D}}, G=B=0{{D}}, which has a saturation of 119 in units of chroma). An overshoot (up to 150%) is allowed for non-valid RGB pixels (150% corresponds to U=V=255{{D}}, which has a saturation of √(127<sup>2</sup>+127<sup>2</sup>) = 180). Thus when using the default values all pixels will be processed.
: Interpolate the saturation adjustment at the edges of the chosen range to prevent banding. The adjustment is interpolated between 1.0 and ''sat'' in the range [''minS''-''interp'', ''minS''] and between ''sat'' and 1.0 in [''maxS'', ''maxS''+''interp''], where ''minS'' and ''maxS'' are the equivalents of ''minSat'' and ''maxSat'' in chroma units (100% = 119 units). There is no interpolation for interp=0, which can be useful when a clip consists of uniform colors and you want a hard cutoff. The interpolation is linear. (0 to 32, default 16; given in units of chroma, rather than a percentage)
+
  
;dither
+
::Range 0 to 150; default 150, 0; {{FuncArg|minSat}} must be less than {{FuncArg|maxSat}}
: When true, [[ordered dithering]] is applied when doing the adjustment. (default false)
+
  
 +
:{{Par2|interp|float|16.0}}
 +
::Interpolate the saturation adjustment at the edges of the chosen range to prevent banding.
  
----
+
::The adjustment is interpolated between 1.0 and {{FuncArg|sat}} in the range [''minS''-{{FuncArg|interp}}, ''minS''] and between {{FuncArg|sat}} and 1.0 in [''maxS'', ''maxS''+{{FuncArg|interp}}], where ''minS'' and ''maxS'' are the equivalents of {{FuncArg|minSat}} and {{FuncArg|maxSat}} in chroma units (100% = 119 units). There is no interpolation for interp=0, which can be useful when a clip consists of uniform colors and you want a hard cutoff. The interpolation is linear. (0 to 32, default 16; given in units of chroma, rather than a percentage)
=== Usage and examples: adjusting contrast and brightness ===
+
 
 +
:{{Par2|dither|bool|false}}
 +
::When true, [[ordered dithering]] is applied when doing the adjustment. (default false)
 +
 
 +
{{HiddenAnchor|realcalc}}
 +
:{{Par2|realcalc|bool|false}}
 +
::{{AvsPluscon}} When true, force 'no-lookup': pure float calculation of new pixel values (always true for certain {{Deep_color}} formats) ([[TODO]] - clarify)
 +
 
 +
{{HiddenAnchor|dstrength}}
 +
:{{Par2|dither_strength|float|1.0}}
 +
::{{AvsPluscon}} Control dithering amount.
 +
::For example, {{FuncArg|dither_strength}}=1.0 adds ±0.5 amplitude dither on the 0..255 range, and scaled in proportion for other ranges. ([[TODO]] - confirm)
 +
</div>
 +
 
 +
 
 +
== Examples ==
 +
<div style="max-width:62em" >
 +
==== Adjusting contrast and brightness ====
  
 
{|border=1 cellspacing=1 cellpadding=4
 
{|border=1 cellspacing=1 cellpadding=4
Line 73: Line 152:
 
| original  
 
| original  
 
|}
 
|}
 +
  
 
There are two problems with this picture. It is too dark, and the contrast is too small (the details of the tree are not visible for example). First, we will higher the brightness to make the picture less dark (left picture below). Second, we will higher the contrast to make details in the dark areas more visible (right picture below). Make sure that the bright parts don't get too bright though.
 
There are two problems with this picture. It is too dark, and the contrast is too small (the details of the tree are not visible for example). First, we will higher the brightness to make the picture less dark (left picture below). Second, we will higher the contrast to make details in the dark areas more visible (right picture below). Make sure that the bright parts don't get too bright though.
Line 84: Line 164:
 
|}
 
|}
  
=== Usage and examples: adjusting saturation ===
+
 
 +
==== Adjusting saturation ====
  
 
{|border=1 cellspacing=1 cellpadding=4
 
{|border=1 cellspacing=1 cellpadding=4
Line 93: Line 174:
 
| sat=0.75  
 
| sat=0.75  
 
|}
 
|}
 +
  
 
Suppose we want to lower the saturation of the skin of the girl, and the background should be left intact. The proper way to do this is to set sat=0, and lower the hue range till you found the correct hue range which should be processed. This can be done by using a Vectorscope, but also manually. (If it is needed the saturation range can also be specified if the dark and white parts of that hue should not be processed.) The result is below.
 
Suppose we want to lower the saturation of the skin of the girl, and the background should be left intact. The proper way to do this is to set sat=0, and lower the hue range till you found the correct hue range which should be processed. This can be done by using a Vectorscope, but also manually. (If it is needed the saturation range can also be specified if the dark and white parts of that hue should not be processed.) The result is below.
Line 103: Line 185:
 
| sat=0.75, startHue=105, endHue=138
 
| sat=0.75, startHue=105, endHue=138
 
|}
 
|}
 +
  
 
Instead, we can also try to "select" the skin of the girl by narrowing the saturation range only. The result is below. In this case the result is pretty much identical.
 
Instead, we can also try to "select" the skin of the girl by narrowing the saturation range only. The result is below. In this case the result is pretty much identical.
Line 114: Line 197:
 
|}
 
|}
  
=== Usage: YUV to YIQ conversion ===
 
  
The NTSC analog television system used the YUV color space with its axes rotated by 33 degrees, a color space called [http://en.wikipedia.org/wiki/YIQ YIQ].
+
==== YUV to YIQ conversion ====
In YIQ, orange and teal are along the in-phase (I) axis, while green and magenta are along the quadrature (Q) axis.
+
The eye is far more sensitive to detail along the I axis than along the Q axis, and NTSC traditionally used more bandwidth for I than for Q.
+
  
The Tweak filter can be used to convert YUV to YIQ, where the V axis represents I and U represents Q.
+
The NTSC analog television system used the [[YUV]] color space with the UV axes exchanged and rotated by minus 33 degrees. See [http://www.poynton.com/notes/colour_and_gamma/ColorFAQ.html#RTFToC33 Colour FAQ of Charles Poynton]. Note he gives the reverse transformation (from YIQ to YUV).
The following example, based on an example at [[Swap]], converts a YUV clip to YIQ, blanks the Q channel, and converts back to YUV.
+
This produces the "orange and teal" color scheme that [http://tvtropes.org/pmwiki/pmwiki.php/Main/OrangeBlueContrast became a cliché].
+
<pre>
+
# AviSource() etc. goes above here
+
  
yiqclip = Tweak(hue=33) # at this point v and u represent i and q
+
with its axes rotated by 33 degrees, a color space called [[Wikipedia:YIQ|YIQ]].
u_chroma = BlankClip(UToY(yiqclip),color=$808080)
+
In YIQ, orange and teal are along the in-phase (''I'') axis, while green and magenta are along the quadrature (''Q'') axis.
YToUV(u_chroma, yiqclip.VToY)
+
The eye is far more sensitive to detail along the ''I'' axis than along the ''Q'' axis, and NTSC allocated more bandwidth for ''I'' than for ''Q''.
MergeLuma(yiqclip)
+
Tweak(hue=-33)  # convert back to yuv
+
AudioDub(yiqclip)
+
</pre>
+
  
 +
The Tweak filter can be used to convert YUV to YIQ, where the ''U'' axis represents ''I'' and ''V'' represents ''Q''.
 +
The following example, based on an example at [[Swap]], converts a YUV clip to YIQ, blanks the ''Q'' channel, and converts back to YUV. This produces the "orange and teal" color scheme that [http://tvtropes.org/pmwiki/pmwiki.php/Main/OrangeBlueContrast became a cliché].
 +
<div {{BoxWidthIndent|48|1}} >
 +
Function YUVtoYIQ(clip clip)
 +
{
 +
    YtoUV(clip.VtoY(), clip.UtoY(), clip) # swap U and V
 +
    Tweak(hue=-33)
 +
    # Now: U corresponds to I, V corresponds to Q
 +
    # could also have used: FlipHorizontal(clip).Tweak(hue=57)
 +
    # (see [http://forum.videohelp.com/threads/377237-Purple-green-VHS?p=2435970&viewfull=1#post2435970 forum.videohelp.com])
 +
}
 +
 +
Function YIQtoYUV(clip clip)
 +
{
 +
    clip.Tweak(hue=33)
 +
    YtoUV(VtoY(), UtoY(), last) # swap U and V
 +
}
 +
 +
clip = [[AviSource]](...)
 +
yiqclip = YUVtoYIQ(clip)  # convert to YIQ
 +
v_chroma = [[BlankClip]]([[VToY]](yiqclip), color=$808080)
 +
[[YToUV]](yiqclip.[[UToY]], v_chroma, yiqclip)
 +
YIQtoYUV()  # convert back to YUV
 +
[[AudioDub]](yiqclip)
 +
</div>
 +
This allows processing the ''I'' and ''Q'' signals separately.
 +
</div>
  
This allows processing the I and Q signals separately
+
== Developer notes ==
 +
AviSynth uses the following definitions for hue and saturation:<br>
 +
As can be seen in the first image above, hue is the angle between the positive V-axis of the chroma plane and the point given by the centralised coordinates (V,U) on it. The saturation is the amplitude of the centralised chroma plane. Mathematically:
 +
* hue = 180/{{Serif|π}} * [https://en.wikipedia.org/wiki/Atan2 atan2]((V-128)/128, (U-128)/128)
 +
* sat = √((U-128)<sup>2</sup> + (V-128)<sup>2</sup>)
  
'''Changes'''
+
 
 +
== Changes ==
 +
<div style="max-width:62em" >
 
{|border=1 cellspacing=1 cellpadding=4
 
{|border=1 cellspacing=1 cellpadding=4
|-
+
|-
| v2.58
+
| v2.58
| Added startHue, endHue, maxSat, minSat and interp.
+
| Added startHue, endHue, maxSat, minSat and interp.
|-
+
|-
| v2.60
+
| v2.60
| Added dither.
+
| Added dither.
|}
+
|}
 +
</div>
 +
</div>
  
 
[[Category:Internal filters]]
 
[[Category:Internal filters]]
 
[[Category:Levels and Chroma filters]]
 
[[Category:Levels and Chroma filters]]
[[Category:Chroma correction]]
 

Latest revision as of 08:40, 17 September 2022

AviSynth+
Up-to-date documentation: https://avisynthplus.readthedocs.io


Adjust hue, saturation, brightness, and contrast of a video clip.

In v2.60, both the saturation and hue can be adjusted for range of saturation from minSat to maxSat and a range of hue from startHue to endHue.

AVS+ adds new realcalc and dither_strength parameters.
AVS+ all parameters are autoscaling – they work without changes at all bit depths.

Contents

[edit] Syntax and Parameters

Tweak( clip clip [,
     float hue, float sat, float bright, float cont,
     bool coring, bool sse, float startHue, float endHue,
     float maxSat, float minSat, float interp, bool dither ] )

Tweak( clip clip [,
     float hue, float sat, float bright, float cont,
     bool coring, bool sse, float startHue, float endHue,
     float maxSat, float minSat, float interp, bool dither,
     bool realcalc, float dither_strength ] ) AVS+

clip   =
Input clip. YUV data only (no RGB).
float  hue = 0.0
Adjust the color hue of the image.
  • hue>0.0 shifts the image towards red.
  • hue<0.0 shifts the image towards green.
Range -180.0 to +180.0, default 0.0
float  sat = 0.0
Adjust the color saturation of the image by controlling gain of the color channels.
  • sat>1.0 increases the saturation.
  • sat<1.0 reduces the saturation.
Use sat=0 to convert to GreyScale.
Range 0.0 to 10.0, default 1.0
float  bright = 0.0
Change the brightness of the image by applying a constant bias to the luma channel.
  • bright>0.0 increases the brightness.
  • bright<0.0 decreases the brightness.
Range -255.0 to 255.0, default 0.0
float  cont = 1.0
Change the contrast of the image by multiplying the luma values by a constant.
  • cont>1.0 increase the contrast (the luma range will be stretched).
  • cont<1.0 decrease the contrast (the luma range will be contracted).
Range 0.0 to 10.0, default 1.0
bool  coring = true
When set to true (the default), the luma (Y) and chroma are clipped to TV-range;
When set to false, the luma and chroma are unconstrained.
bool  sse = false
Only available for YUY2 with coring=false and with the default hue, sat, bright and cont options.
It re-enables the SSE code if required. (default false)
float  startHue = 0.0
float  endHue = 360.0
The hue and saturation will be adjusted for image values in the range [startHue, endHue] when startHue<endHue. Note that the hue is periodic, thus a hue of 360 degrees corresponds with a hue of zero degrees.
Range 0 to 360, given in degrees. Default 0, 360 (all hues).
The following shows some arbitrary startHue and endHue values for the basic colors, with a Histogram vectorscope to illustrate the color circle:
Color startHue (center) endHue
Labeled-vector-color2.png
Red 075 102 115
Yellow 150 176 180
Green 191 230 258
Cyan 279 282 300
Blue 316 000 004
Magenta 028 048 052
If endHue<startHue then the range [endHue, 360] and [0, startHue] will be selected (thus anti-clockwise). If you need to select a range of [350, 370] for example, you need to specify startHue=350 and endHue=10, (370-360). Thus when using the default values, all pixels will be processed.
float  maxSat = 150.0
float  minSat = 0.0
The hue and saturation will be adjusted for image values in the range [minSat, maxSat].
Practically speaking, the percentage saturation of a pixel will be in the range [0, 100], since these correspond to valid RGB pixels (100% corresponds to R=255d, G=B=0d, which has a saturation of 119 in units of chroma). An overshoot (up to 150%) is allowed for non-valid RGB pixels (150% corresponds to U=V=255d, which has a saturation of √(1272+1272) = 180). Thus when using the default values all pixels will be processed.
Range 0 to 150; default 150, 0; minSat must be less than maxSat
float  interp = 16.0
Interpolate the saturation adjustment at the edges of the chosen range to prevent banding.
The adjustment is interpolated between 1.0 and sat in the range [minS-interp, minS] and between sat and 1.0 in [maxS, maxS+interp], where minS and maxS are the equivalents of minSat and maxSat in chroma units (100% = 119 units). There is no interpolation for interp=0, which can be useful when a clip consists of uniform colors and you want a hard cutoff. The interpolation is linear. (0 to 32, default 16; given in units of chroma, rather than a percentage)
bool  dither = false
When true, ordered dithering is applied when doing the adjustment. (default false)
bool  realcalc = false
AVS+ When true, force 'no-lookup': pure float calculation of new pixel values (always true for certain Deep Color formats) (TODO - clarify)
float  dither_strength = 1.0
AVS+ Control dithering amount.
For example, dither_strength=1.0 adds ±0.5 amplitude dither on the 0..255 range, and scaled in proportion for other ranges. (TODO - confirm)


[edit] Examples

[edit] Adjusting contrast and brightness

Tweak original.jpg
original


There are two problems with this picture. It is too dark, and the contrast is too small (the details of the tree are not visible for example). First, we will higher the brightness to make the picture less dark (left picture below). Second, we will higher the contrast to make details in the dark areas more visible (right picture below). Make sure that the bright parts don't get too bright though.

Tweak bright20.jpg Tweak bright20 cont12.jpg
bright=20 bright=20, cont=1.2


[edit] Adjusting saturation

Tweak original2.jpg Tweak sat075.jpg
original sat=0.75


Suppose we want to lower the saturation of the skin of the girl, and the background should be left intact. The proper way to do this is to set sat=0, and lower the hue range till you found the correct hue range which should be processed. This can be done by using a Vectorscope, but also manually. (If it is needed the saturation range can also be specified if the dark and white parts of that hue should not be processed.) The result is below.

Tweak hue105-138.jpg Tweak hue105-138 sat075.jpg
sat=0, startHue=105, endHue=138 sat=0.75, startHue=105, endHue=138


Instead, we can also try to "select" the skin of the girl by narrowing the saturation range only. The result is below. In this case the result is pretty much identical.

Tweak sat70-50.jpg Tweak sat70-50 sat075.jpg
sat=0, maxSat=75, minSat=55 sat=0.75, maxSat=75, minSat=55


[edit] YUV to YIQ conversion

The NTSC analog television system used the YUV color space with the UV axes exchanged and rotated by minus 33 degrees. See Colour FAQ of Charles Poynton. Note he gives the reverse transformation (from YIQ to YUV).

with its axes rotated by 33 degrees, a color space called YIQ. In YIQ, orange and teal are along the in-phase (I) axis, while green and magenta are along the quadrature (Q) axis. The eye is far more sensitive to detail along the I axis than along the Q axis, and NTSC allocated more bandwidth for I than for Q.

The Tweak filter can be used to convert YUV to YIQ, where the U axis represents I and V represents Q. The following example, based on an example at Swap, converts a YUV clip to YIQ, blanks the Q channel, and converts back to YUV. This produces the "orange and teal" color scheme that became a cliché.

Function YUVtoYIQ(clip clip)
{
   YtoUV(clip.VtoY(), clip.UtoY(), clip) # swap U and V
   Tweak(hue=-33)
   # Now: U corresponds to I, V corresponds to Q
   # could also have used: FlipHorizontal(clip).Tweak(hue=57) 
   # (see forum.videohelp.com)
}

Function YIQtoYUV(clip clip)
{
   clip.Tweak(hue=33)
   YtoUV(VtoY(), UtoY(), last) # swap U and V
}

clip = AviSource(...)
yiqclip = YUVtoYIQ(clip)  # convert to YIQ
v_chroma = BlankClip(VToY(yiqclip), color=$808080)
YToUV(yiqclip.UToY, v_chroma, yiqclip)
YIQtoYUV()  # convert back to YUV
AudioDub(yiqclip)

This allows processing the I and Q signals separately.

[edit] Developer notes

AviSynth uses the following definitions for hue and saturation:
As can be seen in the first image above, hue is the angle between the positive V-axis of the chroma plane and the point given by the centralised coordinates (V,U) on it. The saturation is the amplitude of the centralised chroma plane. Mathematically:

  • hue = 180/π * atan2((V-128)/128, (U-128)/128)
  • sat = √((U-128)2 + (V-128)2)


[edit] Changes

v2.58 Added startHue, endHue, maxSat, minSat and interp.
v2.60 Added dither.
Personal tools