View Full Version : BM3D-r7 | state-of-the-art image/video denoising filter


mawen1250
24th May 2015, 08:54
Source & Readme (https://github.com/HomeOfVapourSynthEvolution/VapourSynth-BM3D)

Binary: GitHub (https://github.com/HomeOfVapourSynthEvolution/VapourSynth-BM3D/releases) | NMM (https://www.nmm-hd.org/upload/get~y1StLOycTvs/BM3D-r7.7z)

After over a month's effort, it's finally completed.
Including the 2D(image) denoising filter BM3D and the 3D(video) denoising filter V-BM3D.

The computational complexity of this denoising algorithm is fairly high, thus it's very slow.
Moreover, the memory consumption of V-BM3D is very high. Since for each current frame, multiple frames are requested, and the filtering result is also aggregated to those frames.

For convenience, I wrote a script named mvsfunc (http://forum.doom9.org/showthread.php?p=1737309), with which you could apply it with a simple call like:
import mvsfunc as mvf

core.max_cache_size = 4000 # Set a big enough cache size. For V-BM3D, you may need 8000 or even more (according to resolution and radius)

# Any input format
clip = mvf.BM3D(clip, sigma=[3,3,3], radius1=0) # radius1=0 for BM3D, radius1>0 for V-BM3D
# Same as input format

mawen1250
24th May 2015, 18:49
Update r2

Fix memory leaks in VAggregate.

mawen1250
26th May 2015, 16:06
Update r3

Fixed a stupid mistake that the order of applying DCT and IDCT is reversed (it should be DCT->filter->IDCT), which leads to over-filtering in fine structures and produces artifacts such as blocking, ringing and desaturation.
Now it actually filters as expected.

MonoS
28th May 2015, 01:06
I get incorrect result disabling chroma processing in OPP colorspace [also disabling only one channel]

res = edi.nnedi3_resample(crop, crop.width, crop.height, mats="601", fulls=False, curves="709", sigmoid=True, scale_thr=1.0, csp=vs.RGB48)

res = core.bm3d.RGB2OPP(res)
ref = core.bm3d.VBasic(res, radius=1, matrix=100, sigma=[8,0,0]).bm3d.VAggregate(radius=1)
flt = core.bm3d.VFinal(res, ref, radius=1, matrix=100, sigma=[8,0,0]).bm3d.VAggregate(radius=1)
flt = core.bm3d.OPP2RGB(flt)

flt = edi.nnedi3_resample(flt, flt.width, flt.height, matd="601", fulld=False, curves="709", sigmoid=True,scale_thr=1.0, csp = vs.YUV420P16)


IIRC OPP is similar to YUV so this operation should be possible, correct me if i'm wrong

mawen1250
28th May 2015, 13:59
Ah, I forgot to mention it in the README...
When specific plane is not processed for V-BM3D, the result of that plane will be garbage...Thus you should manually use std.ShufflePlanes to merge them.
It's mainly becanse the implementaion of V-BM3D is divided into 2 functions, it's not very convenient and efficient to pass through the unprocessed planes.

Later I will add the notification and example about it to the README.

mawen1250
21st November 2015, 06:46
Update r4

Added SSE2 optimizations
Basic, Final: profile="fast" use group_size=8 instead of 16 for better speed
OPP2RGB, RGB2OPP: now override frame property "_Matrix"
Compiled with VS2015

~35% faster with the same settings
~175% faster with default settings for bm3d.Basic+bm3d.Final

MonoS
11th December 2015, 00:23
This goes in my backlog of avx optimization :D

mawen1250
23rd January 2016, 02:54
Update r5

Final estimate: Fixed NaN or INF results which may produce corrupt output and/or break subsequent filters

Hagi
23rd January 2016, 04:38
Thanks mawen1250. It is, by far, the very best denoising filter I've ever used.

In case you use Paypal, I'd be happy to pay you a few beers. Cheers!

mawen1250
23rd January 2016, 09:58
Thanks mawen1250. It is, by far, the very best denoising filter I've ever used.

In case you use Paypal, I'd be happy to pay you a few beers. Cheers!
Wow, thanks for your support and I'm glad you like this filter, that's the best reward for me. I'll PM you my Paypal.

Hagi
30th January 2016, 06:03
Wow, thanks for your support and I'm glad you like this filter, that's the best reward for me. I'll PM you my Paypal.

You're welcome. Hard work deserves a fair reward, within your means.

asarian
8th April 2016, 15:09
Looks wonderful! :) What is the best way to pre-calculate core.max_cache_size, though? Is there some kind of formula I can use?

mawen1250
9th April 2016, 10:43
Looks wonderful! :) What is the best way to pre-calculate core.max_cache_size, though? Is there some kind of formula I can use?
Just did a simple test with mvf.BM3D.
1920x1080 input
threads=8, max_cache_size=20000
profile="fast"

radius | Memory consumption
0 | ~4GB
1 | ~10GB
2 | ~15GB

Then try lowering max_cache_size to see if there will be obvious speed penalty. From my tests, 2/3 the memory consumption above is a well-balanced point.
That is, 2500 for radius=0, 7000 for radius=1, 10000 for radius=2, for 1920x1080 video.

asarian
9th April 2016, 11:17
Thank you very much! :)

