Log in

View Full Version : HELP on advanced AVS conditional filter


frank10
13th December 2005, 15:18
I am learning avisynth advanced scripting and I tried to write a script to
treat a clip with different settings at different scenes (dark-normal).

So I made a detect scene-change routine and then with a conditional filter I'm trying to switch the scene, based on the averageLuma of the frame that was just changed: dark scenes will get some filtering, normal one another one:



AviSource("D:\Temp\temp.avi").ConvertToYV12()

change = -1
b = last

# this reports to zero the variable after the scene change:
frameevaluate(" change = (change == -1) ? averageLuma(b) : change ")

# this should return a different filtered clip based on the average luma of the frame of the
# scene just changed:
scriptclip(""" (change == -1) && (avgL > 40) ? Tweak(0.0, 0.0,0.0,1.3).subtitle(display + "normal") : Tweak(0.0, 1.6,0.0,2.0).subtitle(display + "dark") """)

# this is only for test-display purpose:
frameevaluate( """ display = String(change) + " avg:" + String(avgL) """)

# this evaluates the averageLuma of current frame:
frameevaluate( " avgL = averageLuma(b) ")

#this detects scene change:
frameevaluate( "change = (YDifferenceToNext(b)-YDifferenceFromPrevious(b) < -7) ? -1 : change ")


It works all well, BUT I can change only the filtering of the *current frame* just changed.

How can I make *all frames* from a scene change to another one, change according to the luma measured on the scene change?
i.e:
sceneA - sceneB
measure luma on the first frame of sceneA (this works)
filter *all* frames from this to the new sceneB, according to the measured Luma (THIS doesn't work)
repeat for all scenes...


Thank you a lot for your suggestions

Didée
13th December 2005, 16:36
You'd have to initiate a global variable, say "global darkscene". By conditional filtering, set this variable as follows:

global darkscene = (scenechange detected)
? ( (newframe darker 40) ? 1 : 0 )
: darkscene

Then, based on the actual content of "darkscene", you can decide by ScriptClip which clip to put out:

ScriptClip(source, "darkscene == 1 ? YourDarkFilteredClip : YourNormalFilteredClip")


However I'm not sure if this will work out. What do you do with scenes that start dark, then slowly get brighter, or vice versa?

What's so wrong about something like

LoadPlugin(MaskTools.dll)

source = WhateverSource()

dark = source .DarkSceneFiltering()
norm = source .NormSceneFiltering()

dmask = source.bicubicresize(32,24)
\ .temporalsoften(2,8,8,16,2)
\ .levels(40-4,1.0,40+4,0,255,coring=false)
\ .bicubicresize(source.width(),source.height(),1,0)
\ .fity2uv()

MaskedMerge( dark, norm, dmask, U=3,V=3) which, as you should know, I had suggested before (http://forum.doom9.org/showthread.php?p=703897#post703897)?

frank10
13th December 2005, 18:19
Thank you Didée.

There is nothing wrong with your code, on the contrary!
You explained it better now, as I asked you on my previous post in the thread you mentioned. And surely it works also in that scenes that haven't abrupt change. It is perfect particularly to brighten more the dark scenes than the normal ones.

But I see a problem with your code, as I have already explained: the frames tend to blend between the two settings when there are dark parts and lighter ones in the same frame.
I.e. If you want to desaturate on normal and to brighten in dark scene, in mixed luma scene you get a blend of these settings that it isn't what I want. But you can also think about more strange boost filtering and precise scene detection. With your approach you can't because of the blend.

Furthermore I am learning variables in Avisynth and so my code is also an exercise to improve my skill and I thank you for your suggestion that works.

Your works:

global darkscene = 1
scene_normal = Tweak (0.0, 0.0,0.0,1.3)
scene_dark = Tweak (0.0, 1.6,0.0,2.0)

frameevaluate(" change = (change == -1) ? averageLuma(b) : change ")

ScriptClip( " darkscene == 1 ? scene_dark : scene_normal ")

frameevaluate(" darkscene = (change == -1) && (avgL > 40) ? 0 : 1 ")


I dont know why my attempt instead, without that intermediate variable 'darkscene', don't work, because the variable 'change' remains always equal at -1 , so it doesn't detect scene change:



frameevaluate(" change = (change == -1) ? averageLuma(b) : change ")

scriptclip(" (change == -1) && (avgL > 40) ? scene_normal : scene_dark ")


Finally you're right about the dissolves: that's the second part of my attempt, as I asked before with no luck here:
http://forum.doom9.org/showthread.php?t=103741

I hope to receive some hints also there.
Thank you again and let me know better these variables thing in AVS!


I've seen your edit, now: I made little variation, but that part works anyway.