Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion.

Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules.

 

Go Back   Doom9's Forum > Capturing and Editing Video > Avisynth Usage

Reply
 
Thread Tools Search this Thread Display Modes
Old 18th February 2007, 16:25   #1  |  Link
Morte66
Flying Skull
 
Morte66's Avatar
 
Join Date: Jan 2005
Posts: 397
MVDenoise vs MVDegrain1/2

Lately I've been trying out MVTools, mostly for denoising. And one thing is puzzling me: what's the difference in intent between MVDegrain1/2 and MVDenoise? Obviously they have slightly different parameters, and MVDenoise goes faster whilst AFAICT MVDegrain generally does more. But other than that, are they meant for different applications? Or is MVDegrain just a more sophisticated solution to the same problem?

Do they tackle different issues, e.g. one for pixel-sized random noise and the other for patterened film grain or something like that?

How would you decide which to use, apart from trial and error?

Would it ever make sense to use both?

This might have an answer so simple that nobody felt they needed to put it in the docs, but indulge me...
Morte66 is offline   Reply With Quote
Old 18th February 2007, 16:42   #2  |  Link
Terranigma
*Space Reserved*
 
Terranigma's Avatar
 
Join Date: May 2006
Posts: 953
Mvdegrain removes both grain and noise.
using mvdenoise from my experiences, seemed to have introduced blocks in certain frames. I've never gotten that using mvdegrain, so I'd prefer mvdegrain2 over mvdenoise any day.
Terranigma is offline   Reply With Quote
Old 18th February 2007, 17:30   #3  |  Link
*.mp4 guy
Registered User
 
*.mp4 guy's Avatar
 
Join Date: Feb 2004
Posts: 1,350
It roughly breaks down to mvdegrain2>mvdegrain1>mvdenoise both in quality/effectiveness and speed. Otherwise they all do more or less the same thing, infact the only difference between mvdegrain 1 and 2 is the amount of motion compensation used (2 uses more). mvdegrain1/2 doesn't ever introduce blocking (in my experience) while mvdenoise can.
*.mp4 guy is offline   Reply With Quote
Old 18th February 2007, 17:55   #4  |  Link
Didée
Registered User
 
Join Date: Apr 2002
Location: Germany
Posts: 5,390
The lesser blocking of MVDegrain is most probably due to the fact that MVDegrain can work with overlapped blocks. MVDenoise can not. (MVDenoise was there long time before overlapped-blocks operations were introduced by Fizick.)

Methodology of operation:

- MVDenoise does a plain temporal averaging of the compensated frames.

- MVDegrain: We don't know what it's doing exactly, Fizick never told us. *cough*. (In the sources, the interesting parts are assembler code.)
Some kind of temporal median filtering is supposed to be involved, that's all that can be said. Until Fizick reveals the "secret", that is.

(You may call me an oddball, but that's the main reason I don't use MVDegrain. It's a black box, and about black boxes I've ranted in the past already ...)
__________________
- We´re at the beginning of the end of mankind´s childhood -

My little flickr gallery. (Yes indeed, I do have hobbies other than digital video!)
Didée is offline   Reply With Quote
Old 18th February 2007, 19:16   #5  |  Link
Morte66
Flying Skull
 
Morte66's Avatar
 