I only have 12G installed, so I guess I can forget about 'radius=5' then. (Although that was on a 640x480 source, so maybe I can make it work anyway)

jackoneill
9th April 2016, 11:57
Just did a simple test with mvf.BM3D.
1920x1080 input
threads=8, max_cache_size=20000
profile="fast"

radius | Memory consumption
0 | ~4GB
1 | ~10GB
2 | ~15GB

Then try lowering max_cache_size to see if there will be obvious speed penalty. From my tests, 2/3 the memory consumption above is a well-balanced point.
That is, 2500 for radius=0, 7000 for radius=1, 10000 for radius=2, for 1920x1080 video.

How many frames did you filter? The cache reevaluates its behaviour every few hundred frames, so the speed/memory consumption may improve (or degrade) over time.

mawen1250
9th April 2016, 18:20
How many frames did you filter? The cache reevaluates its behaviour every few hundred frames, so the speed/memory consumption may improve (or degrade) over time.
approximate 500 frames

From previous experience, the memory consumption of VS will gradually decrease during encoding procedure. It's an interesting question if it will decrease when V-BM3D is used, and we can set lower max_cache_size? Maybe I'll do more tests to find it out.

asarian
10th April 2016, 13:30
How many frames did you filter? The cache reevaluates its behaviour every few hundred frames, so the speed/memory consumption may improve (or degrade) over time.

I noticed that, the other day. The other day I set

core.max_cache_size = 4096

(Using TempLinearApproximateMC), just to see what would happen. Python started off at ca 6G (as expected for the job), but slowly tapered off to almost not using the cache at all. Seems Python is clever enough to realize what it actually needs, over time. I like that. :) (And kinda logical too: it is, after all, max_cache_size, not just cache_size).

mawen1250
11th April 2016, 08:08
I noticed that, the other day. The other day I set

core.max_cache_size = 4096

(Using TempLinearApproximateMC), just to see what would happen. Python started off at ca 6G (as expected for the job), but slowly tapered off to almost not using the cache at all. Seems Python is clever enough to realize what it actually needs, over time. I like that. :) (And kinda logical too: it is, after all, max_cache_size, not just cache_size).
Python is just an interface for vs though. it's the vs core that manages the frame cache (which is written in C++).

By the way, I've tested processing more frames with BM3D(radius=2).
Up to now, the result is:
frame memory(MB)
100 15500
750 15500
1950 15300
8400 13400
37600 12700

asarian
8th June 2016, 17:19
Is this, despite its wicked memory requirements, perchance a good alternative to KNLMeansCL? (Something I could use on my VM, sans relevant GPU, to tide me over until I have the GTX 750 for it).

feisty2
8th June 2016, 17:26
Is this, despite its wicked memory requirements, perchance a good alternative to KNLMeansCL? (Something I could use on my VM, sans relevant GPU, to tide me over until I have the GTX 750 for it).

NLMeans -> for white noise
BM3D -> for Gaussian noise

Gaussian is just one kind of white noise, other kinds are out there also.

different algorithms, these two work best when combined together, not one replacing another, you could over de-noise the image a tiny little bit with BM3D and then refine it with an NLMeans loop, the result will be stunning and better than both plain BM3D or plain NLMeans

asarian
8th June 2016, 17:39
Okay, thanks for the explanation.

mawen1250
9th June 2016, 13:00
It's the V-BM3D that requires lots of memory, for spatial BM3D it's mostly acceptable.
Original NLMeans and BM3D were both designed for Gaussian white noise. In the paper, their models are built upon Gaussian white noise assumption, and their performance is also measured with Gaussian white noise.
From my experience, KNLMeans works great with anime-style sources, it'll smooth flat area and won't filter edges much.
On the contrary, BM3D will filter edges more, resulting in a more uniform de-noising. it's more suitable for non-anime content, and it's also really good to eliminate blocking and ringing in highly-compressed sources.

feisty2
9th June 2016, 14:14
KNLMeans works great with anime-style sources, it'll smooth flat area and won't filter edges much.

depends, generally larger s = smoother edge but more ringings...
s=4 leaves lots of ringing like residual noise around edges on VERY grainy clips
s=0/1 slays at ringing removal, it vaporizes ringings with little costs to the edge sharpness

mawen1250
10th June 2016, 08:09
With s=0, NLMeans falls back to something like Bilateral filter with box spatial weighting. Narrowly speaking it's not NLMeans any more (whose weighting is based on neighborhood similarity).

feisty2
10th June 2016, 08:25
With s=0, NLMeans falls back to something like Bilateral filter with box spatial weighting. Narrowly speaking it's not NLMeans any more (whose weighting is based on neighborhood similarity).

right, and actually s=0 and 1 are for different kinds of ringings..
s=0 (like an alternative kind of blurring, weighting on error instead of spatial distance) is good for overshoot kind of stuff
s=1, the real NLMeans is good for mosquito noise

asarian
10th June 2016, 12:19
different algorithms, these two work best when combined together, not one replacing another, you could over de-noise the image a tiny little bit with BM3D and then refine it with an NLMeans loop, the result will be stunning and better than both plain BM3D or plain NLMeans

