Log in

View Full Version : Plz suggest a filter for jerky playback caused by low fps source


Die*wrek*show
16th February 2010, 18:39
I'm trying to find if there is an easy fix for this clip, that doesn't involve taking out or changing the two convertfps lines. Which would break my other scripts that depend on it having a certain framecount, framerate, and speed at which the subject is moving.

Anyway, I had to do a janky 10 fps to 22 fps conversion because my original clip was done at 10 fps, then later I ended up using 22 fps for all the other parts of the video. And stackhorizontal has to have matching framerate.

here is the script that creates the intermediate .avi
a=import("mypath")
b=import("mypath")
a+b
spline36resize(196,264)
convertfps(7.1)
convertfps(5)
assumefps(22)

here is the script that animates the .avi

avisource("mypath").loop(3)
animate(stat,0,83,"spline36resize",344,264,149.0,0,344,264,344,264,0.0,0,344,264

Finally, here is the video (http://www.sorceriesandstuff.com/left%203.avi) it produces.

I am completely dependent upon the downconvert from the original 10fps to 7.1>5 then up to 22fps. If I change that I might as well start over.

What gives me the problem is I don't know the terminology. What I need, is it called "temporal denoising" or "stabilization" or "motion compensation"?

I thought adding a stmedianfilter line would help, because it does two of those^ but NOTHING seemed to work. I was probably inserting the filter line in the wrong part of the script. I tried all of these:

stmedianfilter(16,255,7,14)
temporalsoften(1,255,255,60,2)
deflicker(lag=20,noise=10,scene=60,percent=92)
temporalcleaner(8,0)
{
}
stab(2,5,3)

the only change i noticed, is if i really cranked up the settings they would produce some distortion : ( but no smoothing like I wanted.

wonkey_monkey
16th February 2010, 19:18
I am completely dependent upon the downconvert from the original 10fps to 7.1>5 then up to 22fps.

Why convertfps to 7.1 and then to 5? Why not just convertfps(5)?

Given that it's animation, perhaps changefps would give you better results. If you want something smoother than convertfps, you could try MVTools 2, and the MFlowFPS function in particular:

a=import("mypath")
b=import("mypath")
a+b
spline36resize(196,264)

super = MSuper(last)
backward_vec = MAnalyse(super, isb = true)
forward_vec = MAnalyse(super, isb = false)
MFlowFps(super, backward_vec, forward_vec, num=5, den=1, ml=100) # get 5 fps
assumefps(22)

Die*wrek*show
16th February 2010, 19:30
Why convertfps to 7.1 and then to 5? Why not just convertfps(5)?

If you start at 10 fps, and go to 5 fps convertfps throws an error and won't let you use blending mode. I thought I was preserving quality.

Changefps from 10fps to 5fps would throw away half my frames, and give me no blending.

The original 10fps video, the subject was moving WAAAYYYYYY to slow. Which is why I didn't just do assumefps from 10fps to 22fps. I needed to compress the actual motion within the video.

Die*wrek*show
16th February 2010, 22:15
I had to change the syntax but I tried out that script you posted and I see something happening now. Something good.

But it also made me realize, that part of the script, where the framerate dips down and then I speed it back up, is not the problem. That part is fine the way it is, it's only his feet moving anyway, and that motion is plenty fluid enough. The rest of his body doesn't move at all.

What's not ok is the line that animates him to move to the right. That seems to be the offending script. I can see lots of flickery-ness around the edges as he moves.

I saw a motion blur example just now, and I tried that on the final .avi and it almost seemed worse than before.

I don't know if this is even worth all the trouble. I wasn't ready for this, that's for sure. No more framerate conversions for me. Ugh, what a mess.

Alex_ander
17th February 2010, 09:29
A few chances to make something good with MVTools with such a low initial framerate (10fps) - you can expect numerous new artifacts. Maybe the least evil would be repeating frames evenly in time (to minimize the main component of jerkyness). If you can afford a non-standard framerate, make both 21 fps (that's just +-5% in speed terms): ChangeFPS(20).AssumeFPS(21) for the 10fps source and AssumeFPS(21) for the 22fps one.
You can also try ConvertFPS(20) for inserting mixed frames instead of ChangeFPS(20) mentioned above, then apply pulldown 21 -> 29.97 and encode interlaced if you want it for DVD.

IanB
17th February 2010, 11:55
You definitely don't want to do extended blending from 1 frame to the next, that just looks crappy no matter what. The eye just sees the 2 distinct images fading from one to the next, not pseudo motion. Alex_ander's suggestion above is sound.

Although your material is animation, and it is probably unsuitable for motion estimated interpolation with MFlowFPS(), it may still be suitable for motion blur with MFlowBlur(). Motion estimation errors in the FlowFPS case lead to ugly distortions of shapes, in the FlowBlur case they lead to inappropriate smear at the edge of shapes, which may or may not be objectionable. Correct motion estimation leads to smear appropriate to the motion of the object, like with real film with a normal shutter duration.

Or perhaps you may get away with combination of Frame duplication, FlowFPS and FlowBlur.

Beauty is in the eye of the Beer holder.

Die*wrek*show
18th February 2010, 18:03
I'm in a world of hurt right now. Please help.

I finally got mflowblur working, but I wanted to combine the un-blurred video with the blurred video, and nothing I'm trying is working.

I want to merge the two videos, they both have the same framecount(28frms), size, ect...

But not in the normal way. I would like a 4:3 pattern of 7 frames. 4 frames from "bottom" video, and 3 frames from "top" video, like:

ABCD efg HIJK lmn ....and so on. the idea is to see-saw the two videos.

I erased the original script, but I wrote something like

bottom=avisource(path to unblurred source)
top=avisource(path to blurred source).selectevery(7,0,1,2,3).overlay(bottom,top,opacity=0)
top=avisource(path to blurred source).selectevery(7,4,5,6).overlay(bottom,top)

and it didn't work.

2nd attempt, i tried making an overlay function, and it worked but it DOUBLES the framecount for no reason(which i easily solve with trim), but most importantly, if i put more than one range line, it only listens to the first line. that exact script is here, minus the paths-

bottom=avisource("path to unblurred avi")
top=applyrange(bottom,0,9,"hack")
top=applyrange(bottom,20,25,"hack")


function hack(clip bottom)
{
top=avisource("path to blurred avi")
return overlay(bottom,top)
}

bottom+top
trim(28,56)

wonkey_monkey
18th February 2010, 19:13
But not in the normal way. I would like a 4:3 pattern of 7 frames. 4 frames from "bottom" video, and 3 frames from "top" video, like:

ABCD efg HIJK lmn ....and so on. the idea is to see-saw the two videos.

If I've understood you correctly, you could try:

interleave(bottom,top)
selectevery(14, 0,2,4,6, 9,11,13)


You may have to assumefps() back to the correct framerate.

David

Die*wrek*show
18th February 2010, 21:39
You know, for two lines of code I sure am impressed David! :p

It's working now. At first I tried it and it was jerky, then I hop on the main doom site to look up the definition (http://www.doom9.org/index.html?/glossary.htm) of interleave and I see what's up.

You already know, but I'll write it out in case any newbies :rolleyes: could find it useful.

I start with two videos. Both 28 frames long.

The first 7 frames of the Bottom video, written with uppercase-

ABCD EFG

The first 7 frames of the Top video, written with lowercase

abcd efg

The script you gave will produce this,

Aa Bb Cc Dd Ee Ff Gg

Which has shifted the very first top frame, "a" one frame right.

So, the select every numbers will work, to produce a 4:3 pattern but now the "3" side of the pattern is broken because if I do

Aa...Bb...Cc...Dd...Ee...Ff...Gg
0.....2.....4....6.......9....11...13

e,f,and g are giving me a frame that's ahead in time by one frame.

So, I just re-map the frames for that clip, so everything is shifted left one frame. This is what I used.


bottom=avisource("path to nonblurred avi")
top=avisource("path to blurred avi").trim(1,27).DuplicateFrame(26).Freezeframe(27,27,0)
interleave(bottom,top)
selectevery(14,0,2,4,6,9,11,13)

Gavino
19th February 2010, 13:05
So, the select every numbers will work, to produce a 4:3 pattern but now the "3" side of the pattern is broken because if I do

Aa...Bb...Cc...Dd...Ee...Ff...Gg
0.....2.....4....6.......9....11...13

e,f,and g are giving me a frame that's ahead in time by one frame.
I don't get what you're saying here, since e, f and g correspond to the same times (in the original clips) as E, F and G.

So, I just re-map the frames for that clip, so everything is shifted left one frame. This is what I used.

bottom=avisource("path to nonblurred avi")
top=avisource("path to blurred avi").trim(1,27).DuplicateFrame(26).Freezeframe(27,27,0)
interleave(bottom,top)
selectevery(14,0,2,4,6,9,11,13)

So you end up with ABCD fgh which seems to skip a frame (as well as repeating frame 1 of 'top' at the end) .
Or is it just that the original clips are out of phase by one frame? :confused:

Die*wrek*show
19th February 2010, 18:28
That's what you call avisynth berzerker mode. Caused from lack of sleep, and staring at the same script for 10+ hours.


Well I'm sorry, I can erase my post if necessary.

Interleave does indeed put the 5th frame of the top video one frame ahead in time of 5th frame of the bottom video. But it doesn't matter where the frame is when selectevery hits it, because as it selects, it is putting them in the right place.

Right?

Oh, and I never thanked david. Thanks for the help!


edit: edited a typo

Gavino
19th February 2010, 18:44
Weave [I guess you mean Interleave] does indeed put the 5th frame of the top video one frame ahead in time of 5th frame of the bottom video. But it doesn't matter where the frame is when selectevery hits it, because as it selects, it is putting them in the right place.
Right?
Yes, exactly.