Log in

View Full Version : Improving compressibility of grainy sources with little to no visual impact - ideas?


mandarinka
15th January 2012, 23:55
As the subject says... I'd like to hear people's ideas or tricks you use for encoding grainy sources when the goal is to preserve the look. Something like denoising without the effects being visible.

I know that one can use encoding tools like psy trellis, but relying on x264's abilities means that the cost of keeping the grain (or something that looks similar to the original grain) is simply there, compromising the amount of bits we can spend on detail that is underneath that grain.
That's why I'd like to hear your ideas on how to actually make a grainy source compress (even just slightly) better, so that the overall quality can be improved. As said, I'm interested in such filtering that would have as little visual impact as possible.

Some approaches that come to my mind: for example, separating noise and softening it a little bit before adding back; or alternatively some denoising that would only remove faint noise while keeping the coarser, more rough part of it. I assume the latter might be able to preserve the look of film grain, but such effect might actually be partially realised by the encoding itself, so this might not be successful in practice.

P.S.:
Thanks for your input :)

Didée
16th January 2012, 00:38
Just these days, I plugged a little script with a similar goal: dampen the grain just a little, to keep the original look, and make it fast, because it's kind of PITA if a sluggish script does almost nothing. (And in particular when it's plenty of seasons with plenty of episodes...)

I took Spresso, and extended the spatial principle to temporal, using Fluxsmooth. The basic chain

Spresso(4,24,2).STpresso(4,24,4,12,3,49,1)

dropped the resulting bitrate (CRF19.5 on a quite grainy 720p stream) from ~6000kbps to ~5000kbps. That's -16%, depending on settings you can expect -5% to -20%.

The script is pretty fast, speed hit is neglectible. (Eventually, the encoding even may go faster, due to the grain becoming "easier".)


function STPresso(clip clp, int "limit", int "bias", int "RGmode", int "tthr", int "tlimit", int "tbias", int "back")
{
limit = default( limit, 3 ) # spatial limit: the spatial part won't change a pixel more than this
bias = default( bias, 24 ) # bias: the percentage of the spatial filter that will apply
RGmode = default( RGmode, 4 ) # the spatial filter is RemoveGrain, this is its mode
tthr = default( tthr, 12 ) # temporal threshold for fluxsmooth. Can be set "a good bit bigger" than usually
tlimit = default( tlimit, 3 ) # the temporal filter won't change a pixel more than this
tbias = default( tbias, 49 ) # the percentage of the temporal filter that will apply
back = default( back, 1 ) # after all changes have been calculated, reduce all pixel changes by this value. (Shift "back" towards original value)

LIM1 = (limit>0) ? string( round(limit*100.0/bias-1.0) ) : string( round(100.0/bias) )
LIM2 = (limit<0) ? "1" : string(limit)
BIA = string(bias)
BK = string(back)
TLIM1 = (tlimit>0) ? string( round(tlimit*100.0/tbias-1.0) ) : string( round(100.0/tbias) )
TLIM2 = (tlimit<0) ? "1" : string(tlimit)
TBIA = string(tbias)

expr = (limit<0) ? "x y - abs "+LIM1+" < x x 1 x y - x y - abs / * - ?"
\ : "x y - abs 1 < x x "+LIM1+" + y < x "+LIM2+" + x "+LIM1+" - y > x "+LIM2+" - " \
+ "x 100 "+BIA+" - * y "+BIA+" * + 100 / ? ? ?"
texpr = (limit<0) ? "x y - abs "+TLIM1+" < x x 1 x y - x y - abs / * - ?"
\ : "x y - abs 1 < x x "+TLIM1+" + y < x "+TLIM2+" + x "+TLIM1+" - y > x "+TLIM2+" - " \
+ "x 100 "+TBIA+" - * y "+TBIA+" * + 100 / ? ? ?"

bzz = clp.removegrain(RGmode)
mt_lutxy( clp, bzz, expr, U=3,V=3)
tthr==0 ? last : mt_lutxy(last,last.mt_makediff(mt_makediff(bzz,bzz.fluxsmootht(tthr),U=3,V=3),U=3,V=3),texpr,U=3,V=3)
back==0 ? last : mt_lutxy(last,clp,"x "+BK+" + y < x "+BK+" + x "+BK+" - y > x "+BK+" - y ? ?",U=2,V=2)
}

