Log in

View Full Version : Autogain


Mounir
17th February 2016, 18:55
I like to autogain option of coloryuv the problem is it don't protect completely black frames. Instead of having a black frame now i have "snow".
Is there another filter with such feature that protect black frames ?

johnmeyer
17th February 2016, 20:59
Autolevels?

Mounir
17th February 2016, 21:01
Yeah i just noticed this filter, i'm trying it now

StainlessS
18th February 2016, 03:21
Mounir, summick I've been playing with since coming in from the pub:


Function AutoContrast(clip c,Float "Strength",Float "Gamma",Float "MinRngPerc",int "MinLen", int "X",int "Y", Int "W", Int "H",
\ Int "Samples",Int "Start", Int "End",Float "Ignore",Bool "PCLevels", Bool "Chroma",Int "Matrix",Bool "Debug",Bool "SplitScreen",Bool "Show") {
/*
AutoContrast() v1.04, Auto Contrast Adjustment, YUV and RGB. http://forum.doom9.org/showthread.php?p=1757661#post1757661
# Req GScript (if not Avs+) (c) Gavino, RT_Stats (c) StainlessS.

Before frame serving starts, pre-scans Samples frames from source, and based on numbers does contrast correction.
Does correction on clip global, ie samples SAMPLES frames from clip and adjusts entire clip based on those SAMPLES frames, ie not
on a frame by frame basis. Is fast, after initial test, is just a simple Levels() [and MergeChroma() if YUV and Chroma==False].
Useful where eg entire clip has roughly same bad exposure.

Args:-

Strength, Default 0.75. Amount of adjustment, 0.0 -> 1.0 (maybe about 0.75 -> 1.0)
Gamma, default 1.0. Gamma used in Levels(), 1.0 = Linear.
MinRngPerc, Default 33.0%, If clip c luma range less than % of ColorSpace range (PCLevels=True or RGB ? 0->255 : 16-235) then do nothing.
MinLen, default 25, if number of frames less than this, then do nothing.
X,Y,W,H, Samples area (as for crop, all default 0, avoid edge noise).

Samples, Default 40. Frames to sample to find 'Global' luma dymamic range (silently limited to Framecount),.
Samples=0, converted to c.FrameCount ie ALL frames sampled.
Start: Default Undefined. Start frame of scan area. The Start arg overrides Auto Intro credits skipping.
End: Default Undefined. End frame for scan area. Overrides Auto End credits skipping. 0 (or less) will be converted to Framecount - 1.
If user supplied Start and End frame numbers given then that marks the range of frames from which to select the Samples frames.
If neither Start nor End given, the function tries to avoid sampling artificial black/white in Intro and End Credits sequences,
for Auto Intro and End Credits Skipping to be set to 5% (of FrameCount for Intro Skipping) and 90% (for End Skipping), the number of
frames between them must be greater or equal to 250 frames, and MUST also be greater than Samples, otherwise Auto skipping ignored and
the Start and End frame numbers are set to 0 and Framecount - 1.
If a user supplies eg a Start frame number ONLY, then End Skipping has to comply with the same above conditions, range between End Skip
frame and user supplied Start has to be at least 250 frames and greater than Samples, otherwise End frame set to FrameCount - 1. The
same conditions apply if only a user supplied End frame only.
After either user supplied Start/End, or via Auto Credits skipping, or defaulted to 0 & FrameCount -1, we have a sample scan range
from which Samples luma samples are taken (for RGB, via Matrix convert RGB to Luma-Y).

Ignore, Default 0.0%, Percentage of extreme pixels to ignore (noise) when getting luma min/max (As Threshold arg for YPlaneMinMaxDifference).
PCLevels, Default false=TV Range output(YUV only).
Chroma, Default True. If False apply Levels to only Luma, else apply Levels to Chroma too (Affects YUV only, levels always alters RGB sat).
Matrix, Default (c.Width>1100||c.Height>600) ? 3(PC709) : 2(PC601) # RGB only to convert to LumaY, Valid values 2 and 3 ONLY.
Debug, Default False. If true send some info to DebugView window (google).
SplitScreen, Default False. True, Only affect Left half of frame.
Show, Default False. Show Levels.
*/
c myName="AutoContrast: "
IsAvsPlus=(FindStr(UCase(versionString),"AVISYNTH+")!=0) HasGScript=RT_FunctionExist("GScript")
Assert(IsAvsPlus || HasGScript,RT_String("%sNeed either GScript or AVS+",myName))
Strength=Max(Min(Float(Default(Strength,0.75)),1.0),0.0)
Gamma=Float(Default(Gamma,1.0))
MinRngPerc=Max(Min(Float(Default(MinRngPerc,33.3)),100.0),0.0) # If luma range less than MinRngPerc, then ignore ie do not adjust.
MinLen=Default(MinLen,25) # If less than MinLen frames, then ignore ie do not adjust.
X=Default(X,0) Y=Default(Y,0) W=Default(W,-0) H=Default(H,-0) # Default test area, set coords to avoid noise at borders.
W = (W<=0) ? (Width-x+W) : W H = (H<=0) ? Height-Y+H : H
Samples = Default(Samples,40) # Frames sampled to establish global luma dynamic range
Ignore = Float(Default(Ignore,0.0)) # Allow up to max % of extreme pixels to ignore finding dynamic luma range
# Function exactly same as Threshold in YPlaneMinMaxDifference().
PCLevels = Default(PCLevels,False)
Chroma = Default(Chroma,True) # Default, do Chroma adjustment (YUV only)

Matrix = Default(Matrix,(Width>1100||Height>600) ? 3 : 2)
Assert(Matrix>=2 && Matrix<=3, RT_String("%s2 <= Matrix <= 3",myName))
DEBUG=Default(Debug,False)
SplitScreen=Default(SplitScreen,False)
SHow=Default(Show,False)
GS=("""
if(STRENGTH>0.0) { # Auto Contrast Adjustment
if(FrameCount>=MinLen) {
# Find current dynamic range of Luma Y.
Eval(RT_QueryLumaMinMax(Samples=Samples,start=Start,end=End,ignore=Ignore,X=X,Y=Y,W=W,H=H,matrix=Matrix, Debug=DEBUG))
if(IsRGB || PCLevels) { CSMin = 0 CSMax = 255 }
else { CSMin = 16 CSMax = 235 }
QLRng=QLMMMax-QLMMMin+1 # Locals set by RT_QueryLumaMinMax
CSRng=CSMax-CSMin+1
CSRngMin=CSRng*MinRngPerc/100.0 # Minimum CS dyamic range to proc, else ignore
if(QLRng >= CSRngMin) { # Ignore if < MinRngPerc of CS range
ALMin = Int(CSMin - ((CSMin - QLMMMin) * STRENGTH) + 0.5) # Round Up
ALMax = Int(CSMax - ((CSMax - QLMMMax) * STRENGTH)) # Round down
if(ALMin!=CSMin || ALMax != CSMax) {
(DEBUG)?RT_DebugF("Levels(%3d,%.2f,%3d,%d,%d,Coring=False)",ALMin,Gamma,ALMax,CSMin,CSMax,name=myName):NOP
if(SplitScreen) {
WW=Width/4*2
Lev=StackHorizontal(Crop(0,0,WW,0).Levels(ALMin,Gamma,ALMax,CSMin,CSMax,Coring=False),Crop(Width-WW,0,-0,-0))
} else {Lev=Levels(ALMin,Gamma,ALMax,CSMin,CSMax,Coring=False) }
if(!Chroma&&(IsYUV&&(VersionNumber<2.6||!IsY8))) {
(DEBUG)?RT_DebugF("Restoring original Chroma",name=myName):NOP
Last = Mergechroma(Lev,Last)
} else {Last = Lev}
(Show) ?RT_Subtitle("Levels(%3d,%.2f,%3d,%d,%d,Coring=False)",ALMin,Gamma,ALMax,CSMin,CSMax,align=2):NOP
} else {(DEBUG)?RT_DebugF("No Change to Levels",name=myName):NOP}
} else {
(DEBUG)?RT_DebugF("Low range Luma, No Change",name=myName):NOP
(Show)?RT_Subtitle("Low range Luma, No Change",align=2):NOP
}
} Else {
(DEBUG)?RT_DebugF("FrameCount too low [%d] Ignoring, need @ least %d frames",FrameCount,MinLen,name=myName):NOP
(Show)?RT_Subtitle("FrameCount low [%d] Ignoring",FrameCount,MinLen,align=2):NOP
}
}
""")
!HasGScript?Eval(GS):GScript(GS)
Return Last
}