Join Date: Jan 2005
Posts: 397
Quote:
Originally Posted by Didée View Post
The lesser blocking of MVDegrain is most probably due to the fact that MVDegrain can work with overlapped blocks. MVDenoise can not.
That's what I've found. My interest in MVTools started with a degrain/deblock routine M4G gave me for a really bad DVD:
Code:
source = last
backward_vec2 = source.MVAnalyse(isb = true, delta = 2, pel = 2, overlap=4, sharp=2, idx = 1, truemotion=true)
backward_vec1 = source.MVAnalyse(isb = true, delta = 1, pel = 2, overlap=4, sharp=2, idx = 1, truemotion=true)
forward_vec1 = source.MVAnalyse(isb = false, delta = 1, pel = 2, overlap=4, sharp=2, idx = 1, truemotion=true)
forward_vec2 = source.MVAnalyse(isb = false, delta = 2, pel = 2, overlap=4, sharp=2, idx = 1, truemotion=true)
mask = mvmask(kind=1, vectors=forward_vec1).UtoY().spline36resize(720,576)#its very important that this line matches the resolution you are feeding the script with
smooth = source.degrainmedian(mode=3).fft3dfilter(bt=3, sigma=4, plane=0)
source2 = maskedmerge(source, smooth, mask)
source2.MVDegrain2(backward_vec1,forward_vec1,backward_vec2,forward_vec2,thSAD=400,idx=1)
That's great but very slow, about 1.75fps for 720x576 on my A64 X2 3800+. So I started looking at Deblock_QED with MVDenoise, MVDegrain1/2 or fft3dgpu, hoping it would work out for normal quality DVDs where the blocking is not due to motion in the content.

I got Deblock_QED and non-overlapped MVDegrain1 working pretty nicely at about 5-6fps, and at first I thought I had 80% of the results for 30% of the CPU. But it turns out that it breaks up into clusters of blocks on certain patterns and motion (check clothing is a particular culprit). The same material has no blocking with ffd3dgpu, but it doesn't look so pleasing to me. I'm going to try MVDegrain with overlapping next.

Last edited by Morte66; 18th February 2007 at 19:34.
Morte66 is offline   Reply With Quote
Old 18th February 2007, 19:27   #6  |  Link
Boulder
Pig on the wing
 
Boulder's Avatar
 
Join Date: Mar 2002
Location: Hollola, Finland
Posts: 4,292
Quote:
Originally Posted by Didée View Post
- MVDegrain: We don't know what it's doing exactly, Fizick never told us. *cough*. (In the sources, the interesting parts are assembler code.)
Some kind of temporal median filtering is supposed to be involved, that's all that can be said. Until Fizick reveals the "secret", that is.
I've always thought that MVDegrain is DeGrainmedian on steroids..just better motion compensation perhaps?
__________________
And if the band you're in starts playing different tunes
I'll see you on the dark side of the Moon...
Boulder is online now   Reply With Quote
Old 18th February 2007, 22:11   #7  |  Link
Fizick
AviSynth plugger
 
Fizick's Avatar
 
Join Date: Nov 2003
Location: Russia
Posts: 2,183
Well,
I complitely with you, Didee! I do not use any of your scripts, because I do not understand them.

Do you really try read C source code?
Interesting part of code does not contain any assembler.
Here is simple description:

MVdenoise uses hard thresholding. If SAD is above thSAD threshold, or motion vector length is above some thMV threshold, this compensated block is not used. If no, source block is used instead (in averaging). Result pixel is average of all compensated pixels of good blocks with difference from source pixel below third Temporal threshold (and source included).

MVDegrain uses soft thresholding. If SAD is above threshold, this block is not used. If SAD is below threshold, its weight is equal to (Threshold-SAD). Result is (normalized) weighted sum of blocks (several frames and source).
Second difference is overlapping in MVDegrain.
__________________
My Avisynth plugins are now at http://avisynth.org.ru and mirror at http://avisynth.nl/users/fizick
I usually do not provide a technical support in private messages.

Last edited by Fizick; 19th February 2007 at 06:15. Reason: Corrected mvdenoise description
Fizick is offline   Reply With Quote
Old 19th February 2007, 00:43   #8  |  Link
Didée
Registered User
 
Join Date: Apr 2002
Location: Germany
Posts: 5,390
Quote:
Originally Posted by Fizick View Post
Well,
I complitely with you, Didee! I do not use any of your scripts, because I do not understand them.
Fair enough! (For the joke.)