The spatial part might be a bit too narrow for 1080p encoding (since it's only a 3x3 kernel). It did fit quite well for 720p encoding, though.

mastrboy
16th January 2012, 01:13
I usually run TTempSmoothF(strength=1,maxr=7) to increase compression without noticeable quality loss, but I've seen this create some artifacts on the luma plane on high motion scenes, using motion compensation usually solves this, but the speed will slow down quite a bit...

But considering Didée's history on this forum, his solution is more likely a better option

pandy
16th January 2012, 15:11
http://registry.gimp.org/node/11742 - can be nice if someone will implement this as a Avisynth filter...

Didée
16th January 2012, 15:51
@pandy: For the time being, you can do with FFT3dFilter or dfttest. Or generally with any spatial filter - apply a lowpass, filter the lowpassed image, re-apply the hipass.

___
edit: found a free minute.

fft3dfilter(sigma=0.01,sigma2=1,sigma3=4,sigma4=8,bw=16,bh=16,ow=8,oh=8,bt=1,plane=0)

http://thumbnails48.imagebam.com/17009/6effb4170081060.jpg (http://www.imagebam.com/image/6effb4170081060)

mandarinka
16th January 2012, 17:22
I'm testing the S(T)Presso functions and I'm pleasantly surprised :) For example, I was able to get reductions even with lowered settings that virtually 'did nothing' (which is nice, although I didn't have much time to check what it does with quality, with low differences in filesize it's hard to tell). Optimal settings would be higher, but so far I was trying it from the obsessive side of things.

What I noticed however is something I assume is fluxsmooth-related, because I recall it from DFMDerainbow: at the default tthr of 12, I was getting some artifacting in pans (can probably happen in other motion), where fluxsmooth got fooled and averaged stuff it shouldn't have (motion compensating prevented it); and also, in an animation source with colour flashes, the averages caused changes in hue in large areas (lowering tthr to about 6 made them mostly go away) or stuff like gun blazes. This probably wouldn't be issue in live action footage, and even here, the averaging shouldn't be that visible in motion, human eyes probably don't care much. I don't know what's the internal operation of fluxsmooth like, but it probably isn't very careful about chroma...

Boulder
16th January 2012, 17:50
Didée, can you please come up with a modification for 1080p sources? That function looks just like what I was looking for some time ago - improve compressibility but retain much of the detail.

pandy
16th January 2012, 19:01
@pandy: For the time being, you can do with FFT3dFilter or dfttest. Or generally with any spatial filter - apply a lowpass, filter the lowpassed image, re-apply the hipass.


As You know wavelets are bit different than FFT, also You need be very precise with FFT (describing filtered bins range) - they are always pros and cons for each method but IMHO wavelets seems to be more "analog".

librarian
16th January 2012, 19:15
Playing, like Didée posted (Or generally with any spatial filter - apply a lowpass, filter the lowpassed image, re-apply the hipass), with Vaguedenoiser, a wavelet-based spatial denoiser?

bmb
20th March 2012, 09:22
didee i cant seem to get stpresso to work ?

blvakillxxmc
20th March 2012, 09:48
Thanks,i am workinghttp://www.froco.info/smile.gif

Didée
20th March 2012, 11:47
Why not? What error message? What script?

bmb
20th March 2012, 13:39
scratch that, i sorted it, didee is their anyway of contacting you privately ?

Didée
20th March 2012, 13:54
Sure. This forum offers private message (PM) functionality.

bmb
20th March 2012, 14:11
sent u a message didee

SilaSurfer
23rd April 2012, 15:59
Just these days, I plugged a little script with a similar goal: dampen the grain just a little, to keep the original look, and make it fast, because it's kind of PITA if a sluggish script does almost nothing. (And in particular when it's plenty of seasons with plenty of episodes...)

I took Spresso, and extended the spatial principle to temporal, using Fluxsmooth. The basic chain

Spresso(4,24,2).STpresso(4,24,4,12,3,49,1)

dropped the resulting bitrate (CRF19.5 on a quite grainy 720p stream) from ~6000kbps to ~5000kbps. That's -16%, depending on settings you can expect -5% to -20%.

The script is pretty fast, speed hit is neglectible. (Eventually, the encoding even may go faster, due to the grain becoming "easier".)