So, I'd do a BM3D (radius1=0), for a Gaussian noise reduction (per frame) first, and then follow up with a KNLmeansCL pass, right?

mawen1250
10th June 2016, 15:30
So, I'd do a BM3D (radius1=0), for a Gaussian noise reduction (per frame) first, and then follow up with a KNLmeansCL pass, right?

If you want a very clean output, it's right. KNLMeans after BM3D will give a noise-free result with smooth flat area.
Though I think feisty2 was referring to combining them in frequency domain or to using one as the reference for another, which is mainly for less detail loss.

feisty2
10th June 2016, 15:36
exactly, I was talking about refining with NLMeans, not simply appending an NLMeans after BM3D

Elegant
14th June 2016, 15:10
Would you be better off with BM3D refined with NLMeans over just NLMeans for anime content? Or would their still be too much filtering of the edges?

asarian
15th June 2016, 12:07
exactly, I was talking about refining with NLMeans, not simply appending an NLMeans after BM3D

I'm sure you were. :) Can you give a crude example, though, please, of how you would 'nest' the two like that, though?

feisty2
16th June 2016, 14:43
I'm sure you were. :) Can you give a crude example, though, please, of how you would 'nest' the two like that, though?


import vapoursynth as vs
import mvmulti
core = vs.get_core()

fmtc_args = dict (fulls=True, fulld=True)
msuper_args = dict (chroma=False, hpad=32, vpad=32, sharp=2, levels=0)
manalyze_args = dict (search=3, chroma=False, truemotion=False, trymany=True, levels=0, badrange=-24)
mrecalculate_args = dict (chroma=False, truemotion=False, search=3, smooth=1)

def freq_merge (low, hi, p=8):
core = vs.get_core ()
Resample = core.fmtc.resample
MakeDiff = core.std.MakeDiff
MergeDiff = core.std.MergeDiff
def gauss (src):
upsmp = Resample (src, src.width * 2, src.height * 2, kernel="gauss", a1=100, **fmtc_args)
clip = Resample (upsmp, src.width, src.height, kernel="gauss", a1=p, **fmtc_args)
return clip
hif = MakeDiff (hi, gauss (hi))
clip = MergeDiff (gauss (low), hif)
return clip

def padding (src, left=0, right=0, top=0, bottom=0):
core = vs.get_core ()
Resample = core.fmtc.resample
w = src.width
h = src.height
clip = Resample (src, w+left+right, h+top+bottom, -left, -top, w+left+right, h+top+bottom, kernel="point", **fmtc_args)
return clip

def getvectors (src, pelclip=None, tr=6, pel=1, thsad=400):
core = vs.get_core ()
MSuper = core.mvsf.Super
MAnalyze = mvmulti.Analyze
MRecalculate = mvmulti.Recalculate
supersoft = MSuper (src, pelclip=pelclip, rfilter=4, pel=pel, **msuper_args)
supersharp = MSuper (src, pelclip=pelclip, rfilter=2, pel=pel, **msuper_args)
vmulti = MAnalyze (supersoft, overlap=16, blksize=32, tr=tr, **manalyze_args)
vmulti = MRecalculate (supersoft, vmulti, overlap=8, blksize=16, tr=tr, thsad=thsad/2, **mrecalculate_args)
vmulti = MRecalculate (supersharp, vmulti, overlap=4, blksize=8, tr=tr, thsad=thsad/2, **mrecalculate_args)
vmulti = MRecalculate (supersharp, vmulti, overlap=2, blksize=4, tr=tr, thsad=thsad/2, **mrecalculate_args)
return vmulti

clp = rule6
clp = core.fmtc.bitdepth(clp, bits=32, flt=True)
clp = padding(clp,36,36,36,36)
ref = core.bm3d.VBasic (clp, radius=6, sigma=24.0, block_size=8, block_step=8).bm3d.VAggregate(6, 1)
cln = core.bm3d.VFinal (clp, ref,radius=6, sigma=24.0, block_size=8, block_step=8).bm3d.VAggregate(6, 1)
cln0 = cln

vec = getvectors(cln)
blk = core.std.Expr(cln,"0.5")

dif = core.std.MakeDiff(clp, cln)
dif = core.knlm.KNLMeansCL(dif, 0, 32, 4, 12, rclip=cln)
sup = core.mvsf.Super (dif, rfilter=2, pel=1, **msuper_args)
dif = mvmulti.DegrainN (blk, sup, vec, tr=6, thsad=10000)
cln = core.std.MergeDiff(cln, dif)

dif = core.std.MakeDiff(clp, cln)
dif = core.knlm.KNLMeansCL(dif, 0, 16, 3, 10.5, rclip=cln)
sup = core.mvsf.Super (dif, rfilter=2, pel=1, **msuper_args)
dif = mvmulti.DegrainN (blk, sup, vec, tr=6, thsad=10000)
cln = core.std.MergeDiff(cln, dif)

