Log in

View Full Version : mdegrain like filtering


Terka
1st September 2009, 21:18
when doing mo-compensation, i can use external denoiser:

interleave(forward_compensation, last, backward_compensation)
DeGrainMedian()
selectevery(3,1)

or mdegrain

could mdegrain be somehow used same way (without computing the vectors again)

interleave(forward_compensation, last, backward_compensation)
mdegrain1()
selectevery(3,1)

lets say another way:
have same frame processed by 3 different denoisers
fa,fb,f3. want to do some 'averaging them' like mdegrain, but because they are the same frame, the vectors are (0,0)

interleave(fa, fb, f3)
mdegrain1()
selectevery(3,1)

IS THIS SOMEHOW POSSIBLE, OR EXISTS SOME VERY SIMILAR FILTER LIKE MDEGRAINX?

thewebchat
1st September 2009, 22:24
Why not just call DeGrainMedian again? MDeGrain just averages frames produced by MAnalyse/Compensate.

Terka
1st September 2009, 22:30
the vectors are different, they are (0,0)

Sagekilla
1st September 2009, 22:39
You could probably get away with simple averaging in that case.

I don't know the specifics of how MDegrain works internally, but I believe what it does is it tries to line up the 3 frames (back_comp, current, forward_comp) and do some averaging on them.

If you wanna be really lazy (and slow, for that matter), you could do some averaging with mt_lutxyz (may be wrong):


a = src.some_filter()
b = src.some_filter()
c = src.some_filter()

new = mt_lutxyz(a, b, c, "a b + c + 3 /")



Here's the actual MDegrain1 code that does the luma averaging:

pDst[x] = (pRefF[x]*WRefF + pSrc[x]*WSrc + pRefB[x]*WRefB + 128)>>8



or in other words:

src = src * w_src
F = f_comp * weight_f
B = b_comp * weight_b

frame = (src + F + B + 128) / 256

Terka
2nd September 2009, 08:30
im asking because imho mdegrain does not simple overlay or somehow averge the 3 frames, but is 'calming' the moving grain.
So if there is some object moving up/dn up/dn, after mdegrain it
becomes some position in between and the 'jumping' is away. Without much blurring the object.

Didée
2nd September 2009, 09:45
The story of a little boy who once stamped his foot, and in that very moment there happened to be a power failure in the whole city.

The little boy wondered what a magic foot he had.

Didée
2nd September 2009, 12:43
Ah, the server is up again.

Less allegory:

MDegrain indeed does "simple" averaging of mo-comped frames, just that each pixel is weighted according to the SAD of the block which the pixel lives in. That's all. Not more, not less.
*Basically*, MDegrain will *not* calm any moving/trembling objects, since the motion search will follow that motion. (When MDegrain in practice does do so nonetheless, then it is a sign of "failed" motion match, e.g. when there's a tiny object in a large block, like when using a blksize of 32x32.) (And in case of TGMC, the stage0 filtering does remove trembling on purpose, so that the motion search definetly won't snap-in on that trembling.)
_____

Averaging several clips-or-filters can be done with

- Merge() (a little inprecise for more than 2 clips)

- Interleave(c1,c2,...,cN).Temporalsoften([(N-1)/2],255,255).SelectEvery(N,(N-1)/2)
(only for odd numbers of clips)

or, most versatile and precise, with

- Average() (plugin by mg262, hope he's well)

_____

Terka, you're posing quite nebulous questions. First it's about "interleaving MDegrain1", then about "averaging of filters", then about calming trembling objects.

It's pretty hard to answers questions, when the only clear fact is that the goal behind the question is not clear.

Try to be more clear about what and why you want to do. From the very start.

Terka
2nd September 2009, 15:20
1.thank for the answer.

2.mdegrain
for me it looked like mdegrain wasnot blurring, overlayering, but calming the flicker; moving the grain to some 'central position', when it was trembling.

3.So i wanted to try following:
1 frame processed through 3 different filters.
every filter has some 'own' denoising effect and some artefacts
at the end i wanted to put the 3 resuts to 1 frame.
But i wanted something more sofisticated than
x=overlay(a,b, opacity=0.5)
overlay(x,c, opacity=0.3)
so because of 2) i wanted to use mdegrain. Didnot know about the weights.

4. the TGMC thing, if i understand it is in simplicity denoising using mdegrain, where prefiltered clip for better motion search.
temporalsoften removes the noise for better motion search and
the powerful denoiser which is able to denoise the interlace flicker is mdegrain.