function STPresso(clip clp, int "limit", int "bias", int "RGmode", int "tthr", int "tlimit", int "tbias", int "back")
{
limit = default( limit, 3 ) # spatial limit: the spatial part won't change a pixel more than this
bias = default( bias, 24 ) # bias: the percentage of the spatial filter that will apply
RGmode = default( RGmode, 4 ) # the spatial filter is RemoveGrain, this is its mode
tthr = default( tthr, 12 ) # temporal threshold for fluxsmooth. Can be set "a good bit bigger" than usually
tlimit = default( tlimit, 3 ) # the temporal filter won't change a pixel more than this
tbias = default( tbias, 49 ) # the percentage of the temporal filter that will apply
back = default( back, 1 ) # after all changes have been calculated, reduce all pixel changes by this value. (Shift "back" towards original value)

LIM1 = (limit>0) ? string( round(limit*100.0/bias-1.0) ) : string( round(100.0/bias) )
LIM2 = (limit<0) ? "1" : string(limit)
BIA = string(bias)
BK = string(back)
TLIM1 = (tlimit>0) ? string( round(tlimit*100.0/tbias-1.0) ) : string( round(100.0/tbias) )
TLIM2 = (tlimit<0) ? "1" : string(tlimit)
TBIA = string(tbias)

expr = (limit<0) ? "x y - abs "+LIM1+" < x x 1 x y - x y - abs / * - ?"
\ : "x y - abs 1 < x x "+LIM1+" + y < x "+LIM2+" + x "+LIM1+" - y > x "+LIM2+" - " \
+ "x 100 "+BIA+" - * y "+BIA+" * + 100 / ? ? ?"
texpr = (limit<0) ? "x y - abs "+TLIM1+" < x x 1 x y - x y - abs / * - ?"
\ : "x y - abs 1 < x x "+TLIM1+" + y < x "+TLIM2+" + x "+TLIM1+" - y > x "+TLIM2+" - " \
+ "x 100 "+TBIA+" - * y "+TBIA+" * + 100 / ? ? ?"

bzz = clp.removegrain(RGmode)
mt_lutxy( clp, bzz, expr, U=3,V=3)
tthr==0 ? last : mt_lutxy(last,last.mt_makediff(mt_makediff(bzz,bzz.fluxsmootht(tthr),U=3,V=3),U=3,V=3),texpr,U=3,V=3)
back==0 ? last : mt_lutxy(last,clp,"x "+BK+" + y < x "+BK+" + x "+BK+" - y > x "+BK+" - y ? ?",U=2,V=2)
}

The spatial part might be a bit too narrow for 1080p encoding (since it's only a 3x3 kernel). It did fit quite well for 720p encoding, though.

:). Great to be back after some absence, and look at that, the first thing that I find going through the forum another very interesting Didée's function. ;) This would definitely come in handy with those series like you said lots of seasons and episodes. I would just ask you Didée could you make modification to your function to Motion Compensate FluxSmooth, give it a pair of glasses , please. Thanks :p

TheProfileth
23rd April 2012, 23:11
@SilaSurfer
From what I understand the whole point of using fluxsmooth is that it works very quickly so adding motion compensation atleast proper motion compensation would probably make it a lot less viable as a "quick guiltless compression aid" then again I could be wrong and maybe proper motion compensation could be achieved while not completely ruining the speed.

SilaSurfer
25th April 2012, 15:59
@SilaSurfer
From what I understand the whole point of using fluxsmooth is that it works very quickly so adding motion compensation atleast proper motion compensation would probably make it a lot less viable as a "quick guiltless compression aid" then again I could be wrong and maybe proper motion compensation could be achieved while not completely ruining the speed.

I know it would slow down this function, but IMHO Fluxsmooth doesn't need very slow settings when using Motion compensation of MVTools2. Where it could benefit fluxsmooth is only on scene changes. It would still be faster then Mdegrain2/3, which would be ideal for as I said above for seasons of series (more practical). I will try to modify this myself when I get time. ;)

TheProfileth
25th April 2012, 21:37
I know it would slow down this function, but IMHO Fluxsmooth doesn't need very slow settings when using Motion compensation of MVTools2. Where it could benefit fluxsmooth is only on scene changes. It would still be faster then Mdegrain2/3, which would be ideal for as I said above for seasons of series (more practical). I will try to modify this myself when I get time. ;)
Hmm I was thinking, Fluxsmooth works on a 3 frame basis right? Just the previous current and next? Well if so then only minimal motion compensation is really necessary as you stated. I may consider putting together a rough demo of a mocomped fluxsmooth in the meantime if I get a chance.

