Compare commits
76 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 443b100ab9 | |||
| 63495ef4a8 | |||
| 9d9b2253e1 | |||
| e914669079 | |||
| 94ce321060 | |||
| 7cae796188 | |||
| 7f2a9f3f22 | |||
| 00312ee70e | |||
| e309861f24 | |||
| 4b5c6ea770 | |||
| 56d1b22118 | |||
| eaf0f32850 | |||
| fa30f473e7 | |||
| 67abe0fba8 | |||
| ac060de96b | |||
| 74aeb44f94 | |||
| f012c14d93 | |||
| b44a4ad72a | |||
| 13a5ec3802 | |||
| 2824d0aea7 | |||
| 5439679c83 | |||
| e7a20fbb2d | |||
| 88a627050a | |||
| 6e8c8361fd | |||
| ad5b6da118 | |||
| 7485ba3ffc | |||
| acdf26c6bf | |||
| 4ab3869eea | |||
| 70692aa5c4 | |||
| 9964c8ce85 | |||
| 895b0cb2b5 | |||
| 894f3035fd | |||
| 40c34ad6d7 | |||
| bae7381e34 | |||
| d6be469e14 | |||
| af6c53c3f3 | |||
| b05410efae | |||
| 6569ca9f6b | |||
| 48da4ee8c1 | |||
| 1a8c4d7701 | |||
| 624e998efb | |||
| 81c5472b69 | |||
| 6fc62729e9 | |||
| 19f93dcb58 | |||
| 5ca3455873 | |||
| 2026f39ee7 | |||
| 73e7a69b4c | |||
| f25047745d | |||
| 658230679a | |||
| 1fe392c772 | |||
| 2ff3d882b9 | |||
| f06f8441fd | |||
| a5c550b72b | |||
| 0c3adc9002 | |||
| ad9027b6a0 | |||
| 66dbee3591 | |||
| c6e09b8f70 | |||
| 7e056835fa | |||
| 050830a709 | |||
| 27e7913135 | |||
| 0cd776b479 | |||
| cf2391f400 | |||
| 898f5ec712 | |||
| 9e2d37ddbf | |||
| 8df40937c9 | |||
| 06c2afc85e | |||
| 2d6b019842 | |||
| 8660a65ebd | |||
| fe272d21ef | |||
| 61721919cc | |||
| d5b6c0852d | |||
| ea8f724846 | |||
| 320487e300 | |||
| 9386643c60 | |||
| f7098c6ff5 | |||
| 3ebd31d09d |
@@ -23,9 +23,10 @@ build a .deb package by typing:
|
||||
|
||||
Prerequisites
|
||||
-------------
|
||||
- A C compiler compatible with GCC.
|
||||
- A system sufficiently compatible to POSIX and GNU.
|
||||
- POSIX utilities: chmod, printf, sh, sed (or compatible)
|
||||
- GNU utilities: date, gzip, install, tar (or compatible)
|
||||
- POSIX utilities: chmod, head, printf, sh, sed (or compatible)
|
||||
- GNU utilities: date, gzip, install, make, tar (or compatible)
|
||||
- Other utilities: bzip2
|
||||
- Imlib2 shared library and development headers. On a Debian or Ubuntu system
|
||||
they are provided by the packages libimlib2 and libimlib2-dev.
|
||||
@@ -37,8 +38,11 @@ Prerequisites
|
||||
- Imlib2 requires the X11/Xlib.h header and links against some X11 libraries,
|
||||
at least on GNU/Linux with X11 GUI, thus X11 shared libraries and development
|
||||
headers are required for ssocr, too, although ssocr does not use X11 itself
|
||||
- Build tools, e.g. build-essential on a Debian (or Ubuntu) system.
|
||||
- Build tools, e.g., build-essential on a Debian (or Ubuntu) system, usually
|
||||
contain both make and a C compiler.
|
||||
- To build a .deb package, you probably need the debhelper package.
|
||||
- To create an HTML version of the man page, you need a man utility that can
|
||||
produce HTML output.
|
||||
|
||||
Additional Makefile Targets
|
||||
---------------------------
|
||||
@@ -93,6 +97,6 @@ https://www.unix-ag.uni-kl.de/~auerswal/ssocr/
|
||||
|
||||
Third Party Packages
|
||||
--------------------
|
||||
There exist third party packaging efforts for e.g. GNU/Linux distributions
|
||||
There exist third party packaging efforts for, e.g., GNU/Linux distributions
|
||||
and FreeBSD. Thus you can search the packaging system of your distribution
|
||||
for an ssocr package.
|
||||
|
||||
@@ -8,8 +8,9 @@ BINDIR := $(PREFIX)/bin
|
||||
MANDIR := $(PREFIX)/share/man/man1
|
||||
DOCDIR := $(PREFIX)/share/doc/ssocr
|
||||
DOCS := AUTHORS COPYING INSTALL README THANKS NEWS
|
||||
VERSION := $(shell sed -n 's/^.*VERSION.*\(".*"\).*/\1/p' defines.h)
|
||||
VERSION := $(shell sed -n 's/^.*VERSION.*"\(.*\)".*/\1/p' defines.h)
|
||||
CRYEARS := $(shell sed -n 's/^.*fprintf.*Copyright.*\(2004-2[0-9][0-9][0-9]\).*Erik.*Auerswald.*$$/\1/p' help.c)
|
||||
RELDATE := $(shell sed -n 's/^Version [.0-9]* .\([-0-9]*\).*$$/\1/p' NEWS | head -n1)
|
||||
|
||||
all: ssocr ssocr.1
|
||||
|
||||
@@ -20,9 +21,9 @@ imgproc.o: imgproc.c defines.h imgproc.h help.h Makefile
|
||||
help.o: help.c defines.h imgproc.h help.h Makefile
|
||||
charset.o: charset.c charset.h defines.h help.h Makefile
|
||||
|
||||
ssocr.1: ssocr.1.in Makefile defines.h
|
||||
ssocr.1: ssocr.1.in Makefile defines.h help.c NEWS
|
||||
sed -e 's/@VERSION@/$(VERSION)/' \
|
||||
-e "s/@DATE@/$(shell date +%Y-%m-%d)/" \
|
||||
-e 's/@DATE@/$(RELDATE)/' \
|
||||
-e 's/@CRYEARS@/$(CRYEARS)/' <$< >$@
|
||||
|
||||
ssocr-manpage.html: ssocr.1
|
||||
@@ -43,7 +44,7 @@ ssocr-dir:
|
||||
chmod +x ssocr-$(VERSION)/notdebian/rules
|
||||
|
||||
notdebian/changelog:
|
||||
printf "ssocr ($(VERSION)-1) unstable; urgency=low\n\n * self built package of current ssocr version in .deb format\n\n -- $(USER) $(shell date -R)\n" >$@
|
||||
printf 'ssocr ($(VERSION)-1) unstable; urgency=low\n\n * self built package of current ssocr version in .deb format\n\n -- $(USER) $(shell date -R)\n' >$@
|
||||
|
||||
selfdeb: notdebian/changelog notdebian/control notdebian/rules ssocr-dir
|
||||
(cd ssocr-$(VERSION); ln -sv notdebian debian; fakeroot debian/rules binary; fakeroot debian/rules clean; rm -f debian)
|
||||
|
||||
@@ -1,6 +1,54 @@
|
||||
Noteworthy Changes in ssocr Releases
|
||||
====================================
|
||||
|
||||
Version 2.25.1 (2025-10-31):
|
||||
----------------------------
|
||||
* Fix one debug message to be printed only with -P, --debug-output
|
||||
|
||||
Version 2.25.0 (2025-03-23):
|
||||
----------------------------
|
||||
* New option -F, --adapt-after-crop to skip threshold adjustment directly
|
||||
before cropping the image
|
||||
* Print warning when the two options -a, --absolute-threshold and -T,
|
||||
--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):
|
||||
----------------------------
|
||||
* Print warning when an unknown charset name is ignored
|
||||
* Print warning when an unknown luminance formula name is ignored
|
||||
* Fix one debug message to be printed only with -P, --debug-output
|
||||
* Documentation improvements
|
||||
|
||||
Version 2.24.0 (2024-06-22):
|
||||
----------------------------
|
||||
* Fix decimal separator recognition when widest digit is a one
|
||||
* Add recognition of lower case variant of character 'h' to full charset
|
||||
* Add recognition of lower case variant of character 'r' to full charset
|
||||
* Documentation improvements
|
||||
* Error, warning, and debug message improvements
|
||||
|
||||
Version 2.23.1 (2023-05-18):
|
||||
----------------------------
|
||||
* The man page uses the latest ssocr release date as its date (to help
|
||||
in creating reproducible builds)
|
||||
* Documentation improvements
|
||||
|
||||
Version 2.23.0 (2023-05-01):
|
||||
----------------------------
|
||||
* New option -N, --min-segment to specify the minimum width and height of
|
||||
a segment, for both scanline based and ratio based character recognition
|
||||
* New option -M, --min-char-dims to specify minimum character dimensions
|
||||
* The option -d, --number-digits now also accepts a range description
|
||||
|
||||
Version 2.22.2 (2023-04-24):
|
||||
----------------------------
|
||||
* Documentation improvements
|
||||
|
||||
Version 2.22.1 (2022-01-25):
|
||||
----------------------------
|
||||
* Fix build failure with Imlib 1.7.5 (pkg-config replaces imlib2-config)
|
||||
|
||||
@@ -7,7 +7,7 @@ as well), Mac OS X (Homebrew can be used to install the library Imlib2,
|
||||
used by ssocr), and even on Windows (using Cygwin). ssocr should work
|
||||
on any UNIX-like or POSIX compatible operating system.
|
||||
|
||||
Unless ssocr is installed via some packaging system, e.g. from a GNU/Linux
|
||||
Unless ssocr is installed via some packaging system, e.g., from a GNU/Linux
|
||||
distribution, it is distributed in source form and needs to be built
|
||||
before it can be used. See the INSTALL file for instructions on how to
|
||||
build ssocr.
|
||||
@@ -19,7 +19,7 @@ quotes).
|
||||
You can get the current ssocr version from the official ssocr website:
|
||||
https://www.unix-ag.uni-kl.de/~auerswal/ssocr/
|
||||
(Links to ssocr should point to the official website, not to a convenience
|
||||
copy of the development repository, e.g. on GitHub.)
|
||||
copy of the development repository, e.g., on GitHub.)
|
||||
|
||||
I am usually quicker to reply to emails than to GitHub issues. But
|
||||
increasingly Google blocks emails sent by me, so if you do not receive
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* Copyright (C) 2018-2022 Erik Auerswald <auerswal@unix-ag.uni-kl.de> */
|
||||
/* Copyright (C) 2018-2025 Erik Auerswald <auerswal@unix-ag.uni-kl.de> */
|
||||
|
||||
/* standard things */
|
||||
#include <stdio.h> /* puts, printf, BUFSIZ, perror, FILE */
|
||||
@@ -44,7 +44,7 @@ charset_t parse_charset(char *keyword)
|
||||
} else if(strncasecmp(keyword, "tt_robot", 8) == 0) {
|
||||
return CS_TT_ROBOT;
|
||||
} else {
|
||||
return DEFAULT_CHARSET;
|
||||
return CS_PARSE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,9 +86,13 @@ void init_charset(charset_t cs)
|
||||
charset_array[D_T] = 't';
|
||||
charset_array[D_L] = 'l';
|
||||
charset_array[D_H] = 'h';
|
||||
charset_array[D_h] = 'h';
|
||||
charset_array[D_R] = 'r';
|
||||
charset_array[D_ALT_R] = 'r';
|
||||
charset_array[D_r] = 'r';
|
||||
charset_array[D_P] = 'p';
|
||||
charset_array[D_N] = 'n';
|
||||
charset_array[D_n] = 'n';
|
||||
charset_array[D_Y] = 'y';
|
||||
charset_array[D_J] = 'j';
|
||||
break;
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* Copyright (C) 2018-2022 Erik Auerswald <auerswal@unix-ag.uni-kl.de> */
|
||||
/* Copyright (C) 2018-2025 Erik Auerswald <auerswal@unix-ag.uni-kl.de> */
|
||||
|
||||
#ifndef SSOCR2_CHARSET_H
|
||||
#define SSOCR2_CHARSET_H
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* Copyright (C) 2004-2022 Erik Auerswald <auerswal@unix-ag.uni-kl.de> */
|
||||
/* Copyright (C) 2004-2025 Erik Auerswald <auerswal@unix-ag.uni-kl.de> */
|
||||
/* Copyright (C) 2013 Cristiano Fontana <fontanacl@ornl.gov> */
|
||||
|
||||
#define PROG "ssocr"
|
||||
@@ -23,7 +23,7 @@
|
||||
#define SSOCR2_DEFINES_H
|
||||
|
||||
/* version number */
|
||||
#define VERSION "2.22.1"
|
||||
#define VERSION "2.25.1"
|
||||
|
||||
/* states */
|
||||
#define FIND_DARK 0
|
||||
@@ -76,6 +76,7 @@
|
||||
#define D_HEX_A (ALL_SEGS & ~HORIZ_DOWN)
|
||||
#define D_HEX_b (ALL_SEGS & ~(HORIZ_UP | VERT_RIGHT_UP))
|
||||
#define D_HEX_C (ALL_SEGS & ~(VERT_RIGHT_UP | HORIZ_MID | VERT_RIGHT_DOWN))
|
||||
/* a C in the lower half can only happen when digit boundary detection fails */
|
||||
#define D_HEX_c (HORIZ_MID | VERT_LEFT_DOWN | HORIZ_DOWN)
|
||||
#define D_HEX_d (ALL_SEGS & ~(HORIZ_UP | VERT_LEFT_UP))
|
||||
#define D_HEX_E (ALL_SEGS & ~(VERT_RIGHT_UP | VERT_RIGHT_DOWN))
|
||||
@@ -84,10 +85,15 @@
|
||||
#define D_T (ALL_SEGS & ~(HORIZ_UP | VERT_RIGHT_UP | VERT_RIGHT_DOWN))
|
||||
#define D_L (D_T & ~HORIZ_MID)
|
||||
#define D_H (ALL_SEGS & ~(HORIZ_UP | HORIZ_DOWN))
|
||||
#define D_h (VERT_LEFT_UP | VERT_LEFT_DOWN | HORIZ_MID | VERT_RIGHT_DOWN)
|
||||
#define D_R (D_ZERO & ~(VERT_RIGHT_DOWN | HORIZ_DOWN))
|
||||
#define D_ALT_R (VERT_LEFT_UP | VERT_LEFT_DOWN | HORIZ_UP)
|
||||
/* an r in the lower half can only happen when digit boundary detection fails */
|
||||
#define D_r (VERT_LEFT_DOWN | HORIZ_MID)
|
||||
#define D_P (D_HEX_F | VERT_RIGHT_UP)
|
||||
#define D_N (D_ZERO & ~HORIZ_DOWN)
|
||||
/* an N in the lower half can only happen when digit boundary detection fails *//* define D_LOW_N (VERT_LEFT_DOWN | VERT_RIGHT_DOWN | HORIZ_MID) */
|
||||
/* an N in the lower half can only happen when digit boundary detection fails */
|
||||
#define D_n (VERT_LEFT_DOWN | VERT_RIGHT_DOWN | HORIZ_MID)
|
||||
#define D_Y (ALL_SEGS & ~(HORIZ_UP | VERT_LEFT_DOWN))
|
||||
#define D_J (HORIZ_DOWN | VERT_RIGHT_UP | VERT_RIGHT_DOWN)
|
||||
/* add two "wrong" 7 definitions used in a character set for a Chinese
|
||||
@@ -113,9 +119,21 @@
|
||||
/* add space characters if digit distance is greater than SPC_FAC * min dist */
|
||||
#define SPC_FAC 1.4
|
||||
|
||||
/* to find segment need # of pixels */
|
||||
/* number of set pixels needed in a scanline to recognize a segment */
|
||||
#define NEED_PIXELS 1
|
||||
|
||||
/* minimum number of pixels required for a segment
|
||||
* this generalizes to both scanline and ratio based digit detection,
|
||||
* but only when the digit is built using segments, i.e., this is not
|
||||
* used for decimal separators */
|
||||
#define MIN_SEGMENT 1
|
||||
|
||||
/* minimum width of a character respectively digit */
|
||||
#define MIN_CHAR_W 1
|
||||
|
||||
/* minimum height of a character respectively digit */
|
||||
#define MIN_CHAR_H 1
|
||||
|
||||
/* ignore # of pixels when checking a column fo black or white */
|
||||
#define IGNORE_PIXELS 0
|
||||
|
||||
@@ -138,6 +156,7 @@
|
||||
#define OMIT_DECIMAL (1<<10)
|
||||
#define PRINT_SPACES (1<<11)
|
||||
#define SPC_USE_AVG_DST (1<<12)
|
||||
#define ADAPT_AFTER_CROP (1<<13)
|
||||
|
||||
/* colors used by ssocr */
|
||||
#define SSOCR_BLACK 0
|
||||
@@ -154,6 +173,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,
|
||||
@@ -169,10 +192,11 @@ typedef enum luminance_e {
|
||||
MAXIMUM,
|
||||
RED,
|
||||
GREEN,
|
||||
BLUE
|
||||
BLUE,
|
||||
LUM_PARSE_ERROR
|
||||
} luminance_t;
|
||||
|
||||
/* direction, to mirror horizontally or vertically, or for a scan line */
|
||||
/* direction, to mirror horizontally or vertically, or for a scanline */
|
||||
typedef enum direction_e {
|
||||
HORIZONTAL,
|
||||
VERTICAL
|
||||
@@ -184,7 +208,8 @@ typedef enum charset_e {
|
||||
CS_DIGITS,
|
||||
CS_DECIMAL,
|
||||
CS_HEXADECIMAL,
|
||||
CS_TT_ROBOT
|
||||
CS_TT_ROBOT,
|
||||
CS_PARSE_ERROR
|
||||
} charset_t;
|
||||
|
||||
#define DEFAULT_CHARSET CS_FULL
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* Copyright (C) 2004-2022 Erik Auerswald <auerswal@unix-ag.uni-kl.de> */
|
||||
/* Copyright (C) 2004-2025 Erik Auerswald <auerswal@unix-ag.uni-kl.de> */
|
||||
/* Copyright (C) 2013 Cristiano Fontana <fontanacl@ornl.gov> */
|
||||
|
||||
/* standard things */
|
||||
@@ -92,11 +92,11 @@ void print_version(FILE *f)
|
||||
{
|
||||
fprintf(f, "Seven Segment Optical Character Recognition Version %s\n",
|
||||
VERSION);
|
||||
fprintf(f, "Copyright (C) 2004-2022 by Erik Auerswald"
|
||||
fprintf(f, "Copyright (C) 2004-2025 Erik Auerswald"
|
||||
" <auerswal@unix-ag.uni-kl.de>\n");
|
||||
fprintf(f, "This program comes with ABSOLUTELY NO WARRANTY\n");
|
||||
fprintf(f, "This program comes with ABSOLUTELY NO WARRANTY.\n");
|
||||
fprintf(f, "This is free software, and you are welcome to redistribute it"
|
||||
" under the terms\nof the GNU GPL (version 3 or later)\n");
|
||||
" under the terms\nof the GNU GPL (version 3 or later).\n");
|
||||
}
|
||||
|
||||
/* print short usage */
|
||||
@@ -120,9 +120,12 @@ void usage(char *name, FILE *f)
|
||||
fprintf(f, " -a, --absolute-threshold don't adjust threshold to image\n");
|
||||
fprintf(f, " -T, --iter-threshold use iterative thresholding method\n");
|
||||
fprintf(f, " -n, --number-pixels=# number of pixels needed to recognize a segment\n");
|
||||
fprintf(f, " -N, --min-segment=SIZE minimum width and height of a segment\n");
|
||||
fprintf(f, " -i, --ignore-pixels=# number of pixels ignored when searching digit\n");
|
||||
fprintf(f, " boundaries\n");
|
||||
fprintf(f, " -d, --number-digits=# number of digits in image (-1 for auto)\n");
|
||||
fprintf(f, " -M, --min-char-dims=WxH minimum width and height of a character/digit\n");
|
||||
fprintf(f, " -d, --number-digits=RNG number of digits in image (-1 for auto,\n");
|
||||
fprintf(f, " positive number, or positive range)\n");
|
||||
fprintf(f, " -r, --one-ratio=# height/width ratio to recognize a \'one\'\n");
|
||||
fprintf(f, " -m, --minus-ratio=# width/height ratio to recognize a minus sign\n");
|
||||
fprintf(f, " -H, --dec-h-ratio=# max_dig_h/h ratio to recognize decimal point\n");
|
||||
@@ -148,6 +151,8 @@ void usage(char *name, FILE *f)
|
||||
fprintf(f, " -C, --omit-decimal-point omit decimal points from output\n");
|
||||
fprintf(f, " -c, --charset=KEYWORD select recognized characters\n");
|
||||
fprintf(f, " use -c help for list of KEYWORDS\n");
|
||||
fprintf(f, " -F, --adapt-after-crop do not adapt threshold to image directly\n"
|
||||
" before, only after, cropping\n");
|
||||
fprintf(f, "\nCommands: dilation [N] [N times] dilation algorithm"
|
||||
"\n (set_pixels_filter with mask"
|
||||
" of 1 pixel)\n");
|
||||
@@ -176,7 +181,7 @@ void usage(char *name, FILE *f)
|
||||
fprintf(f, " color\n");
|
||||
fprintf(f, " shear OFFSET shear image OFFSET pixels (at bottom) to the\n");
|
||||
fprintf(f, " right\n");
|
||||
fprintf(f, " rotate THETA rotate image by THETA degrees\n");
|
||||
fprintf(f, " rotate THETA rotate image clockwise by THETA degrees\n");
|
||||
fprintf(f, " mirror {horiz|vert} mirror image horizontally or vertically\n");
|
||||
fprintf(f, " crop X Y W H crop image with upper left corner (X,Y) with\n");
|
||||
fprintf(f, " width W and height H\n");
|
||||
@@ -184,22 +189,26 @@ void usage(char *name, FILE *f)
|
||||
fprintf(f, " pixels set (including checked position)\n");
|
||||
fprintf(f, " keep_pixels_filter MASK keeps pixels that have at least MASK neighbor\n");
|
||||
fprintf(f, " pixels set (not counting the checked pixel)\n");
|
||||
fprintf(f, "\nDefaults: needed pixels = %2d\n", NEED_PIXELS);
|
||||
fprintf(f, " ignored pixels = %2d\n", IGNORE_PIXELS);
|
||||
fprintf(f, " no. of digits = %2d\n", NUMBER_OF_DIGITS);
|
||||
fprintf(f, " threshold = %5.2f\n", THRESHOLD);
|
||||
fprintf(f, " foreground = %s\n",
|
||||
fprintf(f, "\nDefaults: needed pixels = %2d\n", NEED_PIXELS);
|
||||
fprintf(f, " minimum segment size = %2d\n", MIN_SEGMENT);
|
||||
fprintf(f, " minimum character width = %2d\n", MIN_CHAR_W);
|
||||
fprintf(f, " minimum character height = %2d\n", MIN_CHAR_H);
|
||||
fprintf(f, " ignored pixels = %2d\n", IGNORE_PIXELS);
|
||||
fprintf(f, " minimum number of digits = %2d\n", NUMBER_OF_DIGITS);
|
||||
fprintf(f, " maximum number of digits = %2d\n", NUMBER_OF_DIGITS);
|
||||
fprintf(f, " threshold = %5.2f\n", THRESHOLD);
|
||||
fprintf(f, " foreground = %s\n",
|
||||
(SSOCR_DEFAULT_FOREGROUND == SSOCR_BLACK) ? "black" : "white");
|
||||
fprintf(f, " background = %s\n",
|
||||
fprintf(f, " background = %s\n",
|
||||
(SSOCR_DEFAULT_BACKGROUND == SSOCR_BLACK) ? "black" : "white");
|
||||
fprintf(f, " luminance = ");
|
||||
fprintf(f, " luminance = ");
|
||||
print_lum_key(DEFAULT_LUM_FORMULA, f); fprintf(f, "\n");
|
||||
fprintf(f, " height/width threshold = %2d\n", ONE_RATIO);
|
||||
fprintf(f, " height/width threshold for digit one = %2d\n", ONE_RATIO);
|
||||
fprintf(f, " width/height threshold for minus sign = %2d\n", MINUS_RATIO);
|
||||
fprintf(f, " max_dig_h/h threshold for decimal sep = %2d\n", DEC_H_RATIO);
|
||||
fprintf(f, " max_dig_w/w threshold for decimal sep = %2d\n", DEC_W_RATIO);
|
||||
fprintf(f, " space width factor = %.2f\n", SPC_FAC);
|
||||
fprintf(f, " character set = ");
|
||||
fprintf(f, " space width factor = %.2f\n", SPC_FAC);
|
||||
fprintf(f, " character set = ");
|
||||
print_cs_key(DEFAULT_CHARSET, f); fputs("\n", f);
|
||||
fprintf(f, "\nOperation: The IMAGE is read, the COMMANDs are processed in the sequence\n");
|
||||
fprintf(f, " they are given, in the resulting image the given number of digits\n");
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* Copyright (C) 2004-2022 Erik Auerswald <auerswal@unix-ag.uni-kl.de> */
|
||||
/* Copyright (C) 2004-2025 Erik Auerswald <auerswal@unix-ag.uni-kl.de> */
|
||||
|
||||
#ifndef SSOCR2_HELP_H
|
||||
#define SSOCR2_HELP_H
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* Copyright (C) 2004-2022 Erik Auerswald <auerswal@unix-ag.uni-kl.de> */
|
||||
/* Copyright (C) 2004-2025 Erik Auerswald <auerswal@unix-ag.uni-kl.de> */
|
||||
|
||||
/* ImLib2 Header */
|
||||
#include <X11/Xlib.h> /* needed by Imlib2.h */
|
||||
@@ -27,8 +27,11 @@
|
||||
/* string manipulation */
|
||||
#include <string.h> /* strcasecmp, strcmp, strrchr */
|
||||
|
||||
/* sin, cos */
|
||||
#include <math.h>
|
||||
/* trigonometry */
|
||||
#include <math.h> /* sin, cos, M_PI */
|
||||
#ifndef M_PI /* sometimes, M_PI is not defined */
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
/* my headers */
|
||||
#include "defines.h" /* defines */
|
||||
@@ -76,12 +79,12 @@ void ssocr_set_color(fg_bg_t color)
|
||||
}
|
||||
|
||||
/* draw a fore- or background pixel */
|
||||
void draw_pixel(Imlib_Image *image, int x, int y, fg_bg_t color)
|
||||
void draw_fg_bg_pixel(Imlib_Image *image, int x, int y, fg_bg_t color)
|
||||
{
|
||||
Imlib_Image *current_image; /* save current image */
|
||||
|
||||
current_image = imlib_context_get_image();
|
||||
imlib_context_set_image(image);
|
||||
imlib_context_set_image(*image);
|
||||
ssocr_set_color(color);
|
||||
imlib_image_draw_pixel(x,y,0);
|
||||
imlib_context_set_image(current_image);
|
||||
@@ -90,13 +93,25 @@ void draw_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_pixel(image, x, y, FG);
|
||||
draw_fg_bg_pixel(image, x, y, FG);
|
||||
}
|
||||
|
||||
/* draw a background pixel */
|
||||
void draw_bg_pixel(Imlib_Image *image, int x, int y)
|
||||
{
|
||||
draw_pixel(image, x, y, BG);
|
||||
draw_fg_bg_pixel(image, x, y, BG);
|
||||
}
|
||||
|
||||
/* draw a pixel of a given color */
|
||||
void draw_color_pixel(Imlib_Image *image, int x, int y, Imlib_Color color)
|
||||
{
|
||||
Imlib_Image *current_image; /* save current image */
|
||||
|
||||
current_image = imlib_context_get_image();
|
||||
imlib_context_set_image(*image);
|
||||
imlib_context_set_color(color.red, color.green, color.blue, color.alpha);
|
||||
imlib_image_draw_pixel(x, y, 0);
|
||||
imlib_context_set_image(current_image);
|
||||
}
|
||||
|
||||
/* check if a pixel is set regarding current foreground/background colors */
|
||||
@@ -165,9 +180,9 @@ Imlib_Image set_pixels_filter(Imlib_Image *source_image, double thresh,
|
||||
}
|
||||
/* set pixel if at least mask pixels around it are set */
|
||||
if(set_pixel >= mask) {
|
||||
draw_fg_pixel(new_image, x, y);
|
||||
draw_fg_pixel(&new_image, x, y);
|
||||
} else {
|
||||
draw_bg_pixel(new_image, x, y);
|
||||
draw_bg_pixel(&new_image, x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -257,12 +272,6 @@ Imlib_Image keep_pixels_filter(Imlib_Image *source_image, double thresh,
|
||||
width = imlib_image_get_width();
|
||||
new_image = imlib_clone_image();
|
||||
|
||||
/* draw white (background) rectangle to clear new image */
|
||||
imlib_context_set_image(new_image);
|
||||
ssocr_set_color(BG);
|
||||
imlib_image_draw_rectangle(0, 0, width, height);
|
||||
imlib_context_set_image(*source_image);
|
||||
|
||||
/* check for every pixel if it should be set in filtered image */
|
||||
for(x=0; x<width; x++) {
|
||||
for(y=0; y<height; y++) {
|
||||
@@ -285,9 +294,9 @@ Imlib_Image keep_pixels_filter(Imlib_Image *source_image, double thresh,
|
||||
/* set pixel if at least mask pixels around it are set */
|
||||
/* mask = 1 keeps all pixels */
|
||||
if(set_pixel > mask) {
|
||||
draw_fg_pixel(new_image, x, y);
|
||||
draw_fg_pixel(&new_image, x, y);
|
||||
} else {
|
||||
draw_bg_pixel(new_image, x, y);
|
||||
draw_bg_pixel(&new_image, x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -402,9 +411,9 @@ Imlib_Image dynamic_threshold(Imlib_Image *source_image,double t,luminance_t lt,
|
||||
lum = get_lum(&color, lt);
|
||||
thresh = get_threshold(source_image, t/100.0, lt, x-ww/2, y-ww/2, ww, wh);
|
||||
if(is_pixel_set(lum, thresh)) {
|
||||
draw_fg_pixel(new_image, x, y);
|
||||
draw_fg_pixel(&new_image, x, y);
|
||||
} else {
|
||||
draw_bg_pixel(new_image, x, y);
|
||||
draw_bg_pixel(&new_image, x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -441,9 +450,9 @@ Imlib_Image make_mono(Imlib_Image *source_image, double thresh, luminance_t lt)
|
||||
imlib_image_query_pixel(x, y, &color);
|
||||
lum = get_lum(&color, lt);
|
||||
if(is_pixel_set(lum, thresh)) {
|
||||
draw_fg_pixel(new_image, x, y);
|
||||
draw_fg_pixel(&new_image, x, y);
|
||||
} else {
|
||||
draw_bg_pixel(new_image, x, y);
|
||||
draw_bg_pixel(&new_image, x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -456,23 +465,28 @@ 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, int x,
|
||||
int y, int w, int h, unsigned int flags)
|
||||
double adapt_threshold(Imlib_Image *image, double thresh, luminance_t lt,
|
||||
unsigned int flags, int force_update)
|
||||
{
|
||||
double t = thresh;
|
||||
if(!(flags & ABSOLUTE_THRESHOLD)) {
|
||||
static int is_adapted = 0;
|
||||
if(is_adapted && !force_update) {
|
||||
if(flags & DEBUG_OUTPUT)
|
||||
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, x, y, w, h);
|
||||
t = get_threshold(image, thresh/100.0, lt, 0, 0, -1, -1);
|
||||
if(flags & DEBUG_OUTPUT)
|
||||
fprintf(stderr, " %f\n", t);
|
||||
if(flags & DO_ITERATIVE_THRESHOLD) {
|
||||
if(flags & DEBUG_OUTPUT)
|
||||
fprintf(stderr, "doing iterative_thresholding: %f ->", t);
|
||||
t = iterative_threshold(image, t, lt, x, y, w, h);
|
||||
t = iterative_threshold(image, 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);
|
||||
@@ -528,7 +542,7 @@ double get_threshold(Imlib_Image *source_image, double fraction, luminance_t lt,
|
||||
|
||||
/* determine threshold by an iterative method */
|
||||
double iterative_threshold(Imlib_Image *source_image, double thresh,
|
||||
luminance_t lt, int x, int y, int w, int h)
|
||||
luminance_t lt)
|
||||
{
|
||||
Imlib_Image current_image; /* save image pointer */
|
||||
int height, width; /* image dimensions */
|
||||
@@ -553,23 +567,13 @@ double iterative_threshold(Imlib_Image *source_image, double thresh,
|
||||
height = imlib_image_get_height();
|
||||
width = imlib_image_get_width();
|
||||
|
||||
/* special value -1 for width or height means image width/height */
|
||||
if(w == -1) w = width;
|
||||
if(h == -1) h = width;
|
||||
|
||||
/* assure valid coordinates */
|
||||
if(x+w > width) x = width-w;
|
||||
if(y+h > height) y = height-h;
|
||||
if(x<0) x=0;
|
||||
if(y<0) y=0;
|
||||
|
||||
/* find the threshold value to differentiate between dark and light */
|
||||
do {
|
||||
thresh_lum = MAXRGB * new_thresh;
|
||||
old_thresh = new_thresh;
|
||||
size_black = sum_black = size_white = sum_white = 0;
|
||||
for(xi=0; (xi<w) && (xi<width); xi++) {
|
||||
for(yi=0; (yi<h) && (yi<height); yi++) {
|
||||
for(xi=0; xi<width; xi++) {
|
||||
for(yi=0; yi<height; yi++) {
|
||||
imlib_image_query_pixel(xi, yi, &color);
|
||||
lum = get_lum(&color, lt);
|
||||
if(lum <= thresh_lum) {
|
||||
@@ -604,92 +608,39 @@ double iterative_threshold(Imlib_Image *source_image, double thresh,
|
||||
return new_thresh * 100;
|
||||
}
|
||||
|
||||
/* get minimum lum value */
|
||||
double get_minval(Imlib_Image *source_image, int x, int y, int w, int h,
|
||||
luminance_t lt)
|
||||
/* get minimum and maximum lum values */
|
||||
void get_minmaxval(Imlib_Image *source_image, luminance_t lt,
|
||||
double *min, double *max)
|
||||
{
|
||||
Imlib_Image current_image; /* save image pointer */
|
||||
int height, width; /* image dimensions */
|
||||
int w, h; /* image dimensions */
|
||||
int xi,yi; /* iteration variables */
|
||||
Imlib_Color color; /* Imlib2 RGBA color structure */
|
||||
int minval = MAXRGB;
|
||||
int lum = 0;
|
||||
|
||||
*min = MAXRGB;
|
||||
*max = 0;
|
||||
|
||||
/* save pointer to current image */
|
||||
current_image = imlib_context_get_image();
|
||||
|
||||
/* get image dimensions */
|
||||
imlib_context_set_image(*source_image);
|
||||
height = imlib_image_get_height();
|
||||
width = imlib_image_get_width();
|
||||
|
||||
/* special value -1 for width or height means image width/height */
|
||||
if(w == -1) w = width;
|
||||
if(h == -1) h = width;
|
||||
|
||||
/* assure valid coordinates */
|
||||
if(x+w > width) x = width-w;
|
||||
if(y+h > height) y = height-h;
|
||||
if(x<0) x=0;
|
||||
if(y<0) y=0;
|
||||
h = imlib_image_get_height();
|
||||
w = imlib_image_get_width();
|
||||
|
||||
/* find the minimum value in the image */
|
||||
for(xi=0; (xi<w) && (xi<width); xi++) {
|
||||
for(yi=0; (yi<h) && (yi<height); yi++) {
|
||||
for(xi=0; xi<w; xi++) {
|
||||
for(yi=0; yi<h; yi++) {
|
||||
imlib_image_query_pixel(xi, yi, &color);
|
||||
lum = clip(get_lum(&color, lt),0,255);
|
||||
if(lum < minval) minval = lum;
|
||||
if(lum < *min) *min = lum;
|
||||
if(lum > *max) *max = lum;
|
||||
}
|
||||
}
|
||||
|
||||
/* restore image from before function call */
|
||||
imlib_context_set_image(current_image);
|
||||
|
||||
return minval;
|
||||
}
|
||||
|
||||
/* get maximum luminance value */
|
||||
double get_maxval(Imlib_Image *source_image, int x, int y, int w, int h,
|
||||
luminance_t lt)
|
||||
{
|
||||
Imlib_Image current_image; /* save image pointer */
|
||||
int height, width; /* image dimensions */
|
||||
int xi,yi; /* iteration variables */
|
||||
Imlib_Color color; /* Imlib2 RGBA color structure */
|
||||
int lum = 0;
|
||||
int maxval = 0;
|
||||
|
||||
/* save pointer to current image */
|
||||
current_image = imlib_context_get_image();
|
||||
|
||||
/* get image dimensions */
|
||||
imlib_context_set_image(*source_image);
|
||||
height = imlib_image_get_height();
|
||||
width = imlib_image_get_width();
|
||||
|
||||
/* special value -1 for width or height means image width/height */
|
||||
if(w == -1) w = width;
|
||||
if(h == -1) h = width;
|
||||
|
||||
/* assure valid coordinates */
|
||||
if(x+w > width) x = width-w;
|
||||
if(y+h > height) y = height-h;
|
||||
if(x<0) x=0;
|
||||
if(y<0) y=0;
|
||||
|
||||
/* find the minimum value in the image */
|
||||
for(xi=0; (xi<w) && (xi<width); xi++) {
|
||||
for(yi=0; (yi<h) && (yi<height); yi++) {
|
||||
imlib_image_query_pixel(xi, yi, &color);
|
||||
lum = clip(get_lum(&color, lt),0,255);
|
||||
if(lum > maxval) maxval = lum;
|
||||
}
|
||||
}
|
||||
|
||||
/* restore image from before function call */
|
||||
imlib_context_set_image(current_image);
|
||||
|
||||
return maxval;
|
||||
}
|
||||
|
||||
/* draw a white (background) border around image, overwriting image contents
|
||||
@@ -757,15 +708,11 @@ Imlib_Image shear(Imlib_Image *source_image, int offset)
|
||||
/* copy pixels */
|
||||
for(x=width-1; x>=shift; x--) {
|
||||
imlib_image_query_pixel(x-shift, y, &color_return);
|
||||
imlib_context_set_image(new_image);
|
||||
imlib_context_set_color(color_return.red, color_return.green,
|
||||
color_return.blue, color_return.alpha);
|
||||
imlib_image_draw_pixel(x,y,0);
|
||||
imlib_context_set_image(*source_image);
|
||||
draw_color_pixel(&new_image, x, y, color_return);
|
||||
}
|
||||
/* fill with background */
|
||||
for(x=0; x<shift; x++) {
|
||||
draw_bg_pixel(new_image, x, y);
|
||||
draw_bg_pixel(&new_image, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -806,14 +753,10 @@ Imlib_Image rotate(Imlib_Image *source_image, double theta)
|
||||
sy = (y-height/2) * cos(theta) - (x-width/2) * sin(theta) + height/2;
|
||||
if((sx >= 0) && (sx <= width) && (sy >= 0) && (sy <= height)) {
|
||||
imlib_image_query_pixel(sx, sy, &c);
|
||||
imlib_context_set_image(new_image);
|
||||
imlib_context_set_color(c.red, c.green, c.blue, c.alpha);
|
||||
draw_color_pixel(&new_image, x, y, c);
|
||||
} else {
|
||||
imlib_context_set_image(new_image);
|
||||
ssocr_set_color(BG);
|
||||
draw_bg_pixel(&new_image, x, y);
|
||||
}
|
||||
imlib_image_draw_pixel(x,y,0);
|
||||
imlib_context_set_image(*source_image);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -847,20 +790,14 @@ Imlib_Image mirror(Imlib_Image *source_image, direction_t direction)
|
||||
for(x = width-1; x>=0; x--) {
|
||||
for(y = 0; y < height; y++) {
|
||||
imlib_image_query_pixel(width - 1 - x, y, &c);
|
||||
imlib_context_set_image(new_image);
|
||||
imlib_context_set_color(c.red, c.green, c.blue, c.alpha);
|
||||
imlib_image_draw_pixel(x,y,0);
|
||||
imlib_context_set_image(*source_image);
|
||||
draw_color_pixel(&new_image, x, y, c);
|
||||
}
|
||||
}
|
||||
} else if(direction == VERTICAL) {
|
||||
for(x = 0; x < width; x++) {
|
||||
for(y = height-1; y >= 0; y--) {
|
||||
imlib_image_query_pixel(x, height - 1 - y, &c);
|
||||
imlib_context_set_image(new_image);
|
||||
imlib_context_set_color(c.red, c.green, c.blue, c.alpha);
|
||||
imlib_image_draw_pixel(x,y,0);
|
||||
imlib_context_set_image(*source_image);
|
||||
draw_color_pixel(&new_image, x, y, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -935,9 +872,9 @@ Imlib_Image invert(Imlib_Image *source_image, double thresh, luminance_t lt)
|
||||
imlib_image_query_pixel(x, y, &color);
|
||||
lum = get_lum(&color, lt);
|
||||
if(is_pixel_set(lum, thresh)) {
|
||||
draw_bg_pixel(new_image, x, y);
|
||||
draw_bg_pixel(&new_image, x, y);
|
||||
} else {
|
||||
draw_fg_pixel(new_image, x, y);
|
||||
draw_fg_pixel(&new_image, x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1126,7 +1063,7 @@ luminance_t parse_lum(char *keyword)
|
||||
} else if(strcasecmp(keyword, "blue") == 0) {
|
||||
return BLUE;
|
||||
} else {
|
||||
return DEFAULT_LUM_FORMULA;
|
||||
return LUM_PARSE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* Copyright (C) 2004-2022 Erik Auerswald <auerswal@unix-ag.uni-kl.de> */
|
||||
/* Copyright (C) 2004-2025 Erik Auerswald <auerswal@unix-ag.uni-kl.de> */
|
||||
|
||||
#ifndef SSOCR2_IMGPROC_H
|
||||
#define SSOCR2_IMGPROC_H
|
||||
@@ -32,7 +32,7 @@ void set_bg_color(int color);
|
||||
void ssocr_set_color(fg_bg_t color);
|
||||
|
||||
/* draw a fore- or background pixel */
|
||||
void draw_pixel(Imlib_Image *image, int x, int y, fg_bg_t color);
|
||||
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);
|
||||
@@ -40,6 +40,9 @@ 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);
|
||||
|
||||
@@ -126,8 +129,8 @@ Imlib_Image grayscale(Imlib_Image *source_image, luminance_t lt);
|
||||
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, int x,
|
||||
int y, int w, int h, unsigned int flags);
|
||||
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 */
|
||||
@@ -136,15 +139,11 @@ double get_threshold(Imlib_Image *source_image, double fraction, luminance_t lt,
|
||||
|
||||
/* determine threshold by an iterative method */
|
||||
double iterative_threshold(Imlib_Image *source_image, double thresh,
|
||||
luminance_t lt, int x, int y, int w, int h);
|
||||
luminance_t lt);
|
||||
|
||||
/* get minimum gray value */
|
||||
double get_minval(Imlib_Image *source_image, int x, int y, int w, int h,
|
||||
luminance_t lt);
|
||||
|
||||
/* get maximum gray value */
|
||||
double get_maxval(Imlib_Image *source_image, int x, int y, int w, int h,
|
||||
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);
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ Upstream Author(s):
|
||||
|
||||
Copyright:
|
||||
|
||||
Copyright (C) 2004-2022 Erik Auerswald
|
||||
Copyright (C) 2004-2025 Erik Auerswald
|
||||
|
||||
License:
|
||||
|
||||
|
||||
+114
-11
@@ -1,4 +1,4 @@
|
||||
.TH ssocr 1 "@DATE@" @VERSION@ "OCR for seven segment displays"
|
||||
.TH ssocr 1 "@DATE@" "@VERSION@" "OCR for seven segment displays"
|
||||
.SH NAME
|
||||
ssocr \- optical recognition of seven segment displays
|
||||
.SH SYNOPSIS
|
||||
@@ -13,6 +13,29 @@ Use
|
||||
as file name to read the image from standard input.
|
||||
.B ssocr
|
||||
provides several image manipulation algorithms to enhance noisy images.
|
||||
.PP
|
||||
.B Options
|
||||
can be used to change
|
||||
.B ssocr
|
||||
behavior.
|
||||
.PP
|
||||
.B Commands
|
||||
can be used to manipulate the input
|
||||
.I IMAGE
|
||||
before starting the recognition algorithm.
|
||||
.PP
|
||||
Two hyphens
|
||||
.RB ( \-\- )
|
||||
can be used as a special argument to end option-scanning, e.g.,
|
||||
in order to use a negative number as argument to a command.
|
||||
.PP
|
||||
When using a single character (i.e., short) option,
|
||||
arguments can either directly follow the option character,
|
||||
or can be separated from the option character by whitespace.
|
||||
When using a multi character (i.e., long) option,
|
||||
arguments must be separated from the option by either an equals sign
|
||||
.RB ( = ),
|
||||
or whitespace.
|
||||
.SH OPTIONS
|
||||
.SS \-h, \-\-help
|
||||
Write a help message to standard output.
|
||||
@@ -30,53 +53,113 @@ is used. The default threshold is
|
||||
.IR 50 .
|
||||
.SS \-a, \-\-absolute\-threshold
|
||||
Do not adjust the threshold to the luminance values occurring in the image.
|
||||
Using this option also inhibits iterative thresholding using option
|
||||
.BR \-\-iter\-threshold .
|
||||
Consider this option when using the
|
||||
.B dynamic_threshold
|
||||
command.
|
||||
or
|
||||
.B gray_stretch
|
||||
commands.
|
||||
.SS \-T, \-\-iter\-threshold
|
||||
Use an iterative method (one-dimensional k-means clustering) to determine the
|
||||
threshold. The starting value can be specified with the
|
||||
.B \-\-threshold
|
||||
option.
|
||||
Option
|
||||
.B \-\-absolute\-threshold
|
||||
inhibits iterative threshold determination.
|
||||
.SS \-n, \-\-number\-pixels NUMBER
|
||||
Set the number of foreground pixels that have to be found in a scanline to
|
||||
recognize a segment.
|
||||
This does not apply to ratio based recognition.
|
||||
Can be used to ignore some noise in the picture.
|
||||
See the web page of
|
||||
.BR ssocr (1)
|
||||
for a description of the algorithm.
|
||||
.SS \-N, \-\-min\-segment SIZE
|
||||
Set the minimum number of pixels required for width and height of an individual
|
||||
segment of a seven segment display.
|
||||
A set segment in the display must have both a width and height of at least
|
||||
.B SIZE
|
||||
pixels.
|
||||
This minimum is used for both scanline based and ratio based recognition.
|
||||
It is not applied to decimal separator detection,
|
||||
because those are not comprised of regular segments.
|
||||
This option can be used to ignore some noise in the picture.
|
||||
See the web page of
|
||||
.BR ssocr (1)
|
||||
for a description of the algorithm.
|
||||
.SS \-i, \-\-ignore\-pixels NUMBER
|
||||
Set the number of foreground pixels that are ignored when deciding if a column
|
||||
consists only of background or foreground pixels.
|
||||
or row consists only of background or foreground pixels.
|
||||
Can be used to ignore some noise in the picture.
|
||||
See the web page of
|
||||
.BR ssocr (1)
|
||||
for a description of the algorithm.
|
||||
.SS \-d, \-\-number\-digits NUMBER
|
||||
.SS \-M, \-\-min\-char\-dims WIDTHxHEIGHT
|
||||
Specify the minimum dimensions of characters respectively digits.
|
||||
When the segmentation step finds potential digits,
|
||||
those with a width less than
|
||||
.B WIDTH
|
||||
or a height less than
|
||||
.B HEIGHT
|
||||
are ignored.
|
||||
Can be used to ignore some noise in the picture.
|
||||
See the web page of
|
||||
.BR ssocr (1)
|
||||
for a description of the algorithm.
|
||||
.SS \-d, \-\-number\-digits RANGE
|
||||
Specifies the number of digits shown in the image. Default value is
|
||||
.IR 6 .
|
||||
Use
|
||||
.I \-1
|
||||
to automatically detect the number of digits.
|
||||
Use a single positive number to specify an exact number of digits.
|
||||
Use two positive numbers separated with a hyphen
|
||||
.RI ( - )
|
||||
to specify an inclusive range of acceptable values for the number of digits.
|
||||
.SS \-r, \-\-one\-ratio RATIO
|
||||
Set the height/width ratio threshold to recognize a digit as a one.
|
||||
RATIO takes integers only.
|
||||
A digit with a height/width ratio greater than
|
||||
.B RATIO
|
||||
is recognized as a one.
|
||||
.B RATIO
|
||||
takes integers only.
|
||||
See the web page of
|
||||
.BR ssocr (1)
|
||||
for a description of the algorithm.
|
||||
.SS \-m, \-\-minus\-ratio RATIO
|
||||
Set the width/height ratio to recognize a minus sign.
|
||||
A digit with a width/height ratio greater than or equal to
|
||||
.B RATIO
|
||||
is recognized as a minus sign.
|
||||
.B RATIO
|
||||
takes integers only.
|
||||
This uses the same idea as recognizing the digit one.
|
||||
.SS \-H, \-\-dec\-h\-ratio RATIO
|
||||
Set the max_digit_height/height ratio used for recognition of a decimal
|
||||
separator.
|
||||
.B RATIO
|
||||
takes integers only.
|
||||
This value is used in combination with the max_digit_width/width ratio.
|
||||
If the height of a digit is less than
|
||||
.RB 1/ RATIO
|
||||
of the maximum digit height in the image and the max_digit_width/width
|
||||
threshold is also reached,
|
||||
it is recognized as a decimal separator.
|
||||
.SS \-W, \-\-dec\-w\-ratio RATIO
|
||||
Set the max_digit_width/width ratio used for recognition of a decimal
|
||||
separator.
|
||||
Set the max_digit_width/width ratio used for recognition of a decimal separator.
|
||||
.B RATIO
|
||||
takes integers only.
|
||||
This value is used in combination with the max_digit_height/height ratio.
|
||||
If the width of a digit is less than
|
||||
.RB 1/ RATIO
|
||||
of the maximum digit width in the image
|
||||
and the max_digit_height/height threshold is also reached,
|
||||
it is recognized as a decimal separator.
|
||||
.SS \-o, \-\-output\-image FILE
|
||||
Write the processed image to FILE.
|
||||
Write the processed image to
|
||||
.BR FILE .
|
||||
Use
|
||||
.B \-
|
||||
to write to standard output.
|
||||
@@ -155,7 +238,8 @@ The default of
|
||||
should work well in most cases.
|
||||
.SS \-s, \-\-print\-spaces
|
||||
Print space characters between digits (characters) that are farther apart
|
||||
than a factor times the minimum distance between digits (characters).
|
||||
than a factor times the minimum (default) or average distance between digits
|
||||
(characters).
|
||||
.SS \-A, \-\-space\-factor FACTOR
|
||||
Use the given
|
||||
.B FACTOR
|
||||
@@ -213,7 +297,20 @@ of the included characters.
|
||||
The default is
|
||||
.I full
|
||||
(recognizing all characters known to ssocr in the image).
|
||||
.SS \-F, \-\-adapt\-after\-crop
|
||||
When using the
|
||||
.B crop
|
||||
command,
|
||||
adjust (adapt) the threshold to image luminance values only after cropping,
|
||||
not also directly before.
|
||||
Using other commands before
|
||||
.B crop
|
||||
can still lead to adapting the threshold to the original image.
|
||||
.SH COMMANDS
|
||||
Most commands do not change the image dimensions.
|
||||
The
|
||||
.B crop
|
||||
command is a notable exception to this rule.
|
||||
.SS dilation [N]
|
||||
Filter image using dilation algorithm.
|
||||
Any pixel with at least one neighbour pixel set in the source image will be
|
||||
@@ -293,8 +390,13 @@ the values
|
||||
and
|
||||
.B T2
|
||||
are interpreted as percentages.
|
||||
Consider using the
|
||||
.B \-\-absolute\-threshold
|
||||
option together with a manually adjusted
|
||||
.B \-\-threshold
|
||||
for predictable results.
|
||||
.SS dynamic_threshold W H
|
||||
Convert the image to monochrome using dynamic thresholding a.k.a local
|
||||
Convert the image to monochrome using dynamic thresholding a.k.a. local
|
||||
adaptive thresholding.
|
||||
A window of width
|
||||
.B W
|
||||
@@ -355,7 +457,7 @@ or
|
||||
.B dynamic_threshold
|
||||
instead.
|
||||
.SS white_border [WIDTH]
|
||||
The border of the image is set to the foreground color.
|
||||
The border of the image is set to the background color.
|
||||
This border is one pixel wide unless a
|
||||
.B WIDTH
|
||||
>
|
||||
@@ -395,6 +497,7 @@ Use only the subpicture with upper left corner (
|
||||
.B W
|
||||
and height
|
||||
.BR H .
|
||||
This command changes the image dimensions.
|
||||
.SS set_pixels_filter MASK
|
||||
Set every pixel in the filtered image that has at least
|
||||
.B MASK
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* Copyright (C) 2004-2022 Erik Auerswald <auerswal@unix-ag.uni-kl.de> */
|
||||
/* Copyright (C) 2004-2025 Erik Auerswald <auerswal@unix-ag.uni-kl.de> */
|
||||
|
||||
#ifndef SSOCR2_H
|
||||
#define SSOCR2_H
|
||||
@@ -27,4 +27,12 @@ typedef struct {
|
||||
int R, G, B, A;
|
||||
} color_struct;
|
||||
|
||||
typedef struct {
|
||||
int w, h;
|
||||
} dimensions_struct;
|
||||
|
||||
typedef struct {
|
||||
int min, max;
|
||||
} interval_struct;
|
||||
|
||||
#endif /* SSOCR2_H */
|
||||
|
||||
Reference in New Issue
Block a user