5. when compared to TGMC
a)TGMC(TGMC) is not better
b)TGMC(mv/mcbob) is not better
c)TGMC (TGMC joined with original fields) is not better
d) want give to TGMC some less flickering input by following:
trying to keep the original='correct' lines:
calm only the missing data added with bob (bff):
clp.bob(0,0.5).separatefileds().selectevery(4,1,2)
calm_similar_to_TG () #(predenoised mdegrain)
so the new data wont flicker so much.
Put the calmed result together with original fields
But the flicker will still be presend because calmed different lines (upper/lower).
So the result does less flicker, but has shifted filtered lines.
shift the filtered lines to 'more correct' position.
maybee using bob(0,x) for prefiltering, after that bob(0,y) for mdegrain (but in some of your reply you didnot recommend something similar to this)

Sagekilla
3rd September 2009, 19:32
2.mdegrain
for me it looked like mdegrain wasnot blurring, overlayering, but calming the flicker; moving the grain to some 'central position', when it was trembling.

Again, if you read the code I posted (and what Didee said for that matter), MDegrain is not doing anything special at all. It's nothing more than a weighted average.

That code above does nothing but take an input pixel, weight it according to SAD, sum it up with the forward and backward references and average.


3.So i wanted to try following:
1 frame processed through 3 different filters.
every filter has some 'own' denoising effect and some artefacts
at the end i wanted to put the 3 resuts to 1 frame.
But i wanted something more sofisticated than
x=overlay(a,b, opacity=0.5)
overlay(x,c, opacity=0.3)
so because of 2) i wanted to use mdegrain. Didnot know about the weights.


If you want to average, use the plugin Didee suggested (Average).


4. the TGMC thing, if i understand it is in simplicity denoising using mdegrain, where prefiltered clip for better motion search.
temporalsoften removes the noise for better motion search and
the powerful denoiser which is able to denoise the interlace flicker is mdegrain.

5. when compared to TGMC
a)TGMC(TGMC) is not better
b)TGMC(mv/mcbob) is not better
c)TGMC (TGMC joined with original fields) is not better
d) want give to TGMC some less flickering input by following:
trying to keep the original='correct' lines:
calm only the missing data added with bob (bff):
clp.bob(0,0.5).separatefileds().selectevery(4,2,3)
calm_similar_to_TG () #(predenoised mdegrain)
so the new data wont flicker so much.
Put the calmed result together with original fields
But the flicker will still be presend because calmed different lines (upper/lower).
So the result does less flicker, but has shifted filtered lines.
shift the filtered lines to 'more correct' position.
maybee using bob(0,x) for prefiltering, after that bob(0,y) for mdegrain (but in some of your reply you didnot recommend something similar to this)

I have no idea what you're trying to accomplish here, but it sounds like some things Didee has already discussed in the TGMC thread on why it would fail.

Didée
7th September 2009, 20:12
It's no fun to produce answers when the questions are full of tiny details with little meaning on their own, and no trace of what shall be achieved in the end. Hence, the core question is:

WHAT do you want to achieve, - or - , on WHICH problem you want to improve.

All I can see is that you are contradicting yourself, in regard to plausability of the hypothetical result.

I recapture: You want to feed TGMC
d) want give to TGMC some less flickering input by following: [...]
with some "less flickering" input.

Okay ... as of now, the least-possible flickering you can only get in a bobbed clip is: what you get from TGMC.

Then, you have found:
a)TGMC(TGMC) is not better
b)TGMC(mv/mcbob) is not better
c)TGMC (TGMC joined with original fields) is not better

To my understanding, you have used the most powerful of available tools to feed non-flickering input into TGMC, and it did not improve on your problem. Now, if that did not help, do you really expect that fiddling with some cheapo Bob(VerticalBlur=variable) will? No, it will not. Sounds like you are barking on the wrong tree ... when you want to have pears, it doesn't help to reap an apple tree.


If it's about general denoising and calming of jumping blocks (I'm extrapo-specu-lating from recent posts of you in the past), then be a treasure and say so. If it's something else, be a treasure and name it.


(If it's indeed about N.R. and jumpyblocks, the most promising way lies in direction of pre-denoising with FFT3DFilter, and wider spreading of the deltas for stage2's vectors. Eventually, the whole gaussian-thingy would have to be replaced (or at least combined) with a median-thingy at 50% strength.)

Terka
8th September 2009, 12:13
WHAT do you want to achieve
ideal:less flickering, sharp and artefact free DV deinterlace than default TGMC() (by tweaking its param. or modifying)

for now have really stable but blurry version. I got it using the TG denoising principle, applied on double-height source.

