diff options
| author | Mattias Andrée <maandree@kth.se> | 2017-07-26 16:26:05 +0200 |
|---|---|---|
| committer | Mattias Andrée <maandree@kth.se> | 2017-07-26 16:26:05 +0200 |
| commit | ffeba5cae6ebf01f421e11eee2c4d050da0bb3f3 (patch) | |
| tree | 937c4e5d67df787bd86135d56b5e62c3b59b7db8 /src/blind-spatial-mean.c | |
| parent | Add blind-mean (diff) | |
| download | blind-ffeba5cae6ebf01f421e11eee2c4d050da0bb3f3.tar.gz blind-ffeba5cae6ebf01f421e11eee2c4d050da0bb3f3.tar.bz2 blind-ffeba5cae6ebf01f421e11eee2c4d050da0bb3f3.tar.xz | |
blind*-mean: add -d and replace power with power-stream
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to 'src/blind-spatial-mean.c')
| -rw-r--r-- | src/blind-spatial-mean.c | 52 |
1 files changed, 35 insertions, 17 deletions
diff --git a/src/blind-spatial-mean.c b/src/blind-spatial-mean.c index b4e54e5..5511a3f 100644 --- a/src/blind-spatial-mean.c +++ b/src/blind-spatial-mean.c @@ -1,12 +1,13 @@ /* See LICENSE file for copyright and license details. */ #include "common.h" -USAGE("[-g | -h | -l power | -p power | -v]") +USAGE("[-d | -g | -h | -l power-stream | -p power-stream | -v]") /* TODO add [-w weight-stream] for [-ghlpv] */ /* Because the syntax for a function returning a function pointer is disgusting. */ typedef void (*process_func)(struct stream *stream); +#define C (j & 3) /* * X-parameter 1: method enum value * X-parameter 2: identifier-friendly name @@ -17,37 +18,41 @@ typedef void (*process_func)(struct stream *stream); */ #define LIST_MEANS(TYPE)\ /* [default] arithmetic mean */\ - X(ARITHMETIC, arithmetic,, 0, img[j & 3] += *buf, img[j & 3] /= pixels)\ + X(ARITHMETIC, arithmetic,, 0, img[C] += *buf, img[C] /= pixels)\ + /* standard deviation */\ + X(STANDARD_DEVIATION, sd,, 0, (img[C] += *buf * *buf, aux[C] += *buf),\ + img[C] = nnpow((img[C] - aux[C] * aux[C] / pixels) / pixels, (TYPE)0.5)) \ /* geometric mean */\ - X(GEOMETRIC, geometric,, 1, img[j & 3] *= *buf, img[j & 3] = nnpow(img[j & 3], 1 / pixels))\ + X(GEOMETRIC, geometric,, 1, img[C] *= *buf, img[C] = nnpow(img[C], 1 / pixels))\ /* harmonic mean */\ - X(HARMONIC, harmonic,, 0, img[j & 3] += (TYPE)1 / *buf, img[j & 3] = pixels / img[j & 3])\ + X(HARMONIC, harmonic,, 0, img[C] += (TYPE)1 / *buf, img[C] = pixels / img[C])\ /* Lehmer mean */\ - X(LEHMER, lehmer, (a = (TYPE)power, b = a - (TYPE)1), 0,\ - (img[j & 3] += nnpow(*buf, a), aux[j & 3] += nnpow(*buf, b)), img[j & 3] /= aux[j & 3])\ + X(LEHMER, lehmer, (a[0] = powers[0] - (TYPE)1, a[1] = powers[1] - (TYPE)1,\ + a[2] = powers[2] - (TYPE)1, a[3] = powers[3] - (TYPE)1), 0,\ + (img[C] += nnpow(*buf, powers[C]), aux[C] += nnpow(*buf, a[C])), img[C] /= aux[C])\ /* power mean (Hölder mean) (m = 2 for root square mean; m = 3 for cubic mean) */\ - X(POWER, power, a = (TYPE)power, 0, img[j & 3] += nnpow(*buf, a),\ - img[j & 3] = nnpow(img[j & 3], (TYPE)(1. / power)) / pixels)\ + X(POWER, power,, 0, img[C] += nnpow(*buf, powers[C]),\ + img[C] = nnpow(img[C], (TYPE)1 / powers[C]) / pixels)\ /* variance */\ - X(VARIANCE, variance,, 0, (img[j & 3] += *buf * *buf, aux[j & 3] += *buf),\ - img[j & 3] = (img[j & 3] - aux[j & 3] * aux[j & 3] / pixels) / pixels) + X(VARIANCE, variance,, 0, (img[C] += *buf * *buf, aux[C] += *buf),\ + img[C] = (img[C] - aux[C] * aux[C] / pixels) / pixels) #define X(V, ...) V, enum method { LIST_MEANS() }; #undef X -static double power; +static struct stream power; +static const char *power_file = NULL; #define MAKE_PROCESS(PIXFMT, TYPE,\ _1, NAME, INIT, INITIAL, PROCESS_SUBCELL, FINALISE_SUBCELL)\ static void\ process_##PIXFMT##_##NAME(struct stream *stream)\ {\ - TYPE img[4], aux[4], *buf, a, b;\ + TYPE img[4], aux[4], *buf, a[4], powers[4];\ TYPE pixels = (TYPE)(stream->frame_size / sizeof(img));\ size_t i, n, j = 0, m = stream->frame_size / sizeof(*img);\ int first = 1;\ - INIT;\ do {\ n = stream->ptr / stream->pixel_size * stream->n_chan;\ buf = (TYPE *)(stream->buf);\ @@ -60,6 +65,9 @@ static double power; ewriteall(STDOUT_FILENO, img, sizeof(img), "<stdout>");\ }\ first = 0;\ + if (power_file && !eread_frame(&power, powers))\ + return;\ + INIT;\ img[0] = aux[0] = INITIAL;\ img[1] = aux[1] = INITIAL;\ img[2] = aux[2] = INITIAL;\ @@ -75,7 +83,7 @@ static double power; FINALISE_SUBCELL;\ ewriteall(STDOUT_FILENO, img, sizeof(img), "<stdout>");\ }\ - (void) aux, (void) a, (void) b, (void) pixels;\ + (void) aux, (void) a, (void) powers, (void) pixels;\ } #define X(...) MAKE_PROCESS(lf, double, __VA_ARGS__) LIST_MEANS(double) @@ -84,6 +92,7 @@ LIST_MEANS(double) LIST_MEANS(float) #undef X #undef MAKE_PROCESS +#undef C #define X(ID, NAME, ...) [ID] = process_lf_##NAME, static const process_func process_functions_lf[] = { LIST_MEANS() }; @@ -101,6 +110,9 @@ main(int argc, char *argv[]) enum method method = ARITHMETIC; ARGBEGIN { + case 'd': + method = STANDARD_DEVIATION; + break; case 'g': method = GEOMETRIC; break; @@ -109,11 +121,11 @@ main(int argc, char *argv[]) break; case 'l': method = LEHMER; - power = etolf_flag('l', UARGF()); + power_file = UARGF(); break; case 'p': method = POWER; - power = etolf_flag('p', UARGF()); + power_file = UARGF(); break; case 'v': method = VARIANCE; @@ -126,13 +138,19 @@ main(int argc, char *argv[]) usage(); eopen_stream(&stream, NULL); + if (power_file != NULL) { + eopen_stream(&power, power_file); + if (power.width != 1 || power.height != 1) + eprintf("%s: videos do not have the 1x1 geometry\n", power_file); + if (strcmp(power.pixfmt, stream.pixfmt)) + eprintf("videos use incompatible pixel formats\n"); + } if (stream.encoding == DOUBLE) process = process_functions_lf[method]; else process = process_functions_f[method]; - if (DPRINTF_HEAD(STDOUT_FILENO, stream.frames, 1, 1, stream.pixfmt) < 0) eprintf("dprintf:"); process(&stream); |
