mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-01-29 22:00:58 +02:00
avfilter/vf_vaguedenoiser: add new type of threshold
This commit is contained in:
parent
6c57b0d63a
commit
bd6336b970
@ -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.
|
||||
|
||||
@item type
|
||||
The threshold type the filter will use.
|
||||
|
||||
It accepts the following values:
|
||||
@table @samp
|
||||
@item universal
|
||||
Threshold used is same for all decompositions.
|
||||
|
||||
@item bayes
|
||||
Threshold used depends also on each decomposition coefficients.
|
||||
@end table
|
||||
|
||||
Default is universal.
|
||||
@end table
|
||||
|
||||
@section vectorscope
|
||||
|
@ -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];
|
||||
|
Loading…
x
Reference in New Issue
Block a user