Files
Erik Auerswald 94ce321060 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.
2025-03-23 18:54:13 +01:00

186 lines
6.6 KiB
C

/* Seven Segment Optical Character Recognition Image Processing Functions */
/* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* Copyright (C) 2004-2025 Erik Auerswald <auerswal@unix-ag.uni-kl.de> */
#ifndef SSOCR2_IMGPROC_H
#define SSOCR2_IMGPROC_H
/* parse luminance keyword */
luminance_t parse_lum(char *keyword);
/* set foreground color */
void set_fg_color(int color);
/* set background color */
void set_bg_color(int color);
/* set imlib color */
void ssocr_set_color(fg_bg_t color);
/* draw a fore- or background pixel */
void draw_fg_bg_pixel(Imlib_Image *image, int x, int y, fg_bg_t color);
/* draw a foreground pixel */
void draw_fg_pixel(Imlib_Image *image, int x, int y);
/* draw a background pixel */
void draw_bg_pixel(Imlib_Image *image, int x, int y);
/* draw a pixel of a given color */
void draw_color_pixel(Imlib_Image *image, int x, int y, Imlib_Color color);
/* check if a pixel is set regarding current foreground/background colors */
int is_pixel_set(int value, double threshold);
/* set pixel if at least mask neighboring pixels (including the pixel to be set)
* are set
* a pixel is set if its luminance value is less than thresh
* mask=1 is the standard dilation filter
* mask=9 is the standard erosion filter */
Imlib_Image set_pixels_filter(Imlib_Image *source_image, double thresh,
luminance_t lt, int mask);
/* perform set pixel filter operation iter times */
Imlib_Image set_pixels_filter_iter(Imlib_Image *source_image, double thresh,
luminance_t lt, int mask, int iter);
/* shortcut for dilation */
Imlib_Image dilation(Imlib_Image *source_image, double thresh, luminance_t lt,
int n);
/* shortcut for erosion */
Imlib_Image erosion(Imlib_Image *source_image, double thresh, luminance_t lt,
int n);
/* shortcut for closing */
Imlib_Image closing(Imlib_Image *source_image, double thresh, luminance_t lt,
int n);
/* shortcut for opening */
Imlib_Image opening(Imlib_Image *source_image, double thresh, luminance_t lt,
int n);
/* keep only pixels that have at least mask-1 neighbors set */
Imlib_Image keep_pixels_filter(Imlib_Image *source_image, double thresh,
luminance_t lt, int mask);
/* remove isolated pixels (shortcut for keep_pixels_filter with mask = 2) */
Imlib_Image remove_isolated(Imlib_Image *source_image, double thresh,
luminance_t lt);
/* gray stretching, i.e. lum<t1 => lum=0, lum>t2 => lum=100,
* else lum=((lum-t1)*MAXRGB)/(t2-t1) */
Imlib_Image gray_stretch(Imlib_Image *source_image, double t1, double t2,
luminance_t lt);
/* use dynamic (aka adaptive) local thresholding to create monochrome image */
Imlib_Image dynamic_threshold(Imlib_Image *source_image, double t,
luminance_t lt ,int ww, int wh);
/* make black and white */
Imlib_Image make_mono(Imlib_Image *source_image, double thresh, luminance_t lt);
/* set pixel to black (0,0,0) if R<T, T=thresh/100*255 */
Imlib_Image r_threshold(Imlib_Image *source_image, double thresh);
/* set pixel to black (0,0,0) if G<T, T=thresh/100*255 */
Imlib_Image g_threshold(Imlib_Image *source_image, double thresh);
/* set pixel to black (0,0,0) if B<T, T=thresh/100*255 */
Imlib_Image b_threshold(Imlib_Image *source_image, double thresh);
/* make the border white */
Imlib_Image white_border(Imlib_Image *source_image, int width);
/* invert image */
Imlib_Image invert(Imlib_Image *source_image, double thresh, luminance_t lt);
/* shear the image
* the top line is unchanged
* the bottom line is moved offset pixels to the right
* the other lines are moved yPos*offset/(height-1) pixels to the right
* white pixels are inserted at the left side */
Imlib_Image shear(Imlib_Image *source_image, int offset);
/* rotate the image */
Imlib_Image rotate(Imlib_Image *source_image, double theta);
/* mirror image horizontally or vertically */
Imlib_Image mirror(Imlib_Image *source_image, direction_t direction);
/* turn image to grayscale */
Imlib_Image grayscale(Imlib_Image *source_image, luminance_t lt);
/* crop image */
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, int force_update);
/* compute dynamic threshold value from the rectangle (x,y),(x+w,y+h) of
* source_image */
double get_threshold(Imlib_Image *source_image, double fraction, luminance_t lt,
int x, int y, int w, int h);
/* determine threshold by an iterative method */
double iterative_threshold(Imlib_Image *source_image, double thresh,
luminance_t lt);
/* get minimum and maximum gray (luminace) values */
void get_minmaxval(Imlib_Image *source_image, luminance_t lt,
double *min, double *max);
/* compute luminance from RGB values */
int get_lum(Imlib_Color *color, luminance_t lt);
/* compute luminance Y_709 from linear RGB values */
int get_lum_709(Imlib_Color *color);
/* compute luminance Y_601 from gamma corrected (non-linear) RGB values */
int get_lum_601(Imlib_Color *color);
/* compute luminance Y = (R+G+B)/3 */
int get_lum_lin(Imlib_Color *color);
/* compute luminance Y = min(R,G,B) as used in GNU Ocrad 0.14 */
int get_lum_min(Imlib_Color *color);
/* compute luminance Y = max(R,G,B) */
int get_lum_max(Imlib_Color *color);
/* compute luminance Y = R */
int get_lum_red(Imlib_Color *color);
/* compute luminance Y = G */
int get_lum_green(Imlib_Color *color);
/* compute luminance Y = B */
int get_lum_blue(Imlib_Color *color);
/* clip value thus that it is in the given interval [min,max] */
int clip(int value, int min, int max);
/* save image to file */
void save_image(const char *image_type, Imlib_Image *image, const char *fmt,
const char *filename, unsigned int flags);
/* report Imlib2 load/save error to stderr */
void report_imlib_error(Imlib_Load_Error error);
#endif /* SSOCR2_IMGPROC_H */