[FFmpeg-cvslog] avfilter/vf_vaguedenoiser: add new type of threshold

Paul B Mahol git at videolan.org
Sun Jun 7 16:21:14 EEST 2020


ffmpeg | branch: master | Paul B Mahol <onemda at gmail.com> | Sun Jun  7 15:10:03 2020 +0200| [bd6336b9702fc36683acda9ef1d70a6b038d179c] | committer: Paul B Mahol

avfilter/vf_vaguedenoiser: add new type of threshold

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=bd6336b9702fc36683acda9ef1d70a6b038d179c
---

 doc/filters.texi               | 14 ++++++++++++
 libavfilter/vf_vaguedenoiser.c | 52 ++++++++++++++++++++++++++++++++++++++----
 2 files changed, 61 insertions(+), 5 deletions(-)

diff --git a/doc/filters.texi b/doc/filters.texi
index f76604c51e..84567dec16 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -19476,6 +19476,20 @@ Partial of full denoising (limited coefficients shrinking), from 0 to 100. Defau
 
 @item planes
 A list of the planes to process. By default all planes are processed.
+
+ at item type
+The threshold type the filter will use.
+
+It accepts the following values:
+ at table @samp
+ at item universal
+Threshold used is same for all decompositions.
+
+ at item bayes
+Threshold used depends also on each decomposition coefficients.
+ at end table
+
+Default is universal.
 @end table
 
 @section vectorscope
diff --git a/libavfilter/vf_vaguedenoiser.c b/libavfilter/vf_vaguedenoiser.c
index e3d4d30f25..49b338ff91 100644
--- a/libavfilter/vf_vaguedenoiser.c
+++ b/libavfilter/vf_vaguedenoiser.c
@@ -38,6 +38,7 @@ typedef struct VagueDenoiserContext {
     float threshold;
     float percent;
     int method;
+    int type;
     int nsteps;
     int planes;
 
@@ -60,7 +61,7 @@ typedef struct VagueDenoiserContext {
 
     void (*thresholding)(float *block, const int width, const int height,
                          const int stride, const float threshold,
-                         const float percent, const int nsteps);
+                         const float percent);
 } VagueDenoiserContext;
 
 #define OFFSET(x) offsetof(VagueDenoiserContext, x)
@@ -74,6 +75,9 @@ static const AVOption vaguedenoiser_options[] = {
     { "nsteps",    "set number of steps",      OFFSET(nsteps),    AV_OPT_TYPE_INT,   {.i64=6 },  1, 32,     FLAGS },
     { "percent", "set percent of full denoising", OFFSET(percent),AV_OPT_TYPE_FLOAT, {.dbl=85},  0,100,     FLAGS },
     { "planes",    "set planes to filter",     OFFSET(planes),    AV_OPT_TYPE_INT,   {.i64=15 }, 0, 15,     FLAGS },
+    { "type",    "set threshold type",     OFFSET(type),          AV_OPT_TYPE_INT,   {.i64=0 },  0, 1,      FLAGS, "type" },
+        { "universal",  "universal (VisuShrink)", 0,              AV_OPT_TYPE_CONST, {.i64=0},   0, 0,      FLAGS, "type" },
+        { "bayes",      "bayes (BayesShrink)",    0,              AV_OPT_TYPE_CONST, {.i64=1},   0, 0,      FLAGS, "type" },
     { NULL }
 };
 
@@ -333,7 +337,7 @@ static void invert_step(const float *input, float *output, float *temp, const in
 
 static void hard_thresholding(float *block, const int width, const int height,
                               const int stride, const float threshold,
-                              const float percent, const int unused)
+                              const float percent)
 {
     const float frac = 1.f - percent * 0.01f;
     int y, x;
@@ -348,7 +352,7 @@ static void hard_thresholding(float *block, const int width, const int height,
 }
 
 static void soft_thresholding(float *block, const int width, const int height, const int stride,
-                              const float threshold, const float percent, const int nsteps)
+                              const float threshold, const float percent)
 {
     const float frac = 1.f - percent * 0.01f;
     const float shift = threshold * 0.01f * percent;
@@ -368,7 +372,7 @@ static void soft_thresholding(float *block, const int width, const int height, c
 
 static void qian_thresholding(float *block, const int width, const int height,
                               const int stride, const float threshold,
-                              const float percent, const int unused)
+                              const float percent)
 {
     const float percent01 = percent * 0.01f;
     const float tr2 = threshold * threshold * percent01;
@@ -389,6 +393,23 @@ static void qian_thresholding(float *block, const int width, const int height,
     }
 }
 
+static float bayes_threshold(float *block, const int width, const int height,
+                              const int stride, const float threshold)
+{
+    float mean = 0.f;
+
+    for (int y = 0; y < height; y++) {
+        for (int x = 0; x < width; x++) {
+            mean += block[x] * block[x];
+        }
+        block += stride;
+    }
+
+    mean /= width * height;
+
+    return threshold * threshold / (FFMAX(sqrtf(mean - threshold), FLT_EPSILON));
+}
+
 static void filter(VagueDenoiserContext *s, AVFrame *in, AVFrame *out)
 {
     int p, y, x, i, j;
@@ -452,7 +473,28 @@ static void filter(VagueDenoiserContext *s, AVFrame *in, AVFrame *out)
             v_low_size0 = (v_low_size0 + 1) >> 1;
         }
 
-        s->thresholding(s->block, width, height, width, s->threshold, s->percent, s->nsteps);
+        if (s->type == 0) {
+            s->thresholding(s->block, width, height, width, s->threshold, s->percent);
+        } else {
+            for (int n = 0; n < s->nsteps; n++) {
+                float threshold;
+                float *block;
+
+                if (n == s->nsteps - 1) {
+                    threshold = bayes_threshold(s->block, s->hlowsize[p][n], s->vlowsize[p][n], width, s->threshold);
+                    s->thresholding(s->block, s->hlowsize[p][n], s->vlowsize[p][n], width, threshold, s->percent);
+                }
+                block = s->block + s->hlowsize[p][n];
+                threshold = bayes_threshold(block, s->hhighsize[p][n], s->vlowsize[p][n], width, s->threshold);
+                s->thresholding(block, s->hhighsize[p][n], s->vlowsize[p][n], width, threshold, s->percent);
+                block = s->block + s->vlowsize[p][n] * width;
+                threshold = bayes_threshold(block, s->hlowsize[p][n], s->vhighsize[p][n], width, s->threshold);
+                s->thresholding(block, s->hlowsize[p][n], s->vhighsize[p][n], width, threshold, s->percent);
+                block = s->block + s->hlowsize[p][n] + s->vlowsize[p][n] * width;
+                threshold = bayes_threshold(block, s->hhighsize[p][n], s->vhighsize[p][n], width, s->threshold);
+                s->thresholding(block, s->hhighsize[p][n], s->vhighsize[p][n], width, threshold, s->percent);
+            }
+        }
 
         while (nsteps_invert--) {
             const int idx = s->vlowsize[p][nsteps_invert]  + s->vhighsize[p][nsteps_invert];



More information about the ffmpeg-cvslog mailing list