dif = core.std.MakeDiff(clp, cln)
dif = core.knlm.KNLMeansCL(dif, 0, 8, 2, 9, rclip=cln)
sup = core.mvsf.Super (dif, rfilter=2, pel=1, **msuper_args)
dif = mvmulti.DegrainN (blk, sup, vec, tr=6, thsad=10000)
cln = core.std.MergeDiff(cln, dif)

dif = core.std.MakeDiff(clp, cln)
dif = core.knlm.KNLMeansCL(dif, 0, 4, 1, 7.5, rclip=cln)
sup = core.mvsf.Super (dif, rfilter=2, pel=1, **msuper_args)
dif = mvmulti.DegrainN (blk, sup, vec, tr=6, thsad=10000)
cln = core.std.MergeDiff(cln, dif)

dif = core.std.MakeDiff(clp, cln)
dif = core.knlm.KNLMeansCL(dif, 0, 2, 0, 6, rclip=cln)
sup = core.mvsf.Super (dif, rfilter=2, pel=1, **msuper_args)
dif = mvmulti.DegrainN (blk, sup, vec, tr=6, thsad=10000)
cln = core.std.MergeDiff(cln, dif)
cln = freq_merge(cln0,cln,8)

cln.set_output()

asarian
16th June 2016, 17:48
[code]
import vapoursynth as vs
import mvmulti
core = vs.get_core()


You're the best! :) Thank you very much! Very illuminating!

feisty2
18th June 2016, 09:58
BUG REPORT

frames ∈ {[0, radius - 1] ∪ [last frame - radius +1, last frame]} are misplaced after VBasic/VFinal

mawen1250
16th July 2016, 13:35
Update r6

VAggregate bug fix: For Gray input and/or float output, frames [0, radius-1] are replaced by frame 'radius'. frames [num_frames - radius, num_frames - 1] are replaced by frame 'num_frames - radius - 1'
Re-licensed to MIT

mawen1250
16th August 2016, 06:44
Update r7

Update FFTW to 3.3.5

MonoS
4th October 2016, 21:57
Hi, i'm encountering a very strange artifact with this script
import vapoursynth as vs
import nnedi3_resample as edi

core = vs.get_core()

src = core.ffms2.Source("C:/U.S. Theatrical Trailer (Red Band).m2ts23.mkv")

blksize=16
overlap=8
pad = blksize + overlap

deint = core.fmtc.bitdepth(src, bits=16).std.CropRel(left=250, right=250)

deint = core.fmtc.resample(deint, deint.width+pad, deint.height+pad, sw=deint.width+pad, sh=deint.height+pad, kernel="point")

RGB = edi.nnedi3_resample(deint, deint.width, deint.height,csp=vs.RGB48, fast=False)

OPPF = core.bm3d.RGB2OPP(RGB, 1)
OPP = core.fmtc.bitdepth(OPPF, bits=16, flt=False, dmode=1, fulls=True, fulld=True)

super = core.mv.Super(OPP)

bvec2 = core.mv.Analyse(super, isb = True, delta = 2, blksize=blksize, overlap=overlap, truemotion=False)
bvec1 = core.mv.Analyse(super, isb = True, delta = 1, blksize=blksize, overlap=overlap, truemotion=False)
fvec1 = core.mv.Analyse(super, isb = False, delta = 1, blksize=blksize, overlap=overlap, truemotion=False)
fvec2 = core.mv.Analyse(super, isb = False, delta = 2, blksize=blksize, overlap=overlap, truemotion=False)

ref = core.mv.Degrain2(OPP, super, bvec1,fvec1,bvec2,fvec2, 425)
ref = core.fmtc.bitdepth(ref, flt=True)


flt = core.bm3d.VFinal(OPPF, ref, radius=1, matrix=100, sigma=[11,7,7]).bm3d.VAggregate(radius=1, sample=1)
"""
denf = core.bm3d.OPP2RGB(flt, sample=1)

den = core.fmtc.bitdepth(denf, bits=16, flt=False, dmode=0)

den = edi.nnedi3_resample(den[0:55], 946, 720, matd="709", fulld=False, csp=vs.YUV444P16, fulls=True, src_width=1420, src_height=1080, curves="709", curved="709", mats="RGB", sigmoid=True, kernel="spline64") + edi.nnedi3_resample(den[55::], 946, 720, matd="709", fulld=False, csp=vs.YUV444P16, fulls=True, src_width=1420, src_height=1080, curves="709", curved="709", mats="RGB", sigmoid=True, invks=True)
"""
flt.set_output()


The incriminated file is this one https://mega.nz/#!b14RDa6Z!82LdVsl0S4lfMJ5s7YH2pahJqFZSHvRjKk1sDqDiQ9U and the artifact can be seen at frame 648 https://abload.de/img/artifactgvq1k.png , [the screen was made with the last line uncommented] the more the luma sigma the more the artifact is visible.

Did i make some mistake in my script or did i find a bug in the implementation?

Thanks for the attention.

royia
3rd January 2017, 17:26
Anyone encountered mawen1250 lately?

dipje
3rd January 2017, 22:22
Click on name, view public profile, last activity is 12th November 2016.

I don't think doom9 was his primary forum btw, but not sure about stuff like that.

Jindadil007
10th January 2017, 18:05
import vapoursynth as vs
import mvmulti
core = vs.get_core()

