View Full Version : Smooth resulting values in Scriptclip temporally
anton_foy
16th September 2022, 01:41
Very odd question, can you temporally "soften" / "even out" the resulting numbers in ScriptClip somehow?
Results from AverageLuma for example:
frame 1 = 1.2000
frame 2 = 1.2100
frame 3 = 0.7600 #Straying result!
frame 4 = 0.8900 #Straying result!
frame 5 = 1.2110
There are fluctuations here and there rather than a more
smooth and steady ~1.2000 and these "stray" values makes for an
uneven and unsuitable mask.
Edit: I do not want to spatially / temporally (eg. temporalsoften) tamper with the clip fed to Scriptclip.
It is the extracted noise so my script can determine how noisy the image is and return a number (high numbers = high amount of noise)
johnmeyer
16th September 2022, 02:24
Here is something where I created an average, but eliminated any frame where YDiff was near zero.
#----------------
#This function returns a white clip whenever a big jump is detected; otherwise a black clip is returned
#Each YDiff must eliminate Ydiff=0 (duplicate) from moving average.
#Since the first two frames of the clip have no preceding frame, don't return a mask
#for those two frames (which means there will be no fix for the first two frames)
#This function works just fine (i.e., really great detection)
function GenerateMask (clip c)
{
MyMask=c.ScriptClip("""
\ (( (YDifferenceFromPrevious(selectevery(source, 1, 2)) < 0.3 ?
\ YDifferenceFromPrevious(selectevery(source, 1, 3)) :
\ YDifferenceFromPrevious(selectevery(source, 1, 2)) )
\ +
\ (YDifferenceFromPrevious(selectevery(source, 1, 1)) < 0.3 ?
\ YDifferenceFromPrevious(selectevery(source, 1, 2)) :
\ YDifferenceFromPrevious(selectevery(source, 1, 1)) )
\ +
\ (YDifferenceFromPrevious(selectevery(source, 1, -1)) < 0.3 ?
\ YDifferenceFromPrevious(selectevery(source, 1, -2)) :
\ YDifferenceFromPrevious(selectevery(source, 1, -1)) )
\ +
\ (YDifferenceFromPrevious(selectevery(source, 1, -2)) < 0.3 ?
\ YDifferenceFromPrevious(selectevery(source, 1, -3)) :
\ YDifferenceFromPrevious(selectevery(source, 1, -2)) )
\ )/4) /
\ (YDifferenceFromPrevious(source) + 0.01) <= JumpThresh
\ && current_frame > 2
\ ? WhiteFrame : BlackFrame """)
return MyMask
}
anton_foy
16th September 2022, 08:32
Thanks thats good! The number 1.2000 in my example was the number of noise amount for that particular clip (and section of that clip), another clip or another section of the same clip the number will change if the noise will change. Maybe possible then to make it ignore those "stray" frames if the value is min/max more than 0.8 or something for current frame compared to the neighbouring frames.
Hmm tricky how to code it...
Edit: oh wait I misread your explanation and script! Now this seems to do exactly what I need (just replace white and black frame with number from previous frames instead).
Dogway
16th September 2022, 13:35
Another solution would be to get the Average for 5 frames (current, 2 back 2 forward) then do a trimmed mean, that is compute the median and drop the extremes, then do the mean average of the other 3.
Or simply calculate the median.
Sorted = 0.7600, 0.8900, 1.2000, 1.2100, 1.2110
Average is 1.0542
Median is 1.2000
Trimmed mean is (0.8900 + 1.2000 + 1.2100)/3 = 1.1
IQM is ((0.8900 + 1.2100)*0.75 + 1.2000) / 2.5 = 1.11
anton_foy
16th September 2022, 15:10
Another solution would be to get the Average for 5 frames (current, 2 back 2 forward) then do a trimmed mean, that is compute the median and drop the extremes, then do the mean average of the other 3.
Or simply calculate the median.
Sorted = 0.7600, 0.8900, 1.2000, 1.2100, 1.2110
Average is 1.0542
Median is 1.2000
Trimmed mean is (0.8900 + 1.2000 + 1.2100)/3 = 1.1
Cool thank you both!
I used YDifferenceToNext in my original script but YDifferenceFromPrevious would work aswell I guess.
Here is my mod of John's script (not tested yet and probably wrong):
function NoiseMask (clip c)
{
in = mt_makediff(c,c.blur(1.3)).mt_binarize(132)
rt_Mask=c.ScriptClip(c,[in]){
\ (( (YDifferenceFromPrevious(selectevery(in, 1, 2)) < 0.3 ?
\ YDifferenceFromPrevious(selectevery(in, 1, 3)) :
\ YDifferenceFromPrevious(selectevery(in, 1, 2)) )
\ +
\ (YDifferenceFromPrevious(selectevery(in, 1, 1)) < 0.3 ?
\ YDifferenceFromPrevious(selectevery(in, 1, 2)) :
\ YDifferenceFromPrevious(selectevery(in, 1, 1)) )
\ +
\ (YDifferenceFromPrevious(selectevery(in, 1, -1)) < 0.3 ?
\ YDifferenceFromPrevious(selectevery(in, 1, -2)) :
\ YDifferenceFromPrevious(selectevery(in, 1, -1)) )
\ +
\ (YDifferenceFromPrevious(selectevery(in, 1, -2)) < 0.3 ?
\ YDifferenceFromPrevious(selectevery(in, 1, -3)) :
\ YDifferenceFromPrevious(selectevery(in, 1, -2)) )
\ )/4) /
\ (YDifferenceFromPrevious(in) + 0.01) <= 0.32
\ && current_frame > 2
\ ? YDifferenceFromPrevious(in, 1, 1) : YDifferenceFromPrevious(in)
val = last
bv = int(val*0.0037)
c.ex_invert().tweak(bright=(br))
)}
return rt_Mask
}
@Dogway, would your first suggestion result in a smoother ramping of the numbers if the noiselevel rises/lowers? As one scene can go from dark noisy to bright clean for example.
Edit: I edited the code but no I cannot do like that. Im too tired...
Dogway
16th September 2022, 15:45
I think so, because you use median to drop outliers, but then use mean average to smooth out result. For smoother you need more frames though.
anton_foy
18th September 2022, 12:50
I tried first John's suggestion but it flickers way off. Of course I have done something wrong (tried to take the near values and not the last):
function NoiseMask (clip c)
{
in = mt_makediff(c,c.blur(1.3)).mt_binarize(132)
rt_Mask = ScriptClip(c,function[c,in] () {
rt =
\ (( (YDifferenceFromPrevious(selectevery(in, 1, 2)) < 0.3 ?
\ YDifferenceFromPrevious(selectevery(in, 1, 3)) :
\ YDifferenceFromPrevious(selectevery(in, 1, 2)) )
\ +
\ (YDifferenceFromPrevious(selectevery(in, 1, 1)) < 0.3 ?
\ YDifferenceFromPrevious(selectevery(in, 1, 2)) :
\ YDifferenceFromPrevious(selectevery(in, 1, 1)) )
\ +
\ (YDifferenceFromPrevious(selectevery(in, 1, -1)) < 0.3 ?
\ YDifferenceFromPrevious(selectevery(in, 1, -2)) :
\ YDifferenceFromPrevious(selectevery(in, 1, -1)) )
\ +
\ (YDifferenceFromPrevious(selectevery(in, 1, -2)) < 0.3 ?
\ YDifferenceFromPrevious(selectevery(in, 1, -3)) :
\ YDifferenceFromPrevious(selectevery(in, 1, -2)) )
\ )/4) /
\ (YDifferenceFromPrevious(in) + 0.01) <= 0.32
\ && current_frame > 2
\ ? YDifferenceFromPrevious(selectevery(in, 1, 1)) : YDifferenceFromPrevious(selectevery(in, 1, 2))
br = int(rt*0.037)
ex_invert().tweak(bright=(br))
} )
return rt_mask
}
noisemask()
@Dogway, I don't really know how to script your suggestion yet...a hint? :)
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.