Client

Import("AutoContrast.avs")

BAD_CONT = -100 # To make bad contrast clip.
BADCHROMA = True # Make BAD chroma
TEST_RGB = False # Conv clips to RGB32

STRENGTH=1.0
IGNORE=0.0
SPLITSCREEN=True
Show=True

ORG = AviSource("D:\v\StarWars.avi") # Good contrast clip.
BAD = ORG.ColorYUV(cont_y=BAD_CONT,cont_u=(BADCHROMA||TEST_RGB)?BAD_CONT:0,cont_v=(BADCHROMA||TEST_RGB)?BAD_CONT:0) # Make Bad

ORG=(TEST_RGB) ? ORG.ConvertToRGB32 : ORG
BAD=(TEST_RGB) ? BAD.ConvertToRGB32 : BAD

FIX = BAD.AutoContrast(Chroma=BADCHROMA,Strength=STRENGTH,Ignore=IGNORE,debug=True,SplitScreen=SPLITSCREEN,Show=SHOW) # fix it
BLK = ORG.BlankClip
Stackvertical(StackHorizontal(ORG.Subtitle("ORG"),BAD.Subtitle("BAD")),StackHorizontal(FIX.Subtitle(SPLITSCREEN?"HALFFIX":"FIX"),BLK.Subtitle("DUMMY")))

Above EDITED

Below, original post, changed since then.
Got a gazillion versions of that function.
Samples SAMPLES frames from source, and based on numbers does LUMA contrast only correction.
Does correction on clip global, ie samples SAMPLES frames from clip and adjusts entire clip based on those SAMPLES frames, ie not
on a frame by frame basis.
Is fast, after initial test, is just a simple Levels().MergeChroma().

EDIT: MinRngPerc and MinLen are intended to skip adjustments when applied on short scenes trimmed from greater length clip.

Reel.Deel
18th February 2016, 03:59
@StainlessS
Interesting, will definitely give it a try. I'll add it to the wiki as well.

@Mounir
Give AutoAdjust (http://forum.doom9.org/showthread.php?t=167573) a try.

Mounir
18th February 2016, 16:36
Thanks Reel Deel, autoadjust just saved my life

StainlessS
18th February 2016, 22:31
Reel.Deel,

Updated post #4, renamed back to AutoContrast and added support for RGB.
Added several args and changed some defaults.

StainlessS
7th March 2016, 15:37
AutoContrast v1.03

Added Show and SplitScreen.

See post #4

StainlessS
28th April 2016, 23:24
AutoContrast v1.04, see post #4.

Oops, made stupid mistake, was

W = (W>0) ? (Width-x-W) : W H = (H>0) ? Height-Y-H : H


Should have been

W = (W<=0) ? (Width-x+W) : W H = (H<=0) ? Height-Y+H : H


Musta had my head stuck in some orifice at the time.