Didée
25th April 2012, 21:50
The rough demo is present, since many many years, in the documentation of MVTools. Section "Usage examples". Just replace DegrainMedian with FluxSmooth.

Richard1485
29th April 2012, 19:57
Thanks, Didée. Is it possible to use FluxSmoothST() and DegrainMedian() together after using super or do you have to use super twice i.e. can you do this?

a=mpeg2source().TFM().TDecimate().Crop(0,64,0,-64)
super = a.MSuper()
backward_vectors = MAnalyse(super, isb = true)
forward_vectors = MAnalyse(super, isb = false)
forward_compensation = MFlow(a, super, forward_vectors, thSCD1=500)
backward_compensation = MFlow(a, super, backward_vectors, thSCD1=500)
b=interleave(forward_compensation, a, backward_compensation).FluxSmoothST().DeGrainMedian(limitY=5,limitUV=5,mode=3).selectevery(3,1)
return b

(I am using a and b only because I go on to apply other filters.)

Didée
29th April 2012, 20:19
For that you don't need a 2nd super-clip, but you need to increase the temporal radius. If you apply two filters in a row, each with a temporal radius of 1, then you effectively have a temporal radius of 2. (The 2nd filter calls frame N-1 from the first filter. The first filter needs N-2,N-1,N in order to deliver the frame N-1. Same for the other temporal direction.)

That makes

super = a.MSuper()
bv2 = MAnalyse(super, isb = true, delta=2)
bv1 = MAnalyse(super, isb = true, delta=1)
fv1 = MAnalyse(super, isb = false, delta=1)
fv2 = MAnalyse(super, isb = false, delta=2)
fcmp2 = MFlow(a, super, fv2, thSCD1=500)
fcmp1 = MFlow(a, super, fv1, thSCD1=500)
bcmp1 = MFlow(a, super, bv1, thSCD1=500)
bcmp2 = MFlow(a, super, bv2, thSCD1=500)
b=interleave(fcmp2,fcmp1,a,bcmp1,bcmp2).FluxSmoothST().DeGrainMedian(limitY=5,limitUV=5,mode=3).selectevery(5,2)
return b

If that's worth the effort, that's another question.

If that's too slow, the dirty trick is to extend the temporal compensation by abusing the compensations "from the other side" :
super = a.MSuper()
bv1 = MAnalyse(super, isb = true,delta=1)
fv1 = MAnalyse(super, isb = false,delta=1)
fcmp1 = MFlow(a, super, fv1, thSCD1=500)
bcmp1 = MFlow(a, super, bv1, thSCD1=500)
b=interleave(bcmp1,fcmp1,a,bcmp1,fcmp1).FluxSmoothST().DeGrainMedian(limitY=5,limitUV=5,mode=3).selectevery(5,2)
return b

In any case, I would rather use MCompensate (with block overlapping in MAnalyse), instead of MFlow. MFlow is less suited for denoising.

Richard1485
30th April 2012, 22:49
Same for the other temporal direction.)

This means if isb=false rather than true, does it?

If that's worth the effort, that's another question

I am not sure that it is worth it because, as you say, it is very slow. (I think that I understand what you mean by abusing the compensations in the dirty example.)

In any case, I would rather use MCompensate (with block overlapping in MAnalyse), instead of MFlow. MFlow is less suited for denoising.

Out of interest, what would your script be with MCompensate rather than MFlow? Is it as simple as changing MFlow to MCompensate like this?

a=Mpeg2source()
super = a.MSuper()
bv2 = MAnalyse(super, isb = true, delta=2, overlap=4)
bv1 = MAnalyse(super, isb = true, delta=1, overlap=4)
fv1 = MAnalyse(super, isb = false, delta=1, overlap=4)
fv2 = MAnalyse(super, isb = false, delta=2, overlap=4)
fcmp2 = MCompensate(a, super, fv2, thSCD1=500)
fcmp1 = MCompensate(a, super, fv1, thSCD1=500)
bcmp1 = MCompensate(a, super, bv1, thSCD1=500)
bcmp2 = MCompensate(a, super, bv2, thSCD1=500)
b=interleave(fcmp2,fcmp1,a,bcmp1,bcmp2).FluxSmoothST().DeGrainMedian(limitY=5,limitUV=5,mode=3).selectevery(5,2)
return b

