Log in

View Full Version : Another frame duplication function


Pages : 1 [2]

Great Dragon
16th April 2015, 09:05
StainlessS, could you please give some explanation show to use 'Override' option properly? It seems I don't understand how to use those debug values correctly especially the FD parameter.

StainlessS
16th April 2015, 10:03
Using below

FN="pass6_ep1_trim.avi" # Great Dragon Clip
THRESH = 35 # Great Dragon clip ONLY
IGNORE = 0.4 # Great Dragon clip ONLY
OVERRIDE = 0.95 # Great Dragon clip ONLY


IGNORE=0.4 ignores about 1 in 250 pixels.
There seems to be horizontal movement between what should (I think) be dupes, also reason for high Thresh.
If you step through, frame 5 should show MnMxDif=17 and FD=1.150, so this has detected dupe (MnMxDif=17)
but, should not be a dupe due to the moving clouds. We want to override this frame and so Override should be below
the FD=1.15.

Worst frames in your sample are 111(FD=0.986), 185(FD=1.011) and 189(FD=1.016).
So as the worst frame (111) is FD=0.986 you need an Override which is lower than FD, I chose 0.95.
If there are other frames in full sample that should not be dupes then set Override just lower than the shown
FD for that worst frame (frame with lowest FD that should be overridden to 'not a dupe').

Override is just a safety measure so that you can set quite ferocious THRESH and IGNORE without fear of making big mistakes.
I'm guessing that not many dupe detectors would work very well (if at all) with that clip,
thank you I shall keep a copy of it.

EDIT: If you keep your eye on the Character flags on top line as clip plays, you will see the Flag sequences
change as it changes from scene to scene (ie the dupe sequences are different in each scene making it very hard for most dupe detectors).

EDIT: If not detecting enough dupes, then raise Ignore and/or Thresh.
EDIT: Override should be set AFTER BOTH Thresh and Ignore.
EDIT: Can raise Thresh to about 50 (with same other settings).

Great Dragon
16th April 2015, 23:18
Thanks and I have a few more questions.
In the debug first line there is the abbreviation TOD. As far as I understand O stands for "Override", D stands for "Duplicate". But what is T stands for?
Sometimes I have a situation when picture MnMxDif is far lower than Thresh and Override too but it still doesn't detecting as ''dupe" and "T" just turns yellow.

Is it worth to stabilize clip before using dupe detector?
Is crop helps to better detect dupes?

StainlessS
17th April 2015, 11:10
Show (Default False) Shows Metrics if True
Metrics shown on top line are, character flags 'T','O', and 'D'. Where Hilited, 'T' means Thresh detected dupe, 'O' means
Dupe Overridden to non-dupe, and 'D' means using Dupe. Following the character flags, is the current dupe number ie 1
is first in a run of dupes, 2 is 2nd etc. and Following that is the currently greatest count of consecutive dupes in
any single run.

So 'T' means was detected as dupe by Thresh, however if 'O' is also hil-lited, then was Overridden to be NOT dupe.
The 'D' flag gives the final decision, will be hi-lited if 'T' but not 'O' is set hi-lited.
Sometimes I have a situation when picture MnMxDif is far lower than Thresh and Override too but it still doesn't detecting as ''dupe" and "T" just turns yellow.
Not sure what you meant there, was 'O' hilited as well, if so then was Overriden to not dupe.

EDIT:
Override (Default 1.0). Thresh detected Dupes are Overridden to non-dupe if RT_FrameDifference is greater than Override.
RT_FrameDifference is the average pixel difference between the Anchor Frame and current_frame. Suggest about 0.5 -> 1.5.

If overriding too many frames then Override is set too low, if not enough then Override is set too high (Override need to be just below
frame with moving clouds with lowest FD [RT_FrameDifference] as shown in metrics).

Give Thresh, Ignore and Override args and also displayed MnMxDif and FD.
I actually chose 50 as Thresh due to what I think are horizontally displaced frames (which may or may not be intended to be a dupe),
if you decide that these shifted frames are not dupes then probably a lower thresh would suffice, likewise if you do decide that they should be dupes,
you might want to stabilize (and crop) beforehand (but a higher Thresh eg 50 would probably produce exactly same result).

Hope that helps.

EDIT: 50 was just my first guess for Thresh, perhaps somewhere between 35 and 50 is probably more appropriate.

EDIT: It is also possible that setting ChromaWeight to 0.0 could produce better results where only luma difference would be used by
RT_FrameDifference when comparing with Override.

Great Dragon
17th April 2015, 12:47
Thanks, maybe I'll make another sample when I get home to show you what I've meant.
For me I've found that high Thresh with low Ignore works better. It just gives me more freedom. Because when Ignore is to high then MnMxDif changes in to low values and it's easy to get wrong dupes. Especially when moving objects are small.

StainlessS
17th April 2015, 14:53
It probably needs a little bit of practice to use for best results (for me too), I dont usually touch anime as I just don't have any real interest in it.

Just a little bit of extra info:-