However, it is not quite the same:
A user of Avisynth is supposed to understand its script language. (hence figuring a script's workflow can be expected.)
However, an avisynth user is not necessarily supposed to understand C language! (and being unsure about some small syntactical things can be enough to drive you into confusion & not-understanding.)

Therefore, I dare to say that my reasoning is more traceable than yours.

Joking apart: Thanks for the short summation. So, MVDegrain basically is doing just weighted averaging? Interesting.The weighting and overlapping stuff was clear, that was mentioned in the past. But not the averaging thingy ... the "degrain" in the filter name made me think that some median-like clipping would be used. My wrong.
Now I see that MVDegrain is more primitive than I thought it would be.

Well, if so, then Boulder's assumption of
Quote:
I've always thought that MVDegrain is DeGrainmedian on steroids..just better motion compensation perhaps?
can be answered with "no". Clipping and averaging are two different pairs of shoes.


@ Morte66:

Assuming that idx handling of MVDegrain is working as expected, your script is wrong.

First, you're doing halfpel vector search on 'source', with "idx=1". (Now, idx=1 is "tied" to the clip 'source'.)

Then, you produce 'source2'. The result is a clip that's different from 'source'.

Lastly, you call MVDegrain on 'source2' ... BUT with idx=1. And that's where the error lies: You want MVDegrain to work on 'source2', but by specifying idx=1 you tell MVDegrain to use the halfpel interpolation of 'source'. So, effectively MVDegrain is processing 'source' instead of 'source2'.
--> You need to use "idx=2" in the MVDegrain line.
(Or any other value that's a) different from the idx in the MVAnalyze lines and, just in case, that's b) not used anywhere else in the script.)


Hmmh ... somehow, somewhere, a more sticking-out explanation of the idx "problem" should be made. It's not difficult to use idx correctly, really. But somehow, it gets used wrong regularly ...
__________________
- We´re at the beginning of the end of mankind´s childhood -

My little flickr gallery. (Yes indeed, I do have hobbies other than digital video!)
Didée is offline   Reply With Quote
Old 19th February 2007, 06:20   #9  |  Link
Fizick
AviSynth plugger
 
Fizick's Avatar
 
Join Date: Nov 2003
Location: Russia
Posts: 2,183
Yes, MVDegrain is very primitive (as all genious things)
about name: is is not MVDegrainMedian.
idx is hell, i know, but it is useful.


(I corrected MVDenoise description a bit above).
__________________
My Avisynth plugins are now at http://avisynth.org.ru and mirror at http://avisynth.nl/users/fizick
I usually do not provide a technical support in private messages.

Last edited by Fizick; 19th February 2007 at 06:23.
Fizick is offline   Reply With Quote
Old 19th February 2007, 12:41   #10  |  Link
Morte66
Flying Skull
 
Morte66's Avatar
 
Join Date: Jan 2005
Posts: 397
Quote:
Originally Posted by Didée View Post
@ Morte66:

Assuming that idx handling of MVDegrain is working as expected, your script is wrong.

First, you're doing halfpel vector search on 'source', with "idx=1". (Now, idx=1 is "tied" to the clip 'source'.)

Then, you produce 'source2'. The result is a clip that's different from 'source'.

Lastly, you call MVDegrain on 'source2' ... BUT with idx=1. And that's where the error lies: You want MVDegrain to work on 'source2', but by specifying idx=1 you tell MVDegrain to use the halfpel interpolation of 'source'. So, effectively MVDegrain is processing 'source' instead of 'source2'.
Well, the script is a "black box" I just paste it in on certain encodes, I didn't even start to understand it until this weekend.