It loads, but I'm not sure it's right.

Didée
1st May 2012, 00:02
Yes, simply exchange MFlow with MCompensate.

Though, I'd say that FluxsmoothST and DegrainMedian are not particularly well suited for this task anyway. Yoda said "Too spatial, they are."

SilaSurfer
2nd May 2012, 12:55
I hope I got this wrapper correctly, professor Didée do correct me if I'm wrong, I'm still green :D when it comes to writing functions.


Function FluxsmoothTMC(clip clp, int "tthr")

{

tthr = default( tthr, 12 )

super = clp.MSuper(pel=2, sharp=1)

bv1 = manalyse(super,isb=true, truemotion=false, delta=1,blksize=16,overlap=8)
fv1 = manalyse(super,Isb=false, truemotion=false, delta=1,blksize=16,overlap=8)

bc1 = mcompensate(clp, super,bv1)
fc1 = mcompensate(clp, super,fv1)

result=interleave(fc1, clp, bc1).FluxSmoothT(tthr).selectevery(3,1)

Return(result)
}


So STpresso becomes STPressoMC


function STPressoMC(clip clp, int "limit", int "bias", int "RGmode", int "tthr", int "tlimit", int "tbias", int "back")
{
limit = default( limit, 3 ) # spatial limit: the spatial part won't change a pixel more than this
bias = default( bias, 24 ) # bias: the percentage of the spatial filter that will apply
RGmode = default( RGmode, 4 ) # the spatial filter is RemoveGrain, this is its mode
tthr = default( tthr, 12 ) # temporal threshold for fluxsmooth. Can be set "a good bit bigger" than usually
tlimit = default( tlimit, 3 ) # the temporal filter won't change a pixel more than this
tbias = default( tbias, 49 ) # the percentage of the temporal filter that will apply
back = default( back, 1 ) # after all changes have been calculated, reduce all pixel changes by this value. (Shift "back" towards original value)

LIM1 = (limit>0) ? string( round(limit*100.0/bias-1.0) ) : string( round(100.0/bias) )
LIM2 = (limit<0) ? "1" : string(limit)
BIA = string(bias)
BK = string(back)
TLIM1 = (tlimit>0) ? string( round(tlimit*100.0/tbias-1.0) ) : string( round(100.0/tbias) )
TLIM2 = (tlimit<0) ? "1" : string(tlimit)
TBIA = string(tbias)

expr = (limit<0) ? "x y - abs "+LIM1+" < x x 1 x y - x y - abs / * - ?"
\ : "x y - abs 1 < x x "+LIM1+" + y < x "+LIM2+" + x "+LIM1+" - y > x "+LIM2+" - " \
+ "x 100 "+BIA+" - * y "+BIA+" * + 100 / ? ? ?"
texpr = (limit<0) ? "x y - abs "+TLIM1+" < x x 1 x y - x y - abs / * - ?"
\ : "x y - abs 1 < x x "+TLIM1+" + y < x "+TLIM2+" + x "+TLIM1+" - y > x "+TLIM2+" - " \
+ "x 100 "+TBIA+" - * y "+TBIA+" * + 100 / ? ? ?"

bzz = clp.removegrain(RGmode)
mt_lutxy( clp, bzz, expr, U=3,V=3)
tthr==0 ? last : mt_lutxy(last,last.mt_makediff(mt_makediff(bzz,bzz.FluxsmoothTMC(tthr),U=3,V=3),U=3,V=3),texpr,U=3,V=3)
back==0 ? last : mt_lutxy(last,clp,"x "+BK+" + y < x "+BK+" + x "+BK+" - y > x "+BK+" - y ? ?",U=2,V=2)
}

nibus
3rd May 2012, 12:43
^^^ what advantage would this have over regular mdegrain? Just speed?

Didée
3rd May 2012, 14:32
Good question.:) - Speed can't be the reason, since it is even a bit slower than a plain mdegrain1.

Richard1485
3rd May 2012, 19:02
Though, I'd say that FluxsmoothST and DegrainMedian are not particularly well suited for this task anyway. Yoda said "Too spatial, they are."

