commit 45c25008cbea5241fb711dc7a9ba21ec631bce64
parent 7903e99f22c9aa149ef1b7bcc4472cdec4a8a65f
Author: Mattias Andrée <maandree@kth.se>
Date: Sun, 14 May 2017 14:21:02 +0200
Fix errors in blind-kernel and add -w to box blur, and update TODO
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat:
M | TODO | | | 17 | +++++++++++++++++ |
M | src/blind-kernel.c | | | 109 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------- |
2 files changed, 105 insertions(+), 21 deletions(-)
diff --git a/TODO b/TODO
@@ -17,6 +17,21 @@ blind-invert-chroma invert the chroma
blind-from-sent convert a sent presentation to a one-frame-per-slide blind video.
blind-kirsch https://en.wikipedia.org/wiki/Kirsch_operator
+blind-gaussian-noise https://en.wikipedia.org/wiki/Gaussian_noise
+blind-threshold https://en.wikipedia.org/wiki/Thresholding_(image_processing)
+... https://en.wikipedia.org/wiki/Balanced_histogram_thresholding
+blind-otsu https://en.wikipedia.org/wiki/Otsu%27s_method
+blind-sobel https://en.wikipedia.org/wiki/Sobel_operator
+blind-scharr https://en.wikipedia.org/wiki/Sobel_operator#Alternative_operators
+blind-prewitt https://en.wikipedia.org/wiki/Prewitt_operator
+blind-roberts-cross https://en.wikipedia.org/wiki/Roberts_cross
+--- https://en.wikipedia.org/wiki/Foreground_detection
+--- https://en.wikipedia.org/wiki/Noise_reduction#In_images
+--- https://en.wikipedia.org/wiki/Dark-frame_subtraction
+--- https://en.wikipedia.org/wiki/Video_denoising
+--- https://en.wikipedia.org/wiki/Canny_edge_detector
+--- https://en.wikipedia.org/wiki/Deriche_edge_detector
+--- https://en.wikipedia.org/wiki/Edge_detection
blind-from-video: add options to:
* just run ffmpeg just print the output
@@ -28,6 +43,8 @@ blind-from-video: add options to:
Add [-j jobs] to blind-from-video and blind-to-video.
+Add -f (framewise) to blind-repeat
+
Generate a header file with the appropriate values for USING_BINARY32, USING_BINARY64.
long double is slightly faster than long.
long double (xyza q) could be added as another format.
diff --git a/src/blind-kernel.c b/src/blind-kernel.c
@@ -8,7 +8,6 @@
USAGE("[-xyza] kernel [parameter] ...")
#define SUBUSAGE(FORMAT) "Usage: %s [-xyza] " FORMAT, argv0
-#define MATRIX(...) ((const double[]){__VA_ARGS__});
#define STRCASEEQ3(A, B1, B2, B3) (!strcasecmp(A, B1) || !strcasecmp(A, B2) || !strcasecmp(A, B3))
#define LIST_KERNELS\
@@ -20,18 +19,28 @@ USAGE("[-xyza] kernel [parameter] ...")
static const double *
kernel_kirsch(int argc, char *argv[], size_t *rows, size_t *cols, double **free_this)
{
+ static const double matrices[][9] = {
+ { 5, 5, 5, -3, 0, -3, -3, -3, -3},
+ { 5, 5, -3, 5, 0, -3, -3, -3, -3},
+ { 5, -3, -3, 5, 0, -3, 5, -3, -3},
+ {-3, -3, -3, 5, 0, -3, 5, 5, -3},
+ {-3, -3, -3, -3, 0, -3, 5, 5, 5},
+ {-3, -3, -3, -3, 0, 5, -3, 5, 5},
+ {-3, -3, 5, -3, 0, 5, -3, -3, 5},
+ {-3, 5, 5, -3, 0, 5, -3, -3, -3},
+ };
*free_this = NULL;
*rows = *cols = 3;
if (argc != 1)
eprintf(SUBUSAGE("'kirsch' direction"));
- if (STRCASEEQ3(argv[0], "1", "N", "N")) return MATRIX( 5, 5, 5, -3, 0, -3, -3, -3, -3);
- if (STRCASEEQ3(argv[0], "2", "NW", "WN")) return MATRIX( 5, 5, -3, 5, 0, -3, -3, -3, -3);
- if (STRCASEEQ3(argv[0], "3", "W", "W")) return MATRIX( 5, -3, -3, 5, 0, -3, 5, -3, -3);
- if (STRCASEEQ3(argv[0], "4", "SW", "WS")) return MATRIX(-3, -3, -3, 5, 0, -3, 5, 5, -3);
- if (STRCASEEQ3(argv[0], "5", "S", "S")) return MATRIX(-3, -3, -3, -3, 0, -3, 5, 5, 5);
- if (STRCASEEQ3(argv[0], "6", "SE", "ES")) return MATRIX(-3, -3, -3, -3, 0, 5, -3, 5, 5);
- if (STRCASEEQ3(argv[0], "7", "E", "E")) return MATRIX(-3, -3, 5, -3, 0, 5, -3, -3, 5);
- if (STRCASEEQ3(argv[0], "8", "NE", "EN")) return MATRIX(-3, 5, 5, -3, 0, 5, -3, -3, -3);
+ if (STRCASEEQ3(argv[0], "1", "N", "N")) return matrices[0];
+ if (STRCASEEQ3(argv[0], "2", "NW", "WN")) return matrices[1];
+ if (STRCASEEQ3(argv[0], "3", "W", "W")) return matrices[2];
+ if (STRCASEEQ3(argv[0], "4", "SW", "WS")) return matrices[3];
+ if (STRCASEEQ3(argv[0], "5", "S", "S")) return matrices[4];
+ if (STRCASEEQ3(argv[0], "6", "SE", "ES")) return matrices[5];
+ if (STRCASEEQ3(argv[0], "7", "E", "E")) return matrices[6];
+ if (STRCASEEQ3(argv[0], "8", "NE", "EN")) return matrices[7];
eprintf("Unrecognised direction: %s\n", argv[0]);
return NULL;
}
@@ -39,41 +48,85 @@ kernel_kirsch(int argc, char *argv[], size_t *rows, size_t *cols, double **free_
static const double *
kernel_box_blur(int argc, char *argv[], size_t *rows, size_t *cols, double **free_this)
{
- size_t sx, sy, i, n;
- double *cells, value;
+ size_t sx = 1, sy = 1, i, n;
+ double *cells, value, weight = 0;
+ int have_weight = 0;
+ char *arg;
*free_this = NULL;
*rows = *cols = 3;
- if (argc > 3)
- eprintf(SUBUSAGE("'box blur' [spread | x-spread y-spread]"));
- if (!argc)
- return MATRIX(1.0 / 9.0, 1.0 / 9.0, 1.0 / 9.0,
- 1.0 / 9.0, 1.0 / 9.0, 1.0 / 9.0,
- 1.0 / 9.0, 1.0 / 9.0, 1.0 / 9.0);
+
+#define argv0 arg
+ argc++, argv--;
+ ARGBEGIN {
+ case 'w':
+ if (!(arg = ARGF()))
+ goto usage;
+ weight = etolf_flag('w', arg);
+ have_weight = 1;
+ break;
+ default:
+ goto usage;
+ } ARGEND;
+#undef argv0
+
if (argc == 1) {
sx = sy = etozu_arg("spread", argv[0], 0, SIZE_MAX / 2);
- } else {
+ } else if (argc == 2) {
sx = etozu_arg("x-spread", argv[0], 0, SIZE_MAX / 2);
sy = etozu_arg("y-spread", argv[1], 0, SIZE_MAX / 2);
+ } else if (argc) {
+ goto usage;
}
+
*rows = 2 * sy + 1;
*cols = 2 * sx + 1;
*free_this = cells = emalloc3(*rows, *cols, sizeof(double));
+
n = (2 * sy + 1) * (2 * sx + 1);
value = 1 / (double)n;
+ if (have_weight)
+ value = (1.0 - weight) / (double)(n - 1);
for (i = 0; i < n; i++)
cells[i] = value;
+ if (have_weight)
+ cells[sy * *cols + sx] = weight;
return cells;
+
+usage:
+ eprintf(SUBUSAGE("'box blur' [-w weight] [spread | x-spread y-spread]"));
+ return NULL;
}
static const double *
kernel_sharpen(int argc, char *argv[], size_t *rows, size_t *cols, double **free_this)
{
+ static const double matrices[][9] = {
+ { 0, -1, 0, -1, 5, -1, 0, -1, 0},
+ {-1, -1, -1, -1, 9, -1, -1, -1, -1}
+ };
+ char *arg;
+ int intensified = 0;
*free_this = NULL;
*rows = *cols = 3;
+
+#define argv0 arg
+ argc++, argv--;
+ ARGBEGIN {
+ case 'i':
+ intensified = 1;
+ break;
+ default:
+ goto usage;
+ } ARGEND;
+#undef argv0
if (argc)
- eprintf(SUBUSAGE("'sharpen'"));
- return MATRIX(0, -1, 0, -1, 5, -1, 0, -1, -0);
- (void) argv;
+ goto usage;
+
+ return matrices[intensified];
+usage:
+ eprintf(SUBUSAGE("'sharpen' [-i]"));
+ return NULL;
+ (void) arg;
}
static const double *
@@ -147,6 +200,20 @@ usage:
return NULL;
}
+/* TODO more kernels:
+ Edge detection: MATRIX( 1, 0, -1, 0, 0, 0, -1, 0, 1)
+ Edge detection: MATRIX( 0, 1, 0, 1, -4, 1, 0, 1, 0)
+ Edge detection: MATRIX(-1, -1, -1, -1, 8, -1, -1, -1, -1)
+ Edge detection: MATRIX( 0, 0, 0, -1, 2, -1, 0, 0, 0) [H]
+ Edge detection: MATRIX( 0, -1, 0, 0, 2, 0, 0, -1, 0) [V]
+ Gradient detection: MATRIX(-1, -1, -1, 0, 0, 0, 1, 1, 1) [H]
+ Gradient detection: MATRIX(-1, 0, 1, -1, 0, 1, -1, 0, 1) [V]
+ Sobel operator: MATRIX( 1, 2, 1, 0, 0, 0, -1, -2, -1) [H]
+ Sobel operator: MATRIX( 1, 0, -1, 2, 0, -2, 1, 0, -1) [V]
+ Emboss: MATRIX(-2, -1, 0, -1, 1, 1, 0, 1, 2)
+ Edge enhance: MATRIX( 0, 0, 0, -1, 1, 0, 0, 0, 0)
+ */
+
int
main(int argc, char *argv[])
{