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. |
18th February 2007, 16:25 | #1 | Link |
Flying Skull
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... |
18th February 2007, 16:42 | #2 | Link |
*Space Reserved*
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. |
18th February 2007, 17:30 | #3 | Link |
Registered User
Join Date: Feb 2004
Posts: 1,348
|
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.
|
18th February 2007, 17:55 | #4 | Link |
Registered User
Join Date: Apr 2002
Location: Germany
Posts: 5,389
|
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!) |
18th February 2007, 19:16 | #5 | Link | |
Flying Skull
Join Date: Jan 2005
Posts: 397
|
Quote:
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) 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. |
|
18th February 2007, 19:27 | #6 | Link | |
Pig on the wing
Join Date: Mar 2002
Location: Finland
Posts: 5,718
|
Quote:
__________________
And if the band you're in starts playing different tunes I'll see you on the dark side of the Moon... |
|
18th February 2007, 22:11 | #7 | Link |
AviSynth plugger
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 |
19th February 2007, 00:43 | #8 | Link | ||
Registered User
Join Date: Apr 2002
Location: Germany
Posts: 5,389
|
Quote:
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:
@ 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!) |
||
19th February 2007, 06:20 | #9 | Link |
AviSynth plugger
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. |
19th February 2007, 12:41 | #10 | Link | |
Flying Skull
Join Date: Jan 2005
Posts: 397
|
Quote:
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? |
|
19th February 2007, 13:00 | #11 | Link | |
Flying Skull
Join Date: Jan 2005
Posts: 397
|
Quote:
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 |
|
19th February 2007, 13:33 | #12 | Link | |
Registered User
Join Date: Apr 2002
Location: Germany
Posts: 5,389
|
Quote:
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)
__________________
- 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!) |
|
19th February 2007, 13:35 | #13 | Link |
Registered User
Join Date: Feb 2004
Posts: 1,348
|
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.
|
19th February 2007, 13:40 | #14 | Link | |
Flying Skull
Join Date: Jan 2005
Posts: 397
|
Quote:
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. |
|
19th February 2007, 13:50 | #15 | Link |
Registered User
Join Date: Apr 2002
Location: Germany
Posts: 5,389
|
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 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!) |
19th February 2007, 15:40 | #16 | Link | |
Flying Skull
Join Date: Jan 2005
Posts: 397
|
Quote:
|
|
19th February 2007, 19:07 | #17 | Link |
Flying Skull
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 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. |
20th February 2007, 02:23 | #19 | Link |
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 |
20th February 2007, 05:45 | #20 | Link |
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. |
Thread Tools | Search this Thread |
Display Modes | |
|
|