fmtc_args = dict (fulls=True, fulld=True)
msuper_args = dict (chroma=False, hpad=32, vpad=32, sharp=2, levels=0)
manalyze_args = dict (search=3, chroma=False, truemotion=False, trymany=True, levels=0, badrange=-24)
mrecalculate_args = dict (chroma=False, truemotion=False, search=3, smooth=1)

def freq_merge (low, hi, p=8):
core = vs.get_core ()
Resample = core.fmtc.resample
MakeDiff = core.std.MakeDiff
MergeDiff = core.std.MergeDiff
def gauss (src):
upsmp = Resample (src, src.width * 2, src.height * 2, kernel="gauss", a1=100, **fmtc_args)
clip = Resample (upsmp, src.width, src.height, kernel="gauss", a1=p, **fmtc_args)
return clip
hif = MakeDiff (hi, gauss (hi))
clip = MergeDiff (gauss (low), hif)
return clip

def padding (src, left=0, right=0, top=0, bottom=0):
core = vs.get_core ()
Resample = core.fmtc.resample
w = src.width
h = src.height
clip = Resample (src, w+left+right, h+top+bottom, -left, -top, w+left+right, h+top+bottom, kernel="point", **fmtc_args)
return clip

def getvectors (src, pelclip=None, tr=6, pel=1, thsad=400):
core = vs.get_core ()
MSuper = core.mvsf.Super
MAnalyze = mvmulti.Analyze
MRecalculate = mvmulti.Recalculate
supersoft = MSuper (src, pelclip=pelclip, rfilter=4, pel=pel, **msuper_args)
supersharp = MSuper (src, pelclip=pelclip, rfilter=2, pel=pel, **msuper_args)
vmulti = MAnalyze (supersoft, overlap=16, blksize=32, tr=tr, **manalyze_args)
vmulti = MRecalculate (supersoft, vmulti, overlap=8, blksize=16, tr=tr, thsad=thsad/2, **mrecalculate_args)
vmulti = MRecalculate (supersharp, vmulti, overlap=4, blksize=8, tr=tr, thsad=thsad/2, **mrecalculate_args)
vmulti = MRecalculate (supersharp, vmulti, overlap=2, blksize=4, tr=tr, thsad=thsad/2, **mrecalculate_args)
return vmulti

clp = rule6
clp = core.fmtc.bitdepth(clp, bits=32, flt=True)
clp = padding(clp,36,36,36,36)
ref = core.bm3d.VBasic (clp, radius=6, sigma=24.0, block_size=8, block_step=8).bm3d.VAggregate(6, 1)
cln = core.bm3d.VFinal (clp, ref,radius=6, sigma=24.0, block_size=8, block_step=8).bm3d.VAggregate(6, 1)
cln0 = cln

vec = getvectors(cln)
blk = core.std.Expr(cln,"0.5")

dif = core.std.MakeDiff(clp, cln)
dif = core.knlm.KNLMeansCL(dif, 0, 32, 4, 12, rclip=cln)
sup = core.mvsf.Super (dif, rfilter=2, pel=1, **msuper_args)
dif = mvmulti.DegrainN (blk, sup, vec, tr=6, thsad=10000)
cln = core.std.MergeDiff(cln, dif)

dif = core.std.MakeDiff(clp, cln)
dif = core.knlm.KNLMeansCL(dif, 0, 16, 3, 10.5, rclip=cln)
sup = core.mvsf.Super (dif, rfilter=2, pel=1, **msuper_args)
dif = mvmulti.DegrainN (blk, sup, vec, tr=6, thsad=10000)
cln = core.std.MergeDiff(cln, dif)

dif = core.std.MakeDiff(clp, cln)
dif = core.knlm.KNLMeansCL(dif, 0, 8, 2, 9, rclip=cln)
sup = core.mvsf.Super (dif, rfilter=2, pel=1, **msuper_args)
dif = mvmulti.DegrainN (blk, sup, vec, tr=6, thsad=10000)
cln = core.std.MergeDiff(cln, dif)

dif = core.std.MakeDiff(clp, cln)
dif = core.knlm.KNLMeansCL(dif, 0, 4, 1, 7.5, rclip=cln)
sup = core.mvsf.Super (dif, rfilter=2, pel=1, **msuper_args)
dif = mvmulti.DegrainN (blk, sup, vec, tr=6, thsad=10000)
cln = core.std.MergeDiff(cln, dif)

dif = core.std.MakeDiff(clp, cln)
dif = core.knlm.KNLMeansCL(dif, 0, 2, 0, 6, rclip=cln)
sup = core.mvsf.Super (dif, rfilter=2, pel=1, **msuper_args)
dif = mvmulti.DegrainN (blk, sup, vec, tr=6, thsad=10000)
cln = core.std.MergeDiff(cln, dif)
cln = freq_merge(cln0,cln,8)

cln.set_output()


Hi... Can you please inform where to import the video source...a stupid but newbie's question... My current working script is :

import vapoursynth as vs
import mvsfunc as mvf
import mvmulti
core = vs.get_core()
core.max_cache_size = 12000
video = core.d2v.Source(r'C:\DVD\Sample.d2v')
video = mvf.BM3D(video, sigma=[3,3,3], radius2=0)
video.set_output()

