Log in

View Full Version : Need help making an extremely low light footage watchable


Chainmax
20th September 2010, 04:38
...on an SDTV, at least.

I have a series of clips taken with my crappy cellphone's video camera. These were taken in very low light conditions. As expected, attempting to bring out shadow detail is very difficult. The best way to put it is when you apply an autolevels tool to a mostly dark picture and you end up with blueish/yellowish splotches all over. The current script is this:


...
Deblock_QED(quant1=40,aOff1=11,quant2=45,aOff2=6)

dfttest(sigma=1.3,tbsize=3)

FFT3DFilter(sigma=8,plane=3,bw=32,bh=32,bt=3,ow=16,oh=16)

HDRAGC(max_sat=5.0,reducer=2.0)

Stab()

Crop(2,2,636,476,align=true)
Spline36Resize(640,480)

source=last
preNR=source.dfttest(sigma=1.3,tbsize=3).FFT3DFilter(sigma=8,plane=3,bw=32,bh=32,bt=3,ow=16,oh=16)
preNR_super=preNR.MSuper(pel=2, sharp=1)
source_super=source.MSuper(pel=2, sharp=1)
backward_vec3 = MAnalyse(preNR_super,isb = true, delta = 3, overlap=4)
backward_vec2 = MAnalyse(preNR_super,isb = true, delta = 2, overlap=4)
backward_vec1 = MAnalyse(preNR_super,isb = true, delta = 1, overlap=4)
forward_vec1 = MAnalyse(preNR_super,isb = false, delta = 1, overlap=4)
forward_vec2 = MAnalyse(preNR_super,isb = false, delta = 2, overlap=4)
forward_vec3 = MAnalyse(preNR_super,isb = false, delta = 3, overlap=4)
source.MDegrain3(source_super,backward_vec1,forward_vec1,backward_vec2,forward_vec2,backward_vec3,forward_vec3,thSAD=350)

FFT3DFilter(sigma=8,plane=3,bw=32,bh=32,bt=3,ow=16,oh=16)

dfttest(sigma=1.3,tbsize=3)

dull=last
sharp=last.LimitedSharpenFaster(SMode=3,Strength=1000,wide=true,soft=75)
Soothe(sharp,dull,25)

GradFunkMirror(3.02)
GradFunkMirror(1.51)

AddGrain(30,0.6,0.6)
AddGrain(15,0.2,0.2)

As you can see, extremely heavy-handed. Now, I have hardly toyed with HDRAGC other than setting reducer to 2.0, so I am not sure how to proceed in that regard. Also, I have been thinking of ditching All FFT3DFilter chroma lines (except the one in MDegrain) with one or two TemporalSoften ones with heavy settings, and the Deblock_QED line with plain DeBlock. As for detail faking, I'm not sure putting more aggressive GradFunkMirror or AddGrain might be useful.

Any advice on these issues, or alternative ways to make this just a bit more watchable would be appreciated. I cannot post sample clips, but I can post a few before/after screen portions with the above script.

StainlessS
20th September 2010, 07:50
Hi Chainmax, dont know if any of this will help but had some success on a particular project.

May only help if splodges occur on individual frames:-


Function DeNoiseNEW(clip Last,int "P1",int "P2",int "MTHRESH",int "SEG",bool "MOTPN",int "SCPERC")
{
P1 = Default(P1, 32)
P2 = Default(P2, 8)
MTHRESH = Default(MTHRESH,14)
SEG = Default(SEG,2)
MOTPN = Default(MOTPN,true)
SCPERC = Default(SCPERC,51)
yuy2=(isYUY2())?true:false
PreFilt=Last.DeGrainMedian() # prefiltered for better motion analysis
In= (yuy2)?Interleaved2planar():Last
PreFilt= (yuy2)?Prefilt.Interleaved2planar():PreFilt
Super=In.MSuper(planar=yuy2)
SuperPreFilt=PreFilt.MSuper(planar=yuy2)
bv = SuperPreFilt.MAnalyse(isb = true, truemotion=true)
fv = SuperPreFilt.MAnalyse(isb = false, truemotion=true)
# Uses Pixel copy compensation
fc = In.MFlow(super,fv, thSCD1=400,planar=yuy2) # or use MCompensate
bc = In.MFlow(super,bv, thSCD1=400,planar=yuy2) # or use MCompensate
# # Uses Block copy compensation
# fc = In.MCompensate (super,fv,scbehavior=true,thSCD1=400,thSCD2=int(SCPERC * 255.0 / 100.0),mode=0,planar=yuy2)
# bc = In.MCompensate (super,bv,scbehavior=true,thSCD1=400,thSCD2=int(SCPERC * 255.0 / 100.0),mode=0,planar=yuy2)

sadf = In.MMask(fv, ml=100, gamma=1, kind=1, thscd1 =int(SCPERC * 255.0 / 100.0),planar=yuy2) # forward SAD mask
sadb = In.MMask(bv, ml=100, gamma=1, kind=1, thscd1 =int(SCPERC * 255.0 / 100.0),planar=yuy2) # backward SAD mask
msadf= sadf.MT_Binarize() # binary inverted forward SAD mask
msadb = sadb.MT_Binarize() # binary inverted backward SAD mask
msad = MT_Logic(msadf,msadb,mode="or") # combined inverted SAD mask
msade= msad.MT_Expand() # expanded inverted SAD mask
# This mask is high (255) where at least one motion estimation is good,
# so these areas will be protected
msadei = Interleave(msade, msade, msade) # interleaved 3-frame inverted SAD mask

i=interleave(fc, In, bc) # interleave forward compensated, source, and backward compensated
o=DeSpot(i,p1=P1,p2=P2,mthres=MTHRESH,color=true,tsmooth=0,pwidth=width,pheight=height,seg=SEG,mscene=SCPERC,motpn=MOTPN,extmask=msadei,show=0,planar=yuy2)
SelectEvery(o,3,1)
Last=(yuy2)?Planar2Interleaved():Last
return Last
}