Thanks. In that case, I'll either use FluxSmoothT() or find another denoising filter.

mandarinka
1st June 2012, 01:40
I had good results from motion-compensating fluxsmooth when using dfmderainbow. That derainbower is rather aggressive and causes trouble in pans, discolouring huge areas. Motion-compensating the whole thing tends to help.
Though too fast, it isn't. :D

real.finder
23rd April 2020, 16:47
here an update for avs+ HBD

# STPresso by Didée, MC by SilaSurfer, r.f mod in 2020.04.23 for HBD
function STPresso(clip clp, float "limit", float "bias", int "RGmode", int "tthr", float "tlimit", float "tbias", float "back", bool "mc")
{
sisavs26 = !(VersionNumber() < 2.60)
limit = default( limit, 3 ) # spatial limit: the spatial part won't change a pixel more than this
bias = default( bias, 24 ) # bias: the percentage of the spatial filter that will apply
RGmode = default( RGmode, 4 ) # the spatial filter is RemoveGrain, this is its mode
tthr = default( tthr, 12 ) # temporal threshold for fluxsmooth. Can be set "a good bit bigger" than usually
tlimit = default( tlimit, 3 ) # the temporal filter won't change a pixel more than this
tbias = default( tbias, 49 ) # the percentage of the temporal filter that will apply
back = default( back, 1 ) # after all changes have been calculated, reduce all pixel changes by this value. (Shift "back" towards original value)
mc = default( mc, false ) #

LIM1 = (limit>0) ? string( round(limit*100.0/bias-1.0) ) : string( round(100.0/bias) )
LIM2 = (limit<0) ? "1" : string(limit)
BIA = string(bias)
BK = string(back)
TLIM1 = (tlimit>0) ? string( round(tlimit*100.0/tbias-1.0) ) : string( round(100.0/tbias) )
TLIM2 = (tlimit<0) ? "1" : string(tlimit)
TBIA = string(tbias)

expr = (limit<0) ? sisavs26 ? "x y - abs "+LIM1+" scalef < x x 1 x y - x y - abs / * - ?" : "x y - abs "+LIM1+" < x x 1 x y - x y - abs / * - ?"
\ : sisavs26 ? "x y - abs 1 scalef < x x "+LIM1+" scalef + y < x "+LIM2+" scalef + x "+LIM1+" scalef - y > x "+LIM2+" scalef - " \
+ "x 100 scalef "+BIA+" scalef - * y "+BIA+" scalef * + 100 scalef / ? ? ?" \
: "x y - abs 1 < x x "+LIM1+" + y < x "+LIM2+" + x "+LIM1+" - y > x "+LIM2+" - " \
+ "x 100 "+BIA+" - * y "+BIA+" * + 100 / ? ? ?"
texpr = (limit<0) ? sisavs26 ? "x y - abs "+TLIM1+" scalef < x x 1 x y - x y - abs / * - ?" : "x y - abs "+TLIM1+" < x x 1 x y - x y - abs / * - ?"
\ : sisavs26 ? "x y - abs 1 scalef < x x "+TLIM1+" scalef + y < x "+TLIM2+" scalef + x "+TLIM1+" scalef - y > x "+TLIM2+" scalef - " \
+ "x 100 scalef "+TBIA+" scalef - * y "+TBIA+" scalef * + 100 scalef / ? ? ?" \
: "x y - abs 1 < x x "+TLIM1+" + y < x "+TLIM2+" + x "+TLIM1+" - y > x "+TLIM2+" - " \
+ "x 100 "+TBIA+" - * y "+TBIA+" * + 100 / ? ? ?"

bzz = clp.removegrain(RGmode)
sisavs26 ? mt_lutxy( clp, bzz, expr, scale_inputs=limit<0 ? "floatf" : "none", use_expr=1, U=3,V=3) : mt_lutxy( clp, bzz, expr, U=3,V=3)
tthr==0 ? last : sisavs26 ? mt_lutxy(last,last.mt_makediff(mt_makediff(bzz,mc ? bzz.STPresso_FluxsmoothTMC(tthr) : bzz.fluxsmootht(tthr),U=3,V=3),U=3,V=3),texpr,scale_inputs=limit<0 ? "floatf" : "none",use_expr=1,U=3,V=3) : mt_lutxy(last,last.mt_makediff(mt_makediff(bzz,mc ? bzz.STPresso_FluxsmoothTMC(tthr) : bzz.fluxsmootht(tthr),U=3,V=3),U=3,V=3),texpr,U=3,V=3)
back==0 ? last : sisavs26 ? mt_lutxy(last,clp,"x "+BK+" scalef + y < x "+BK+" scalef + x "+BK+" scalef - y > x "+BK+" scalef - y ? ?",U=2,V=2) : mt_lutxy(last,clp,"x "+BK+" + y < x "+BK+" + x "+BK+" - y > x "+BK+" - y ? ?",U=2,V=2)
}


