View Single Post
Old 18th February 2021, 15:33   #1  |  Link
Arx1meD
Registered User
 
Arx1meD's Avatar
 
Join Date: Feb 2021
Posts: 121
Brightness - restore dark and bright zones

This script will be useful for restoring dark and bright zones of a video or for smoothly changing luma.
Thanks to Didée for his Ylevels. This inspired me to create other functions.

Code:
#                        Brightness v1.2
#
# v1.0 - First release.
# v1.1 - Adapted for use in all versions of AviSynth.
# v1.2 - Changed the function for CurveL.
#        Now if 'light' > 0 bright areas will be brighter.
#        Changed the default value of 'light' to -20.

/*
Needed plugins: MaskTools2 v2.2.16 or greater.
    https://github.com/pinterf/masktools/releases
    http://avisynth.nl/index.php/MaskTools2/mt_lut

Brightness(mode, dark, light, bit, chroma, DarkLightZonesOnly, SaveMinMaxLuma)

mode:
-----
    "Line" - linear brightness variation.
    "Cos"  - changes brightness by Cosine function.
    "Cube" - changes brightness by a cubic power function.
    Default: "Cube"

dark:
-----
    The strength of changing dark zones.
    The recommended range is -30 ... 30. The range is not limited, in theory.
    Default: 20

light:
------
    The strength of changing light zones.
    The recommended range is -30...30.
    Default: -20

bit:
----
    Bit depth per channel in input clip.
    -1 - for autoscale in MaskTools2 (slower).
     0 - for autodetection (faster).
    8, 10, 12, 14, 16.
    Default: 0

chroma:
-------
    true  - it means "process"; set u = v = 3 in mt_lut() MaskTools2.
    false - it means "copy" or "copy first"; set u = v = 2.
    Default: false

DarkLightZonesOnly:
-------------------
    Changes only dark and light zones.
    true  or  false.
    If true, then "SaveMinMaxLuma" is ignored.
    Default: false

SaveMinMaxLuma:
---------------
    Smooth brightness change for dark and bright zones. Keep minimum (0) and maximum (255) value of luma range.
    true  or  false.
    Default: true

Usage Default:
Brightness(mode="Cube", dark=20, light=-20, bit=0, chroma=false, DarkLightZonesOnly=false, SaveMinMaxLuma=true)
or
Brightness("Cube", 20, -20, 0, false, false, true)
*/

function Brightness(clip input, string "mode", float "dark", float "light", int "bit", bool "chroma", bool "DarkLightZonesOnly", bool "SaveMinMaxLuma") {
mode   = Default(mode, "Cube")
dark   = Default(dark, 20)
light  = Default(light, -20)
bit    = Default(bit, 0)
chroma = Default(chroma, false)
DLZO   = Default(DarkLightZonesOnly, false)
SMML   = Default(SaveMinMaxLuma, true)

Assert(mode == "Line" || mode == "Cos" || mode == "Cube", "Brightness: Mode must be: Line, Cos, Cube")
Assert(bit == -1 || bit == 0 || bit == 8 || bit == 10 || bit == 12 || bit == 14 || bit == 16, \
       "Brightness: Bit depth per channel must be only: 8, 10, 12, 14, 16 or -1, 0 for autodetection")

Try { bpc = bit == 0 || bit == -1 ? input.BitsPerComponent : bit } Catch (msg) { bpc=8 }      #BitsPerComponent only in AVS+
scale_inputs = bit >= 0 ? "none" : bpc == 8 ? "none" : "allf"   #"all" range in 8 bits Y=16...235; "allf" range in 8 bits Y=0...255
use_expr = bit >= 0 ? 0 : bpc == 8 ? 0 : 2 
chrom = chroma ? "process" : "copy"

LUMA = bit >= 0 ? Pow(2.0, bpc) - 1 : 255.0
maxY = String(LUMA)
midY = String(LUMA/2.0)

stD = bit >= 0 ? String(dark * Pow(2.0, bpc - 8)) : String(dark)
stL = bit >= 0 ? String(light * Pow(2.0, bpc - 8)) : String(light)

k = String(mode == "Line" || mode == "Cube" ? 0 : 1)
n = String(mode == "Cube" ? 3 : 1) # odd numbers only
j = String(30) # even numbers only
l = string(21) # odd numbers only
m = String(SMML == true ? 1 : 0)
f = String(mode == "Line" ? 1.25 : mode == "Cos" ? 1.15 : 1.05)

curveD = dark == 0 ? "x" : !DLZO ? "x "+stD+" "+k+" 1 + 1 x "+midY+" / - "+n+" ^ * pi x * "+maxY+" / cos "+k+" * - * 1 1 x "+midY+" / - "+j+" ^ "+m+" * - * +"
                               \ : "x "+stD+" 1 x "+midY+" / - "+l+" ^ pi x * "+maxY+" / cos "+l+" ^ - * "+f+" * -"
curveL = light == 0 ? "x" : !DLZO ? "x "+stL+" "+k+" 1 + 1 x "+midY+" / - "+n+" ^ * pi x * "+maxY+" / cos "+k+" * - * 1 1 x "+midY+" / - "+j+" ^ "+m+" * - * -"
                                \ : "x "+stL+" 1 x "+midY+" / - "+l+" ^ pi x * "+maxY+" / cos "+l+" ^ - * "+f+" * +"

# function 1:  x + 'st'*((1+'k')*(1 - x/127.5)^'n' - 'k'*cos(x*pi/255))*(1 - 'm'*(1 - x/127.5)^'j')
# function 2:  x - 'f'*'st'*((1 - x/127.5)^'l' - cos(x*pi/255)^'l')

out = "x "+midY+" > "+curveL+" "+curveD+" ?"

mt_lut(input, expr=out, Y=3, chroma=chrom, scale_inputs=scale_inputs, use_expr=use_expr)
# mt_lut(input, expr=out, Y=3, chroma=chrom) # for MaskTools v2.0a48
}
Explanation of what the script does.
1. Basic functions for smoothly changing luma:

Backup copy formulas 1 graphs 1
2. Functions for changes only dark and light zones:

Backup copy formulas 2 graphs 2

Examples:
Brightness(mode="Cube", dark=20, light=0, bit=0, chroma=false, DarkLightZonesOnly=true, SaveMinMaxLuma=true)

Backup copy Source frame Restored frame
Comparison of original and restored clip

Last edited by Arx1meD; 16th February 2023 at 16:56. Reason: Changed image hosting. In mt_lut changed yexpr to expr, use_expr to 2
Arx1meD is offline   Reply With Quote