Thanks !!!

Are_
10th January 2017, 18:16
Hi... Can you please inform where to import the video source...

From feisty2's post, this line:
clp = rule6

rule6 is supposed to be your source filter, but if you are a newbie I don't think using fesity's scripts is a good idea.

Jindadil007
10th January 2017, 18:35
From feisty2's post, this line:
clp = rule6

rule6 is supposed to be your source filter, but if you are a newbie I don't think using fesity's scripts is a good idea.

Thanks Are... I am experimenting a bit and learning...
However when I am trying to do basic and final filtering...I am getting this error :

Error: bm3d.Basic: input clip: sub-sampled format is not supported when chroma is processed, convert it to YUV444 or RGB first. For the best quality, RGB colorspace is recommended as input.

This is the script I am trying :

import vapoursynth as vs
import mvsfunc as mvf
import mvmulti
import havsfunc as haf
core = vs.get_core()
core.max_cache_size = 20000
video = core.d2v.Source(r'C:\DVD\Sample.d2v')
pre = haf.sbr(video, 3)
ref = core.bm3d.Basic(video, pre, sigma=10)
flt = core.bm3d.Final(video, ref, sigma=10)
video.set_output()

can you help me with error... I am trying to use a better denoise alogrithm to improve the video quality with maximum details... Thanks !!!

Are_
10th January 2017, 19:53
You have to do what the error tels you to do, convert to RGB for example:

clip = core.resize.Bicubic(clip, format=vs.RGB48)

But anyway you are better using mvsfunc for that, that function greatly simplifies using bm3d, because bm3d can be quite annoying to use without it. You will not get better quality by not using mvsfunc.

You can read the comments on that module for more options (the comments inside the .py file, not the ones from the readme).

Jindadil007
10th January 2017, 20:37
You have to do what the error tels you to do, convert to RGB for example:

clip = core.resize.Bicubic(clip, format=vs.RGB48)

But anyway you are better using mvsfunc for that, that function greatly simplifies using bm3d, because bm3d can be quite annoying to use without it. You will not get better quality by not using mvsfunc.

You can read the comments on that module for more options (the comments inside the .py file, not the ones from the readme).
Many Thanks Are for the helpful tip...i'll study tomorrow and experiment...

Sent from my GT-N8000 using Tapatalk

Jindadil007
11th January 2017, 14:24
You have to do what the error tels you to do, convert to RGB for example:

clip = core.resize.Bicubic(clip, format=vs.RGB48)

But anyway you are better using mvsfunc for that, that function greatly simplifies using bm3d, because bm3d can be quite annoying to use without it. You will not get better quality by not using mvsfunc.

You can read the comments on that module for more options (the comments inside the .py file, not the ones from the readme).

Hi converted the colour format...now this is the error...

vapoursynth.Error: bm3d.VFinal: input clip and clip "ref" must be of the same format

Here is my script
clp = core.d2v.Source(r'C:\DVD\Sample.d2v')
clp = core.fmtc.bitdepth(clp, bits=32, flt=True)
clp = core.resize.Bicubic(clp, format=vs.RGB48)
ref = core.bm3d.VBasic (clp, radius=6, sigma=24.0, block_size=8, block_step=8).bm3d.VAggregate(6, 1)
cln = core.bm3d.VFinal (clp, ref,radius=6, sigma=24.0, block_size=8, block_step=8).bm3d.VAggregate(6, 1)
cln0 = cln

Pl. guide me...

feisty2
11th January 2017, 14:44
rgb48 -> rgbs

feisty2
11th January 2017, 14:47
bm3d.VAggregate(6, sample=1)
sample = 1 is for floating point stuff, rgb48 is an integer format, read the freaking doc

Jindadil007
23rd January 2017, 04:29
Why vBM3d is so slow as compared to fft3d filter. I tested a video with both filters. With vBm3d i get around 3-5 fps while in fft3d i get around 9-10 fps. A 2 pass encode with VBm3d for a 3 hour movie would take around 50 hours while fft3d takes around 15 hours. My machine : core i7 6700k, 16gb DDR4, 4 GB nvidia GTX 960, 500 gb SSD.

feisty2
23rd January 2017, 05:32
Why vBM3d is so slow as compared to fft3d filter. I tested a video with both filters. With vBm3d i get around 3-5 fps while in fft3d i get around 9-10 fps. A 2 pass encode with VBm3d for a 3 hour movie would take around 50 hours while fft3d takes around 15 hours. My machine : core i7 6700k, 16gb DDR4, 4 GB nvidia GTX 960, 500 gb SSD.

I'll make it simple to you with a metaphor
complexity of fft3d: 1+1
complexity of bm3d: ∫∫∫f(x, y, z)dxdydz

denoising quality of fft3d: 10/100
denoising quality of bm3d: 95/100

I tested a video with both filters. With vBm3d i get around 3-5 fps while in fft3d i get around 9-10 fps.
that's very unlikely, bm3d should be at least 100 times slower with proper settings, something has to be wrong cuz bm3d is working way too fast.