The Subtracted frame is actually half scaled result Int((Anchor-current_frame)/2)+128 (I think), this is how Subtract works. Reason is that eg
255-0=255 and 0-255=-255 ie max possible range=510. The /2 + 128 takes into range 0->255 but does impose a little error in the resultant frame.

As far as YPlaneMin is concerned (and also simililar for YPlaneMax and YPlaneMinMaxDifference),
The function calculates the number of pixels that corresponds with percentage Threshold arg, we will call this pixlim.
It samples every pixel and updates a count array holding a pixel count for each luma level.
It then iterates through the array from 0 -> 255.
Something like:

cnt=0
result = 255
for(i = 0 to 255){
cnt=cnt + count_array[i]
# if(cnt>=pixlim) { # WRONG, Edited to below
if(cnt>pixlim) {
result=i
exit i # exit the loop with result
}
}
return result


The above is same as Ignore thing, it allows it to ignore (EDIT: up to) an amount of extreme noise pixels.
YPlaneMedian is actually implemented as YPlaneMin(Threshold=50.0)

EDITED above mistake, here is exact implementation in C (from conditional_functions.cpp)

// Find the value we need.
if (mode == MIN) {
unsigned int counted=0;
for (int i = 0; i< 256;i++) {
counted += accum[i];
if (counted>tpixels)
return AVSValue(i);
}
return AVSValue(255);
}

StainlessS
20th April 2015, 03:59
Additional to earlier posted NoDupes.avs.
Can cut out audio along with Dupes, if required (EDIT: eg remove static scenes from security cam footage that includes audio).

Supplied (along with SelectRanges.avs) in FrameSel.zip.


Function RejectRanges(clip c,String "SCmd",String "Cmd",Bool "TrimAudio",Float "FadeMS") {
# RejectRanges() by StainlessS. Required:- FrameSel, Prune, RT_Stats
# Wrapper to delete frames/ranges along with audio, can supply frames/ranges in SCmd string And/Or Cmd file.
# The wrapper makes for easier usage of Prune() which supports up to 256 input clips, but requires a clip index,
# eg '3, 100,200' would specify clip 3, range 100 to 200. The wrapper does away with the necessity for the clip index as we
# are only using a single clip here. Prune also does not have a 'reject' arg to delete specified frames rather than select them,
# this wrapper also converts a list of frames to delete into a list of frames to select so that we can use Prune and its audio
# capability.
#
# SCmd: Frames/Ranges specified in String (Frames/Ranges either Chr(10) or ';' separated, infix ',' specifies range, eg 'start,end').
# Cmd: Frames/Ranges specified in file (one frame/range per line, comments also allowed, see FrameSel for Further info).
# TrimAudio:
# True(default), deletes audio belonging to deleted frames
# False, returns original audio, probably out of sync.
# FadeMS: (default 1.0 millisec). Linear Audio Fade duration at splices when TrimAudio==true, 0 = dont fade (might result in audio 'clicks/cracks').
c
TrimAudio=Default(TrimAudio,True) # default true trims audio, false returns original audio (audiodubbed, as Framesel returns no audio)
FadeMS=Float(Default(FadeMS,1.0)) # 1 millisecond linear fadeout/fadein at splices
PruneCmd = (TrimAudio) ? "~Prune_"+RT_LocalTimeString+".txt" : ""
(!TrimAudio)
\ ? FrameSel(scmd=SCmd,cmd=Cmd,reject=true)
\ : FrameSel_CmdReWrite(PruneCmd,scmd=SCmd,cmd=Cmd,reject=true,Prune=True,range=true)
(TrimAudio) ? Prune(Cmd=PruneCmd,FadeIn=True,FadeSplice=True,FadeOut=True,Fade=FadeMS) : NOP
# If TrimAudio==true then delete Prune temp file, Else restore original Audio to the now audio-less clip
(TrimAudio)
\ ? RT_FileDelete(PruneCmd)
\ : (c.HasAudio) ? AudioDub(c) : NOP
Return Last
}

Client

FN="WebCam.AVI"
Avisource(FN)
RejectRanges(Cmd="FrameSelCmd.txt")
Return Last

Great Dragon
20th April 2015, 15:08
At last I have some time to work a little bit more with the script to find out how good it is. And it is really good. None of dupe detectors works as good as Dupped_MI. Especially with fades and Override feature helps a lot with it.

As I've promised early here there are files with examples where the script could fails a little bit more. Of course it's only in my case. It can be tuned to catch dupes almost in any situations. But in a video I work with most of dupes can be removed with this settings
Dupped_MI(Thresh=95, Ignore=0.01, Override=0.95)
And to catch dupes with small movement like blinking, small objects, moving clouds on a background etc. I have to lower override to around 0.5. But in this case all other dupes which don't need such low value would be skipped.

1. Blinking https://www.dropbox.com/s/fmi87fngdzlreog/blinking.avi?dl=0
2. More moving clouds https://www.dropbox.com/s/ngfwju9q669xsnm/moving_clouds.avi?dl=0
3. Small objects https://www.dropbox.com/s/9jsx0vtzp9qz8pp/small_objects.avi?dl=0
4. More small objects https://www.dropbox.com/s/ekern8ysci7g8dz/small_objects2.avi?dl=0

