[FFmpeg-devel] [PATCH 2/2] libavfilter/vf_nlmeans: add amount parameter

Paul B Mahol onemda at gmail.com
Sat May 12 23:24:35 EEST 2018


For better control of denoising.

Signed-off-by: Paul B Mahol <onemda at gmail.com>
---
 doc/filters.texi         | 4 ++++
 libavfilter/vf_nlmeans.c | 5 ++++-
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/doc/filters.texi b/doc/filters.texi
index d77c67eb10..60ce18298b 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -11420,6 +11420,10 @@ Set research size.
 Same as @option{r} but for chroma planes.
 
 The default value is @var{0} and means automatic.
+
+ at item a
+Set denoising amount. Lower values reduces blurring.
+Default value is @var{1.0} and means full denoising.
 @end table
 
 @section nnedi
diff --git a/libavfilter/vf_nlmeans.c b/libavfilter/vf_nlmeans.c
index 6c9c9d312d..ac6380bb83 100644
--- a/libavfilter/vf_nlmeans.c
+++ b/libavfilter/vf_nlmeans.c
@@ -53,6 +53,7 @@ typedef struct NLMeansContext {
     int chroma_w, chroma_h;
     double pdiff_scale;                         // invert of the filtering parameter (sigma*10) squared
     double sigma;                               // denoising strength
+    double amount;                              // denoising amount
     int patch_size,    patch_hsize;             // patch size and half size
     int patch_size_uv, patch_hsize_uv;          // patch size and half size for chroma planes
     int research_size,    research_hsize;       // research size and half size
@@ -77,6 +78,7 @@ static const AVOption nlmeans_options[] = {
     { "pc", "patch size for chroma planes", OFFSET(patch_size_uv), AV_OPT_TYPE_INT, { .i64 = 0 },     0, 99, FLAGS },
     { "r",  "research window",                   OFFSET(research_size),    AV_OPT_TYPE_INT, { .i64 = 7*2+1 }, 0, 99, FLAGS },
     { "rc", "research window for chroma planes", OFFSET(research_size_uv), AV_OPT_TYPE_INT, { .i64 = 0 },     0, 99, FLAGS },
+    { "a",  "denoising amount", OFFSET(amount), AV_OPT_TYPE_DOUBLE, { .dbl = 1.0 }, 0.001, 1.0, FLAGS },
     { NULL }
 };
 
@@ -528,13 +530,14 @@ static av_cold int init(AVFilterContext *ctx)
     int i;
     NLMeansContext *s = ctx->priv;
     const double h = s->sigma * 10.;
+    const double a = 1. / (s->amount * s->amount);
 
     s->pdiff_scale = 1. / (h * h);
     s->max_meaningful_diff = -log(1/255.) / s->pdiff_scale;
     s->pdiff_lut_scale = 1./s->max_meaningful_diff * WEIGHT_LUT_SIZE;
     av_assert0((s->max_meaningful_diff - 1) * s->pdiff_lut_scale < FF_ARRAY_ELEMS(s->weight_lut));
     for (i = 0; i < WEIGHT_LUT_SIZE; i++)
-        s->weight_lut[i] = exp(-i / s->pdiff_lut_scale * s->pdiff_scale);
+        s->weight_lut[i] = exp((-i / s->pdiff_lut_scale * s->pdiff_scale) * a);
 
     CHECK_ODD_FIELD(research_size,   "Luma research window");
     CHECK_ODD_FIELD(patch_size,      "Luma patch");
-- 
2.11.0



More information about the ffmpeg-devel mailing list