clp=avisource("c:\hj\kamera\avisynth\psi\!Psi.avi") #.Crop(left,top,-right,-bottom))
clp=clp.nnedi2(field=-2).nnedi2_rpow2(rfactor=2)
# denoise ##############################################################
calm = clp.calmI()
denoised = mo_denoiseAB (calm,clp)
########################################################################
denoised.spline36resize(720,576)

function mo_denoiseAB (clip calm,clip denoise , int "blksize", int "overlap", int "blksize", int "sharp", int "thSAD", int "refframes")
{
clp=denoise
idx = 20
blksize = default(blksize,16) # blksize value (4, 8 or 16)
overlap = default(overlap,blksize/2) # overlap value (0 to half blksize)
sharp = default(sharp,1) # 0=bilinear softest, 1=bicubic, 2=Wiener sharpest
thSAD = default(thSAD,400) # higher risks motion ghosting and swimming, lower risks blotchy denoising
refframes = default(refframes,4) # temporal radius for MVTools using the "Multi" modification by Josey Wells


vectors = calm.MVAnalyseMulti(refframes = refframes, pel = 2, blksize=blksize, overlap=overlap, sharp=sharp, idx = idx)

clp.MVDegrainMulti(vectors, refframes = refframes, thSAD = thSAD, idx = idx + 1)
return(last)
}

function calmI (clip)
{
t1 = clip.temporalsoften(1,255,255,28,2)
t2 = clip.temporalsoften(2,255,255,28,2)
t1.merge(t2,0.357).merge(clip,0.125)
return(last)
}

Didée
8th September 2009, 13:06
(I take as given that the original input is interlaced, yes?)


Well, I believe that ^that^ is pretty stable and blurry. It's pretty much a barebone version TGMC, with all repX=0, and with all re-sharpening completely disabled.

Once you start working on the sharpness from there, you will loose again the rock-stable-ness. :)


What's not quite correct-in-theory is the plain way of applying MVDegrain. That's linear averaging, not gaussian-weighted averaging. In fully static parts, where a dumb-bobbed pixel goes (may go) like 40-120-40-120-... (the dumb-bob flicker), you *need* gaussian weighting to get a stable middle value. Linear averaging of such a sequence will never be fully calm, it'll always leave residual flicker behind. A stable middle value can only be *approximated*, by taking the average over a long sequence (i.e. using lots of refframes in MVToolsMulti).


Note that I have been through all of those points, thoroughly, when I fiddled together TGMC. I don't find any new aspects in all of this. It's OK to come up with a custom-tailored script (custom-tailored to both your particular clip and your particular taste). But there is no sign of improving the general methodology of TGMC. In contrary: most of those points would *worsen* the general methodology. Which is not my interest.

Terka
8th September 2009, 13:15
yes, interlaced.
yes there is nothing new.
(But) when it this is taken to TG as searchclip, the result is better than TG() alone.
used settings (EdiMode="NNEDI2",border=false,tr2=3)
Tested on "dogs" clip only, will test it on some other.
The gaussian/linear weightning are the 2 lines beginning with
t3=mt_lutxy?

Didée
8th September 2009, 13:53
No. ^That^ line is the twist'n'knot that modifies the searchclip so that the holy SAD concept does not interfere with (or: obviate) the wished result.
(Nowadays this could be replaced by applying MRecalculate accordingly, which could result in a slightly more precise motion search. But back when I did TGMC, MVRecalculate was not yet available, iirc.)


The gaussian weighting is done, as denoted, in
# create motion-compensated temporal gaussian blur
stage1 = (tr1==0) ? edi
\ : (tr1==1) ? mvdg1.merge(edi,0.25)
\ : mvdg1.merge(mvdg2,0.2).merge(edi,0.0625)

to prevent possible confusion: some will note that the averaging for the motion-compensated processing (above) is different from the averaging for the not-compensated processing:
# construct temporal gaussian average from linear averages
t = (tr0==0) ? dbob
\ : (tr0==1) ? t1.merge(dbob,0.25)
\ : t1.merge(t2,0.357).merge(dbob,0.125)

That difference is simply for speed reasons: instead of averaging a 1-frame MVDG with a 2-frame MVDG, I chose to average a 1-frame-MVDG (delta=1) with a 1-frame-MVDG(delta=2), because that way is computational less expensive. That's where the different weightings come from.

Terka
8th September 2009, 14:09
aha.
i did some test on other clip and the 'upscale used - calming' put to TG looks also on the 2nd clip better than without upscale.