KingLir
24th January 2017, 11:52
Hi all, how can I build BM3D on macOS ?
I have installed vapoursynth using brew and everything working fine but I get this:

$ ./configure
CXXFLAGS/LDFLAGS checking...
warning: pkg-config or pc files not found, lib detection may be inaccurate.
checking for vapoursynth headers...
warning: pkg-config or pc files not found, header detection may be inaccurate.
error: vapoursynth checking failed.
error: VapourSynth.h might not be installed.

groucho86
24th January 2017, 15:12
I really recommend you install Vapoursynth from github - I've had similar issues attempting to you use the brew installation.

KingLir
24th January 2017, 17:13
I really recommend you install Vapoursynth from github - I've had similar issues attempting to you use the brew installation.

But I already have it installed and don't want to jinks it.
But anyway, how to install on macOS ? It says that I have zimg missing (although I have the latest install with brew).

JoeyMonco
24th January 2017, 17:36
But I already have it installed and don't want to jinks it.
But anyway, how to install on macOS ? It says that I have zimg missing (although I have the latest install with brew).

One of the first things you need is pkg-config.

KingLir
24th January 2017, 19:26
One of the first things you need is pkg-config.

I am not following. I already have pkg-config-0.29.1_2 installed with brew.

JoeyMonco
24th January 2017, 19:42
I am not following. I already have pkg-config-0.29.1_2 installed with brew.

Misread the warnings in what you posted. My bad. Looks like you don't have PKG_CONFIG_PATH set properly since it's failing to even simply find the vapoursynth headers.

KingLir
24th January 2017, 21:41
Misread the warnings in what you posted. My bad. Looks like you don't have PKG_CONFIG_PATH set properly since it's failing to even simply find the vapoursynth headers.

Yes, can you guide me to how to fix it ?

JoeyMonco
24th January 2017, 22:17
Yes, can you guide me to how to fix it ?

