diff mbox

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

Message ID 20180512202435.6479-2-onemda@gmail.com
State New
Headers show

Commit Message

Paul B Mahol May 12, 2018, 8:24 p.m. UTC
For better control of denoising.

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

Comments

Clément Bœsch May 18, 2018, 5:19 p.m. UTC | #1
On Sat, May 12, 2018 at 10:24:35PM +0200, Paul B Mahol wrote:
> For better control of denoising.
> 
> Signed-off-by: Paul B Mahol <onemda@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.
> +
> +@item a
> +Set denoising amount. Lower values reduces blurring.
> +Default value is @var{1.0} and means full denoising.

I'm not so fond of adding another semantically identical option to
"strength". Do you have some literature on such an option?
Paul B Mahol May 26, 2018, 4:36 p.m. UTC | #2
On 5/18/18, Clement Boesch <u@pkh.me> wrote:
> On Sat, May 12, 2018 at 10:24:35PM +0200, Paul B Mahol wrote:
>> For better control of denoising.
>>
>> Signed-off-by: Paul B Mahol <onemda@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.
>> +
>> +@item a
>> +Set denoising amount. Lower values reduces blurring.
>> +Default value is @var{1.0} and means full denoising.
>
> I'm not so fond of adding another semantically identical option to
> "strength". Do you have some literature on such an option?

It is not identical, you need certain math skills to get it.
diff mbox

Patch

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.
+
+@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");