From 94ce3210601ae0804ed2bee9752aa485868ddd3a Mon Sep 17 00:00:00 2001 From: Erik Auerswald Date: Sun, 23 Mar 2025 14:42:25 +0100 Subject: [PATCH] lazily adapt threshold to image Instead of adapting the threshold to the image before executing commands, adapt the threshold just before it is needed. This allows to avoid theshold adaptation when -p, --process-only is used with only the "grayscale" and/or "mirror" commands. This also prepares the code to allow introduction of a new option to avoid adapting the threshold to the original image before the "crop" command is applied. --- NEWS | 2 ++ defines.h | 4 ++++ imgproc.c | 8 ++++++-- imgproc.h | 2 +- ssocr.c | 27 +++++++++++++++++++++++---- 5 files changed, 36 insertions(+), 7 deletions(-) diff --git a/NEWS b/NEWS index f9ea105..afc8f62 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,8 @@ Version ?.??.? (????-??-??): --iter-threshold are used together because -a inhibits -T * Improved performance when reading image data via standard input * Improved performance when using gray_stretch together with -g + * Improved performance when using option -p, --process-only together + with only the grayscale and/or mirror commands * Documentation improvements Version 2.24.1 (2024-12-11): diff --git a/defines.h b/defines.h index f14fa34..95ef818 100644 --- a/defines.h +++ b/defines.h @@ -172,6 +172,10 @@ /* default luminance formula */ #define DEFAULT_LUM_FORMULA REC709 +/* when to adapt threshold values to the image */ +#define INITIAL 0 /* adapt threshold unless is was already adapted */ +#define UPDATE 1 /* adapt threshold even if it was adapted before */ + /* foreground and background */ typedef enum fg_bg_e { FG, diff --git a/imgproc.c b/imgproc.c index 8ccd31b..81a1eed 100644 --- a/imgproc.c +++ b/imgproc.c @@ -466,10 +466,13 @@ Imlib_Image make_mono(Imlib_Image *source_image, double thresh, luminance_t lt) /* adapt threshold to image values values */ double adapt_threshold(Imlib_Image *image, double thresh, luminance_t lt, - unsigned int flags) + unsigned int flags, int force_update) { double t = thresh; - if(!(flags & ABSOLUTE_THRESHOLD)) { + static int is_adapted = 0; + if(is_adapted && !force_update) { + fprintf(stderr, "threshold is already adjusted to image\n"); + } else if(!(flags & ABSOLUTE_THRESHOLD)) { if(flags & DEBUG_OUTPUT) fprintf(stderr, "adjusting threshold to image: %f ->", t); t = get_threshold(image, thresh/100.0, lt, 0, 0, -1, -1); @@ -482,6 +485,7 @@ double adapt_threshold(Imlib_Image *image, double thresh, luminance_t lt, if(flags & DEBUG_OUTPUT) fprintf(stderr, " %f\n", t); } + is_adapted = 1; } if((flags & VERBOSE) || (flags & DEBUG_OUTPUT)) { fprintf(stderr, "using threshold %.2f\n", t); diff --git a/imgproc.h b/imgproc.h index a79809e..8f75d97 100644 --- a/imgproc.h +++ b/imgproc.h @@ -130,7 +130,7 @@ Imlib_Image crop(Imlib_Image *source_image, int x, int y, int w, int h); /* adapt threshold to image values values */ double adapt_threshold(Imlib_Image *image, double thresh, luminance_t lt, - unsigned int flags); + unsigned int flags, int force_update); /* compute dynamic threshold value from the rectangle (x,y),(x+w,y+h) of * source_image */ diff --git a/ssocr.c b/ssocr.c index 900e75b..efe2665 100644 --- a/ssocr.c +++ b/ssocr.c @@ -735,9 +735,6 @@ int main(int argc, char **argv) min, max); } - /* adapt threshold to image */ - thresh = adapt_threshold(&image, thresh, lt, flags); - /* process commands */ if(flags & VERBOSE) /* then print found commands */ { if(optind >= argc-1) { @@ -771,6 +768,7 @@ int main(int argc, char **argv) n = 1; if(flags & VERBOSE) fputs(" processing dilation (1)\n", stderr); } + thresh = adapt_threshold(&image, thresh, lt, flags, INITIAL); new_image = dilation(&image, thresh, lt, n); imlib_context_set_image(image); imlib_free_image(); @@ -790,6 +788,7 @@ int main(int argc, char **argv) n = 1; if(flags & VERBOSE) fputs(" processing erosion (1)\n", stderr); } + thresh = adapt_threshold(&image, thresh, lt, flags, INITIAL); new_image = erosion(&image, thresh, lt, n); imlib_context_set_image(image); imlib_free_image(); @@ -809,6 +808,7 @@ int main(int argc, char **argv) n = 1; if(flags & VERBOSE) fputs(" processing opening (1)\n", stderr); } + thresh = adapt_threshold(&image, thresh, lt, flags, INITIAL); new_image = opening(&image, thresh, lt, n); imlib_context_set_image(image); imlib_free_image(); @@ -828,18 +828,21 @@ int main(int argc, char **argv) n = 1; if(flags & VERBOSE) fputs(" processing closing (1)\n", stderr); } + thresh = adapt_threshold(&image, thresh, lt, flags, INITIAL); new_image = closing(&image, thresh, lt, n); imlib_context_set_image(image); imlib_free_image(); image = new_image; } else if(strcasecmp("remove_isolated",argv[i]) == 0) { if(flags & VERBOSE) fputs(" processing remove_isolated\n", stderr); + thresh = adapt_threshold(&image, thresh, lt, flags, INITIAL); new_image = remove_isolated(&image, thresh, lt); imlib_context_set_image(image); imlib_free_image(); image = new_image; } else if(strcasecmp("make_mono",argv[i]) == 0) { if(flags & VERBOSE) fputs(" processing make_mono\n", stderr); + thresh = adapt_threshold(&image, thresh, lt, flags, INITIAL); new_image = make_mono(&image, thresh, lt); imlib_context_set_image(image); imlib_free_image(); @@ -860,6 +863,7 @@ int main(int argc, char **argv) if(flags & VERBOSE) fputs(" processing white_border (1)\n", stderr); } + thresh = adapt_threshold(&image, thresh, lt, flags, INITIAL); new_image = white_border(&image, bdwidth); imlib_context_set_image(image); imlib_free_image(); @@ -874,6 +878,7 @@ int main(int argc, char **argv) } if(i+1