Setting environment variables on OS X (http://apple.stackexchange.com/questions/106778/how-do-i-set-environment-variables-on-os-x)

Jindadil007
25th January 2017, 13:23
that's very unlikely, bm3d should be at least 100 times slower with proper settings, something has to be wrong cuz bm3d is working way too fast.

Hi...I am encoding a 3 hour video with Vine and VBM3D. Its encoding @0.44 fps since 19 hours and have not reached half stage even. I am encoding to 2-pass x264 (Slow First Pass). Once this finishes, i have to run 2nd pass. Looks it would take around 1 week to encode one movie. Is VBM3d so slow ? Or I should export the video without encoding ? Pl. help.

feisty2
25th January 2017, 13:36
Hi...I am encoding a 3 hour video with Vine and VBM3D. Its encoding @0.44 fps since 19 hours and have not reached half stage even. I am encoding to 2-pass x264 (Slow First Pass). Once this finishes, i have to run 2nd pass. Looks it would take around 1 week to encode one movie. Is VBM3d so slow ? Or I should export the video without encoding ? Pl. help.

you need to separate the filtering process and the encoding process.
output your filtered video to an uncompressed raw and encode that raw file later.

Jindadil007
25th January 2017, 13:40
you need to separate the filtering process and the encoding process.
output your filtered video to an uncompressed raw and encode that raw file later.

Many Thanks ... You are very helpful. I'll try it now... :thanks:

feisty2
25th January 2017, 13:46
Many Thanks ... You are very helpful. I'll try it now... :thanks:

you can separate things into even more steps, since Vine and V-BM3D are both slow

option A:
filter with Vine -> output a.raw
load a.raw and filter with V-BM3D -> b.raw
encode b.raw

option B:
filter with Vine -> output a.raw
load a.raw and filter with VBasic -> ref.raw
load a.raw and ref.raw and filter with VFinal -> b.raw
encode b.raw

Jindadil007
25th January 2017, 14:00
you can separate things into even more steps, since Vine and V-BM3D are both slow
option A:
filter with Vine -> output a.raw
load a.raw and filter with V-BM3D -> b.raw
encode b.raw


Hi Thanks...Option A looks best to me...But in my script i changed video to floating and back to integer like this :

video = core.d2v.Source(r'C:\DVD\Sample.d2v')
video = core.fmtc.bitdepth(video,bits=32,fulls=False,fulld=True)
video = Vine.Dehalo(video, radius=[2, None])
video = core.resize.Bicubic(video, format=vs.RGB48)
video.set_output()

I just tested encoder is not starting...how can i encode to raw and import it in 2nd step. Would ffms2 support importing raw content ? Thanks !!!

feisty2
25th January 2017, 14:05
vsrawsource (https://github.com/walisser/vsrawsource)

Jindadil007
25th January 2017, 14:22
vsrawsource (https://github.com/walisser/vsrawsource)

Hi this link doesn't have rawsource.dll. This for importing in second step. Pl. tell me how to export to raw source in step 1. Thanks

feisty2
25th January 2017, 14:24
Hi this link doesn't have rawsource.dll. This for importing in second step. Pl. tell me how to export to raw source in step 1. Thanks

vspipe xxx.vpy xxx.raw -p

Jindadil007
25th January 2017, 14:25
vspipe xxx.vpy xxx.raw -p

Many Thanks...:o

Jindadil007
28th January 2017, 06:43
vspipe xxx.vpy xxx.raw -p

Hi I get syntex error in Python while exporting to raw format...following is my script.

>>> import vapoursynth as vs
>>> import adjust
>>> import Vine
>>> import mvmulti
>>> import finesharp
>>> import havsfunc as haf
>>> import mvsfunc as mvf
>>> core = vs.get_core()
>>> core.max_cache_size = 12000
>>> video = core.d2v.Source(r'C:\DVD\Sample.d2v')
>>> video = core.fmtc.bitdepth(video,bits=32,fulls=False,fulld=True)
>>> video = core.resize.Bicubic(video, format=vs.RGB48)
>>> video.set_output()
>>> vspipe script.vpy script.raw -p
File "<stdin>", line 1
vspipe script.vpy script.raw -p
^
SyntaxError: invalid syntax
>>>

Where I am wrong ?

sl1pkn07
28th January 2017, 11:45
vspipe not is a python command, is a executable

put the content of the script into a file called script.vpy, then execute the vspipe command in the same folder

Jindadil007
28th January 2017, 17:14
vspipe not is a python command, is a executable

put the content of the script into a file called script.vpy, then execute the vspipe command in the same folder

I did exactly the same...tried copying script.vpy from python (Program Folder) as well as Video path given in my script...still the same result...

sl1pkn07
28th January 2017, 21:28
works without problem (with little tweak for my source)

http://wstaw.org/m/2017/01/28/Screenshot_20170128_212640.png

Jindadil007
29th January 2017, 04:11
@sl1pkn07 : Many Thanks...You really solved my problem...

KingLir
20th February 2017, 12:52
Anyone knows how to build this on macOS or can share the complied lib for macOS ?

KingLir
21st February 2017, 10:04
Um...
./configure doesn't work?

configure was working but the source on GitHub was missing the following header files in include/vapoursynth
VapourSynth.h , VSHelper.h , VSScript.h

Now everything builds fine.
If someone can do a commit with this fix - please do.

xekon
10th July 2020, 21:12
Has anyone managed to install this on Linux (ubuntu/debian) ?

I figured it out, I had installed fftw3, but you also need to install libfftw3-dev

perforator
11th July 2020, 14:04
Has anyone managed to install this on Linux (ubuntu/debian) ?

I figured it out, I had installed fftw3, but you also need to install libfftw3-dev

This sounds exciting!
Do you have a working "recipe" for the installation? I would really like to set this up on my new Manjaro workstation.

Are_
11th July 2020, 14:41
Manjaro (Arch) has proper packages, don't need any manual bullshit. https://aur.archlinux.org/packages/vapoursynth-plugin-bm3d-git/

Jukus
11th July 2020, 15:49
For Debian there is https://deb-multimedia.org/
But it's funny that there is nothing for Ubuntu

xekon
12th July 2020, 19:47
This sounds exciting!
Do you have a working "recipe" for the installation? I would really like to set this up on my new Manjaro workstation.

it was fairly easy, I will write up a guide on my blog in a few days that details setting up Vapoursynth, VSedit, and all plugins under ubuntu.

Cary Knoop
13th July 2020, 03:34
(V)-BM3D GPU development has stalled completely?

perforator
13th July 2020, 09:55
it was fairly easy, I will write up a guide on my blog in a few days that details setting up Vapoursynth, VSedit, and all plugins under ubuntu.

That would be great! Looking forward to read your blog. :)
Please post a link to it, or send a DM might not be allowed to post links here that are associated to bullshit manuals. ;)

perforator
13th July 2020, 10:05
Manjaro (Arch) has proper packages, don't need any manual bullshit. https://aur.archlinux.org/packages/vapoursynth-plugin-bm3d-git/

Yes one might think manuals are bullshit if one is already knowledgeable in the subject. But for us that have other main focus in general, an easy guide i worth a lot. I tried getting this running five years ago but gave up for the time being as it wasn't working as described in the "newbie posts". I would love to get this up and running as I have a large library of digitised 8mm film that would benefit from a bit of polishing. A wiki page would be preferable as it can easily be maintained and updated as progress is made in the development. Ultimately with a short 1. 2. 3. guide of best practise of processing and generally good settings, I understand there are a lot of settings to tweak if one want. :)

ChaosKing
13th July 2020, 10:40
Does this not count as a manual?
https://github.com/HomeOfVapourSynthEvolution/VapourSynth-BM3D
https://github.com/HomeOfVapourSynthEvolution/mvsfunc/blob/7948c8be129bc9cb282cf24e25b3c4b77328a9e0/mvsfunc.py#L700

vigan1
2nd August 2020, 09:47
Hi Chaosking, I read these links on BM3D, If I want to denoise a 1080p 8bit video from a camera.

How can I choose a setting to remove macroblocks (from low bitrate) and posterisation/banding of the 8bit H264 ?
It's very hard to understand what each settings do in practice.

Thank you for the help.

feisty2
28th August 2020, 03:01
it's been so long since the last appearance of the repo owner, I'm not sure if the repo is still being managed.
can someone who has writing access to the repo merge my latest pr?