Function DeNoiseLight(clip Last)
{
yuy2=(isYUY2())?true:false
Last= (yuy2)?Interleaved2planar():Last
DeSpot(p1=34,p2=12,mthres=14,color=true,tsmooth=0,pwidth=128,pheight=128,seg=2,mscene=25,show=0,planar=yuy2)
Last=(yuy2)?Planar2Interleaved():Last
Return Last
}

Function DeNoiseFast(clip Last)
{
yuy2=(isYUY2())?true:false
a=DePanEstimate(trust=3)
b=DePanInterleave(data=a)
b= (yuy2)?b.Interleaved2planar():b
c=DeSpot(b,p1=44,p2=16,mthres=18,color=true,tsmooth=0,pwidth=width,pheight=height,seg=2,mscene=40,show=0,planar=yuy2)
SelectEvery(c,3, 1)
Last=(yuy2)?Planar2Interleaved():Last
return Last
}

Function DeNoiseHard(clip Last)
{
yuy2=(isYUY2())?true:false
a=DePanEstimate(trust=3)
b=DePanInterleave(data=a)
b= (yuy2)?b.Interleaved2planar():b
c=DeSpot(b,p1=12,p2=4,mthres=10,color=true,tsmooth=0,pwidth=width,pheight=height,mscene=60,mwidth=7,mheight=5,merode=45,motpn=true,seg=2,show=0,planar=yuy2)
SelectEvery(c,3, 1)
Last=(yuy2)?Planar2Interleaved():Last
return Last
}

Chainmax
21st September 2010, 01:35
Thanks for the reply StainlessS. I assume I should use DeNoiseNEW instead of the MDegrain and dfttest lines but keep the chroma FFTDFilter and Deblock_QED ones, would that be correct?

StainlessS
21st September 2010, 02:40
Hi chainmax,

Hard to tell without actually having a sample to play with.
I would perhaps keep the Deblock (but not sure), and HDRAGC lines
and try DenoiseLight() which is a reasonably non-destructive removal
of spots that occur in on only 1 frame. You should definitely not use any
kind of temporal smoothing before any of these denoisers as they
all rely on dirt being present only on individual frames and any temporal
smoothing will screw that up.
I think that the HDRAGC line may actually help despot to identify your
splotches. The DenoiseFast() thing is meant for fast motion rather than
meaning it does it qwik, it should also be not so destructive I think. (long
time since I knocked these up).
Denoisenew is (I think a little more effective but more destructive, and the
DenoiseHard should only be applied to short trims with large splotches
and can be very destructive.
I would play with them viewing what comes out and making sure that you are
not losing too much detail (do a stack horizontal to view before and after).
As these all use Despot, only the areas that are "Fixed" are altered, ie it does
not smooth any other parts of the vid, and so you can pass the vid through
several chained fns. Suggest the Light, Fast, and New variations (in that order),
but hard only as a last resort for large spots on short cuts of the clip.
After you've got the these denoising fns set up as you like em, then you can
pass whats left through to your other filters.
It seems a little overkill to have several FF3DFilter and dfttest, you seem to
be throwing everything at it.
Anyways, checkout that what is coming out of the chain is acceptable, and then
take it from there. Good luck.

Chainmax
22nd September 2010, 01:47
Ok, I modified the original monster script with DenoiseHard first, followed by HDRAGC and the rest. The extra dftest lines were removed and its strength within the MDegrain3 line was subdued. Here is a comparison:


Original:
http://img178.imageshack.us/img178/8640/orig.png

DenoiseHard:
http://img64.imageshack.us/img64/9415/stnlss.png

Ridiculous chain:
http://img834.imageshack.us/img834/5687/monsterd.png

The sections of that frame with big splotches are almost completely flat with either, which is good). Your denoiser is pretty damn powerful all by itself, i must say. This is might be about as good as it gets. I might also try the advice you gave egrimisu on his thread once decided on a final chain.