But now I look at it... It seems to me that I'm doing MVAnalyse on source and leaving notes in idx1. Then I'm using part of the analysis to create the deblocked source2 with MaskTools (which I don't understand at all, that's for next weekend). Then I do MVDegrain on source2 using the notes from source that was stored in idx1. If source2 has the same motion as source (it's a deblocked version), would this be OK?
Morte66 is offline   Reply With Quote
Old 19th February 2007, 13:00   #11  |  Link
Morte66
Flying Skull
 
Morte66's Avatar
 
Join Date: Jan 2005
Posts: 397
Quote:
Originally Posted by Fizick View Post
Yes, MVDegrain is very primitive (as all genious things)
about name: is is not MVDegrainMedian.
So this is why the docs include an example of motion compensation for external denoisers...
Code:
source=last
backward_vectors = source.MVAnalyse(isb = true, truemotion=true, delta = 1, idx = 1)
# we use explicit idx for more fast processing
forward_vectors = source.MVAnalyse(isb = false, truemotion=true, delta = 1, idx = 1)
forward_compensation = source.MVFlow(forward_vectors, idx=1, thSCD1=500) # or use MVCompensate 
backward_compensation = source.MVFlow(backward_vectors, idx=1, thSCD1=500) # or use MVCompensate 
# create interleaved 3 frames sequences
interleave(forward_compensation, source, backward_compensation) 
DeGrainMedian() # place your preferred temporal (spatial-temporal) denoiser here
return selectevery(3,1) # return filtered central (not-compensated) frames only
Morte66 is offline   Reply With Quote
Old 19th February 2007, 13:33   #12  |  Link
Didée
Registered User
 
Join Date: Apr 2002
Location: Germany
Posts: 5,390
Quote:
Originally Posted by Morte66 View Post
But now I look at it... It seems to me that I'm doing MVAnalyse on source and leaving notes in idx1. Then I'm using part of the analysis to create the deblocked source2 with MaskTools (which I don't understand at all, that's for next weekend). Then I do MVDegrain on source2 using the notes from source that was stored in idx1. If source2 has the same motion as source (it's a deblocked version), would this be OK?
Practical answer: Try this:

Code:
source = last
source2 = source.flipvertical()

backward_vec2 = source.MVAnalyse(isb = true,  delta = 2, pel = 2, overlap=4, sharp=1, idx = 1)
backward_vec1 = source.MVAnalyse(isb = true,  delta = 1, pel = 2, overlap=4, sharp=1, idx = 1)
forward_vec1  = source.MVAnalyse(isb = false, delta = 1, pel = 2, overlap=4, sharp=1, idx = 1)
forward_vec2  = source.MVAnalyse(isb = false, delta = 2, pel = 2, overlap=4, sharp=1, idx = 1)

source2.MVDegrain2(backward_vec1,forward_vec1,backward_vec2,forward_vec2,thSAD=400,idx=1)
This should convince you that something is fishy when not using idx as I told.
__________________
- We´re at the beginning of the end of mankind´s childhood -

My little flickr gallery. (Yes indeed, I do have hobbies other than digital video!)
Didée is offline   Reply With Quote
Old 19th February 2007, 13:35   #13  |  Link
*.mp4 guy
Registered User
 
*.mp4 guy's Avatar
 
Join Date: Feb 2004
Posts: 1,350
Didée, I made that script, so It should be me you blame, not Morte66. Secondly you are right about idx, I know what it does, but it must have slipped past me =/. Which means that the processed source isn't doing anything in particular, which would go against the test results I got, I'll have to see whats going on.
*.mp4 guy is offline   Reply With Quote
Old 19th February 2007, 13:40   #14  |  Link
Morte66
Flying Skull
 
Morte66's Avatar
 
Join Date: Jan 2005
Posts: 397
Quote:
Originally Posted by Didée View Post
Practical answer: Try this:

Code:
source = last
source2 = source.flipvertical()

backward_vec2 = source.MVAnalyse(isb = true,  delta = 2, pel = 2, overlap=4, sharp=1, idx = 1)
backward_vec1 = source.MVAnalyse(isb = true,  delta = 1, pel = 2, overlap=4, sharp=1, idx = 1)
forward_vec1  = source.MVAnalyse(isb = false, delta = 1, pel = 2, overlap=4, sharp=1, idx = 1)
forward_vec2  = source.MVAnalyse(isb = false, delta = 2, pel = 2, overlap=4, sharp=1, idx = 1)

source2.MVDegrain2(backward_vec1,forward_vec1,backward_vec2,forward_vec2,thSAD=400,idx=1)
This should convince you that something is fishy when not using idx as I told.
Now I would expect that to fail, because you've done a FlipVertical rather than a deblocking. Of course source2 would have different motion from source in that case, and using the same motion vector analysis would be a disaster.

Whereas it seems that it might work if source2 is a deblocked version of source, with the same content motion.

I think what I need to do is compare is the original script against something like this...
Code:
#deblock
mask_source = last
mask_forward_vec1 = mask_source.MVAnalyse(isb = false, delta = 1, pel = 2, overlap=4, sharp=2, idx = 1, truemotion=true)
mask = mvmask(kind=1, vectors=mask_forward_vec1).UtoY().spline36resize(720,576)
mask_smooth = mask_source.degrainmedian(mode=3).fft3dfilter(bt=3, sigma=4, plane=0)
maskedmerge(mask_source, mask_smooth, mask)

#completely separate degrain
source = last
backward_vec2 = source.MVAnalyse(isb = true, delta = 2, pel = 2, overlap=4, sharp=2, idx = 2, truemotion=true)
backward_vec1 = source.MVAnalyse(isb = true, delta = 1, pel = 2, overlap=4, sharp=2, idx = 2, truemotion=true)
forward_vec1 = source.MVAnalyse(isb = false, delta = 1, pel = 2, overlap=4, sharp=2, idx = 2, truemotion=true)
forward_vec2 = source.MVAnalyse(isb = false, delta = 2, pel = 2, overlap=4, sharp=2, idx = 2, truemotion=true)
source.MVDegrain2(backward_vec1,forward_vec1,backward_vec2,forward_vec2,thSAD=400,idx=2)

Last edited by Morte66; 19th February 2007 at 14:20.
Morte66 is offline   Reply With Quote
Old 19th February 2007, 13:50   #15  |  Link
Didée
Registered User
 
Join Date: Apr 2002
Location: Germany
Posts: 5,390
I just wanted to make clear that with wrong idx usage like

Code:
green = something
red   = green.process(make_reddish)

vectors1/2/3/4 = green.MVanalyze(...,pel=2,idx=1)

result = red.MVDegrain2(vectors1/2/3/4, idx=1) # idx=1 is incorrect
you end up with a mix of (1*green + 4*red)/5

In your case, you would've created a deblocked clip, and get a mix of 20% deblocked and 80% not-deblocked.

It might not look obviously borked, but it *is* wrong. My radical example shows what's *really* happening then.
__________________
- We´re at the beginning of the end of mankind´s childhood -

My little flickr gallery. (Yes indeed, I do have hobbies other than digital video!)
Didée is offline   Reply With Quote
Old 19th February 2007, 15:40   #16  |  Link
Morte66
Flying Skull
 
Morte66's Avatar
 
Join Date: Jan 2005
Posts: 397
Quote:
Originally Posted by Didée View Post
I just wanted to make clear that with wrong idx usage like

Code:
green = something
red   = green.process(make_reddish)

vectors1/2/3/4 = green.MVanalyze(...,pel=2,idx=1)

result = red.MVDegrain2(vectors1/2/3/4, idx=1) # idx=1 is incorrect
you end up with a mix of (1*green + 4*red)/5

In your case, you would've created a deblocked clip, and get a mix of 20% deblocked and 80% not-deblocked.

It might not look obviously borked, but it *is* wrong. My radical example shows what's *really* happening then.
Ha, got it. I need a smiley for "lightbulb over head". This one will have to do...

Morte66 is offline   Reply With Quote
Old 19th February 2007, 19:07   #17  |  Link
Morte66
Flying Skull
 
Morte66's Avatar
 
Join Date: Jan 2005
Posts: 397
After a few more comparisons, I think that the thing I like best about MVDegrain2 us the way it reduces block/macroblick-sized flickery stuff in mpeg2.[1] It has worked wonders for my "Northern Exposure" DVDs.

I wondered whether this is becaue it has a longer timebase (five frames) than most denoisers I use (fft3d, DegrainMedian, FrFun). So I tried an experiment, using MVAnalyse/MVFlow to wrap fft3dgpu, which can be used at 2/3/4 frame durations. Example:
Code:
source=last
forward_vectors = source.MVAnalyse(isb = false, truemotion=true, overlap=4, delta = 1, idx = 3)
backward_vectors = source.MVAnalyse(isb = true, truemotion=true, overlap=4, delta = 1, idx = 3)
backward_vectors2 = source.MVAnalyse(isb = true, truemotion=true, overlap=4, delta = 2, idx = 3)
forward_compensation = source.MVFlow(forward_vectors, idx=3, thSCD1=500) # or use MVCompensate 
backward_compensation = source.MVFlow(backward_vectors, idx=3, thSCD1=500) # or use MVCompensate 
backward_compensation2 = source.MVFlow(backward_vectors2, idx=3, thSCD1=500) # or use MVCompensate 
interleave(forward_compensation, source, backward_compensation,backward_compensation2) 
fft3dgpu(bw=16, bh=16, bt=4, sigma=1, plane=4, precision=1)
selectevery(4,1) # return filtered original (not-compensated) frames only
As the timebase gets longer, I see a small reduction in the random-looking noise (the short filter pretty much killed it), plus a progressive reduction in flicker. It also seems that DegrainMedian and fft3d are less prone to occasional blocking than MVDegrain1/2 if you don't use Overlap, which keeps the speed up.

Since flickery stuff really gets on my nerves, this is great news.

I'd like to try motion compensating a longer (spatial-)temporal denoiser. The only one I'm familiar with is FluxSmooth(S)T. Does anybody have any other favourites I ought to try?

{edit p.s. mocomped fft3dgpu is gorgeous, and slow but not impossibly slow}

--
[1] Not the same as purely oscillatory noise from analogue video tape, e.g. "Roseanne", which I think is better tackled with ReduceFlicker(Strength=1).

Last edited by Morte66; 19th February 2007 at 19:20.
Morte66 is offline   Reply With Quote
Old 19th February 2007, 19:53   #18  |  Link
*.mp4 guy
Registered User
 
*.mp4 guy's Avatar
 
Join Date: Feb 2004
Posts: 1,350
try ttempsmooth(maxr=7), its pure temporal, but it takes 15 frames into account(maxr=7==max temporal radius of 7). Its very good at avoiding averaging in moving areas, so it should be artifact resistent.
*.mp4 guy is offline   Reply With Quote
Old 20th February 2007, 02:23   #19  |  Link
Pookie
Registered User
 
Join Date: Apr 2005
Posts: 1,339
Morte66 - my eyes are sensitive to certain types of flicker as well. Kasandro's Reducefluctuations(limit=2) from his ReduceFlicker plugin is pretty good. Just don't go beyond limit=2 otherwise it can create artifacts.

fluxsmooth seems to calm things down as well, especially on deinterlaced video.

*.mp4 guy - thanks for the info. I'll try that out soon
Pookie is offline   Reply With Quote
Old 20th February 2007, 05:45   #20  |  Link
grannyGeek
Registered User
 
Join Date: Apr 2006
Posts: 81
I would love to try out ReduceFlicker, but the links I found from searching seem to be broken

http://www.reduceflicker.de.tf/
http://home.arcor.de/kassandro/Reduc...uceFlicker.htm


Maybe they are obsolete.

Does anyone have a working link, or can upload a copy somewhere?

Thanks for any help.
grannyGeek is offline   Reply With Quote
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 14:21.


Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.