diff options
| author | Mattias Andrée <maandree@kth.se> | 2017-05-14 14:21:02 +0200 |
|---|---|---|
| committer | Mattias Andrée <maandree@kth.se> | 2017-05-14 14:21:02 +0200 |
| commit | 45c25008cbea5241fb711dc7a9ba21ec631bce64 (patch) | |
| tree | 2fb70aa8fc0c52ea97cf14adb3fa116f08a5b1e3 /src/blind-kernel.c | |
| parent | Add missing default case and use strcasecmp for cheching selecting direction (diff) | |
| download | blind-45c25008cbea5241fb711dc7a9ba21ec631bce64.tar.gz blind-45c25008cbea5241fb711dc7a9ba21ec631bce64.tar.bz2 blind-45c25008cbea5241fb711dc7a9ba21ec631bce64.tar.xz | |
Fix errors in blind-kernel and add -w to box blur, and update TODO
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to 'src/blind-kernel.c')
| -rw-r--r-- | src/blind-kernel.c | 109 |
1 files changed, 88 insertions, 21 deletions
diff --git a/src/blind-kernel.c b/src/blind-kernel.c index 4542e53..3e439ef 100644 --- 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[]) { |