Of course it couldn't be universal settings but at least all those example could help to improve script accuracy.
For now to fix problem areas I isolate them with trim()

StainlessS
20th April 2015, 15:43
Glad you found a use for it.
Saw original author Corran on-site about 4:00AM this morning, I looked previously and he had not been on-site for some time (I think).
I shall implement a optional 'windowed' override (and maybe Thresh detect) at some point so that may assist with blinking eyes type probs.
EDIT:
Might also implement equivalent of Subtract(anchor,current).YPlaneMinMaxDifference but avoiding the Subtract() halfscale clip along with
its precision losses.


EDIT: I shall pick up your samples some time in next day or two (maybe today), thanx.

EDIT: Corran has updated links and first script today.
@Corran, If you come back again soon, suggest remove GetFrame() function [no need for it ie Trim(n,-1) trims a single frame
without all the other nonsense checks or function call], as shown in modded script here:- http://forum.doom9.org/showthread.php?p=1716484#post1716484
Replace your script (or parts) with the mod, it is still your script as far as I'm concerned, attribution not required.

Corran
21st April 2015, 07:06
Thank you for the contributions StainlessS. I've updated the first post with the changes. Sorry you had to put up with my amateurish code. :) I'm glad to see this idea take new forms though. I tried using your new script (Dupped_MI) in Avisynth 2.5.8 but encountered an error with the RT_ColorSpace functions. AviSynth 2.6 appears to work fine however.

StainlessS
21st April 2015, 08:17
... in Avisynth 2.5.8 but encountered an error with the RT_ColorSpace functions. AviSynth 2.6 appears to work fine however.

Thanks, I'll look into it (I dont do a lot of testing on 2.58).
(What version RT_Stats are you using ?)

Corran
21st April 2015, 08:52
What version RT_Stats are you using ?

It was RT_Stats.dll from v1.43_20141008. I'm now using RT_Stats26.dll from the same zip file after upgrading avisynth.

StainlessS
21st April 2015, 13:45
but encountered an error with the RT_ColorSpace functions. AviSynth 2.6 appears to work fine however.

I've taken a look at v2.5 and was not able to find any problem, works fine using Great Dragon original sample and v2.5 RT dll, however,
I've just realized that I made a stupid mistake on the RT_ColorSpace line to reduce IgnoreChroma, it should have remained same as Luma Ignore, I am changing now.
I shall update the post soon, and if you (or anyone else) have further problems can you post exact error message, colorspace, avisynth version, RT dll version, colorspace and size/fps of clip involved.

Great Dragon:
And to catch dupes with small movement like blinking, small objects, moving clouds on a background etc. I have to lower override to around 0.5. But in this case all other dupes which don't need such low value would be skipped.
Yes lowering to 0.5 would override more false detections, it quite depends upon how noisy your source is, perhaps 0.5 or maybe 0.75 would be a better default. EDIT: think I'll change to 0.5

StainlessS
23rd April 2015, 14:45
Found an instance of "LowBitrateAnime.mkv" as used in post #45 here, (posted by Dark Shikari) : http://forum.doom9.org/showthread.php?p=1468097#post1468097

1.77MB, 3:28 secs

StainlessS
23rd April 2015, 17:38
Dupped_MI(), Post #44 updated. Few small mods, mostly docs.

@Corran, If you can remember what the RT_ColorSpaceXMod/YMod problem error message was, can you give me a clue ?
Everything works hunky-dory for me.

StainlessS
23rd April 2015, 18:57
Added Multi-Instance Wrapper to post #44


Function Dupped_MI_X(clip c, Int "Thresh",Float "Ignore",Float "Override",Float "ChromaWeight",
\ bool "Show", bool "Stack",String "Fn",Bool "FnComments",
\ Bool "Pair", Int "Thresh2",Float "Ignore2",Float "Override2",Float "ChromaWeight2") {
/*
Wrapper for convenience.
Works same as Dupped_MI() but auto StackHorizontal of 2nd instance if Pair=True.
Defaults for 2nd Instance are for EXACT dupes only, Change args to 2nd clip using Thresh2, Ignore2, Override2, and ChromaWeight2.
*/
Pair = Default(Pair, false)
Th2 = Default(Thresh2, 0)
Ig2 = Default(Ignore2,0.0)
Ov2 = Default(Override2,255.0)
Cw2 = Default(ChromaWeight2,ChromaWeight)
A = c.Dupped_MI(Thresh=Thresh,Ignore=Ignore,Override=Override,ChromaWeight=ChromaWeight,Show=Show,Stack=Stack,Fn=Fn,FnComments=FnComments)
B = (Pair) ? c.Dupped_MI(Thresh=Th2,Ignore=Ig2,Override=Ov2,ChromaWeight=Cw2,Show=Show,Stack=Stack,Fn="",FnComments=False) : 0
(B.IsClip) ? StackHorizontal(A,B) : A
Return Last
}