Function STPresso_FluxsmoothTMC(clip clp, int "tthr")
{

tthr = default( tthr, 12 )

super = clp.MSuper(pel=2, sharp=1)

bv1 = manalyse(super,isb=true, truemotion=false, delta=1,blksize=16,overlap=8)
fv1 = manalyse(super,Isb=false, truemotion=false, delta=1,blksize=16,overlap=8)

bc1 = mcompensate(clp, super,bv1)
fc1 = mcompensate(clp, super,fv1)

result=interleave(fc1, clp, bc1).FluxSmoothT(tthr).selectevery(3,1)

Return(result)
}

I want volunteers for testing with HBD :sly:

Forteen88
24th April 2020, 21:19
...
I want volunteers for testing with HBD :sly:Thanks, but what is 'HBD'?

StainlessS
24th April 2020, 21:51
Thanks, but what is 'HBD'?

HBD is an acronym for Happy Birthday.
It's often seen as a lazy way of messaging someone on their birthday.
It's also occasionally used to mean here be dragons, referring to unexplored or dangerous territory ahead.


It also on occasion used to mean High Bit Depth.

so many happy bit depths to you.

tormento
25th April 2020, 09:25
I want volunteers for testing with HBD
From Avisynth wiki: "STPresso is recommended for content up to 720p because "the spatial part might be a bit too narrow for 1080p encoding (since it's only a 3x3 kernel)".

Did you fix that part?

real.finder
25th April 2020, 16:28
From Avisynth wiki: "STPresso is recommended for content up to 720p because "the spatial part might be a bit too narrow for 1080p encoding (since it's only a 3x3 kernel)".

Did you fix that part?

no, maybe later

tormento
25th April 2020, 17:45
no, maybe later



So it’s a bit hard to properly test on HBD source, mostly 4K [emoji28]

real.finder
7th May 2020, 07:33
no, maybe later


So it’s a bit hard to properly test on HBD source, mostly 4K [emoji28]

I tried this, maybe RemoveGrainHD will be a better replacement but it didn't updated for a long time (still in avs 2.5 age)

# STPresso by Didée, MC by SilaSurfer, r.f mod in 2020.05.07 for HBD
function STPresso(clip clp, float "limit", float "bias", int "RGmode", int "tthr", float "tlimit", float "tbias", float "back", bool "mc", bool "HD", int "radius")
{
sisavs26 = !(VersionNumber() < 2.60)
limit = default( limit, 3 ) # spatial limit: the spatial part won't change a pixel more than this
bias = default( bias, 24 ) # bias: the percentage of the spatial filter that will apply
RGmode = default( RGmode, 4 ) # the spatial filter is RemoveGrain, this is its mode
tthr = default( tthr, 12 ) # temporal threshold for fluxsmooth. Can be set "a good bit bigger" than usually
tlimit = default( tlimit, 3 ) # the temporal filter won't change a pixel more than this
tbias = default( tbias, 49 ) # the percentage of the temporal filter that will apply
back = default( back, 1 ) # after all changes have been calculated, reduce all pixel changes by this value. (Shift "back" towards original value)
mc = default( mc, false ) #
h = clp.height()
ishd = h > 720
HD = default( HD, ishd ) #
radius = default( radius, round(h/540.0) ) #

LIM1 = (limit>0) ? string( round(limit*100.0/bias-1.0) ) : string( round(100.0/bias) )
LIM2 = (limit<0) ? "1" : string(limit)
BIA = string(bias)
BK = string(back)
TLIM1 = (tlimit>0) ? string( round(tlimit*100.0/tbias-1.0) ) : string( round(100.0/tbias) )
TLIM2 = (tlimit<0) ? "1" : string(tlimit)
TBIA = string(tbias)

expr = (limit<0) ? sisavs26 ? "x y - abs "+LIM1+" scalef < x x 1 x y - x y - abs / * - ?" : "x y - abs "+LIM1+" < x x 1 x y - x y - abs / * - ?"
\ : sisavs26 ? "x y - abs 1 scalef < x x "+LIM1+" scalef + y < x "+LIM2+" scalef + x "+LIM1+" scalef - y > x "+LIM2+" scalef - " \
+ "x 100 scalef "+BIA+" scalef - * y "+BIA+" scalef * + 100 scalef / ? ? ?" \
: "x y - abs 1 < x x "+LIM1+" + y < x "+LIM2+" + x "+LIM1+" - y > x "+LIM2+" - " \
+ "x 100 "+BIA+" - * y "+BIA+" * + 100 / ? ? ?"
texpr = (limit<0) ? sisavs26 ? "x y - abs "+TLIM1+" scalef < x x 1 x y - x y - abs / * - ?" : "x y - abs "+TLIM1+" < x x 1 x y - x y - abs / * - ?"
\ : sisavs26 ? "x y - abs 1 scalef < x x "+TLIM1+" scalef + y < x "+TLIM2+" scalef + x "+TLIM1+" scalef - y > x "+TLIM2+" scalef - " \
+ "x 100 scalef "+TBIA+" scalef - * y "+TBIA+" scalef * + 100 scalef / ? ? ?" \
: "x y - abs 1 < x x "+TLIM1+" + y < x "+TLIM2+" + x "+TLIM1+" - y > x "+TLIM2+" - " \
+ "x 100 "+TBIA+" - * y "+TBIA+" * + 100 / ? ? ?"

bzz = HD ? clp.minblur(radius) : clp.removegrain(RGmode)
sisavs26 ? mt_lutxy( clp, bzz, expr, scale_inputs=limit<0 ? "floatf" : "none", use_expr=1, U=3,V=3) : mt_lutxy( clp, bzz, expr, U=3,V=3)
tthr==0 ? last : sisavs26 ? mt_lutxy(last,last.mt_makediff(mt_makediff(bzz,mc ? bzz.STPresso_FluxsmoothTMC(tthr) : bzz.fluxsmootht(tthr),U=3,V=3),U=3,V=3),texpr,scale_inputs=limit<0 ? "floatf" : "none",use_expr=1,U=3,V=3) : mt_lutxy(last,last.mt_makediff(mt_makediff(bzz,mc ? bzz.STPresso_FluxsmoothTMC(tthr) : bzz.fluxsmootht(tthr),U=3,V=3),U=3,V=3),texpr,U=3,V=3)
back==0 ? last : sisavs26 ? mt_lutxy(last,clp,"x "+BK+" scalef + y < x "+BK+" scalef + x "+BK+" scalef - y > x "+BK+" scalef - y ? ?",U=2,V=2) : mt_lutxy(last,clp,"x "+BK+" + y < x "+BK+" + x "+BK+" - y > x "+BK+" - y ? ?",U=2,V=2)
}


Function STPresso_FluxsmoothTMC(clip clp, int "tthr")
{

tthr = default( tthr, 12 )

super = clp.MSuper(pel=2, sharp=1)

bv1 = manalyse(super,isb=true, truemotion=false, delta=1,blksize=16,overlap=8)
fv1 = manalyse(super,Isb=false, truemotion=false, delta=1,blksize=16,overlap=8)

bc1 = mcompensate(clp, super,bv1)
fc1 = mcompensate(clp, super,fv1)

result=interleave(fc1, clp, bc1).FluxSmoothT(tthr).selectevery(3,1)

Return(result)
}

mp3dom
5th July 2020, 14:42
What's the latest "minblur" version? I'm asking this because the one I have (I think the one on the wiki) have a lutxy expression based on 8bit values. Shouldn't be updated for hbd as well?

Boulder
5th July 2020, 15:45
I think you'll find the latest version in real.finder's script: https://raw.githubusercontent.com/realfinder/AVS-Stuff/master/avs%202.5%20and%20up/Zs_RF_Shared.avsi

mp3dom
5th July 2020, 16:15
Ah.... was it added just recently? I've used SMDegrain some month ago with the latest script (at that time) and, of course, the shared functions, but received a missing minblur function... so I've used the old one.
Well, ok, nice to see it inside the shared functions. Thanks.