The KADMOS Developer kit has a strong modular design. Three main modules form the KADMOS architecture, REC, REL, and REP. The names of the REC, REL, and REP modules are chosen according to their functionality:
Rec
=RE
cognizeC
haracter
REL
=RE
cognizeL
ine
REP
=RE
cognizeP
age
REC
ReImage
. Character
codes are delivered as recognition output with alternatives if necessary in the structure RecData
.
REL
ReImage
, is required. REL segments the text line into single characters and, for each character,
calls the REC module to recognize it. A structure of the text line with possible alternatives of segmentation together
with individual character recognition results is returned in a structure RelData
.REP
ReImage
. An array of results from the REL module related to the recognition
of each text line is returned in a structure RepData
For all supported C/C++ compilers, the REC, REL, and REP modules are made as a run-time library or DLL when it is
available. They can be linked into any application. Data exchange with the calling program is implemented via related
data structures RecData
, RelData
, and RepData
. In these structures, the images
for recognition are required as input, with the corresponding results returned after recognition. To call any module,
i.e. REC
, REL
, or REP
, a classifier for recognition must be specified and initialized.
This must be done so that each data structure RecData
, RelData
, or RepData
is firmly
linked to a specific classifier. If an application wants to recognize several text areas (for example, one numeric
and one alphanumeric) with different classifiers, data structures for each zone (text area) must be declared and used.
Parameters used for finer control of the recognition process can be passed via the data structure ReParm
.
Recognition results are always found in the last part of the RecData
, RelData
, or
RepData
data structures. For RecData
the last part of the structure contains the recognition
results for an isolated character. RelData
and RepData
deliver pointers to data structures
RelGrid
, RelGraph
, RelResult
, and RepResult
,
where the recognition results are located. A detailed description of the parameters can be found in section
"Parameters and Functions". For the verification of the results of line recognition the module RESPELL
is provided.
It compares these results with the content of a dictionary. RESPELL
returns its results in the same
convention as REL. But here the provided alternatives are the words from the dictionary, if found.
#include <stdio.h> #include "KADMOS.h" RecData rec={0}; /* ****************** */ void main (void) { /* ****************** */ rec_init(&rec, "numplus.rec"); rec.image.imgtype=IMGTYPE_PIXELARRAY // falls Bilder als Punktmatrix erwartet werden for (;;) { // hier eigenen Code zur Besetzung von rec.image einfügen. rec.image.data=...; rec.image.width=...; rec.image.height=...; rec_do(&rec); printf("\nErkannt: %s", rec.rec_char[0]); } rec_end(&rec); }
#include <windows.h> #include "KADMOS.h" BOOL RcInit=FALSE; RecData rec={0}; // Prozedurteil für die Initialisierung des Klassifikators ... if (!RcInit){ if (rec_init(&rec, "numpluseu.rec")==RE_SUCCESS) RcInit=TRUE; else { MessageBox(NULL, "rec_init() fehlerhaft", "Beoispiel", MB_OK); return FALSE; } } // Prozedurteil für Klassifikation. rec.parm.labels=(char *) ...; rec.image.data=...; rec.image.imgtype=IMGTYPE_PIXELARRAY; // falls Bilder als Punktmatrix erwartet werden. rec.image.width=...; rec.image.height=...; if rec_do(&rec)!=RE_SUCCESS) { MessageBox(NULL, "rec_do() fehlerhaft", "Beispiel", MB_OK); return FALSE; } // Bei 'rec.rec_char' und 'rec.rec_value' können nun die // Resultate abgeholt werden. rec.rec_char[0] enthält das // erste erkannte Zeichen. rec.rec_value[0] enthält einen Wert // für die Sicherheit der Erkennung. Werte unter 100 sind gut, // grössere Werte sind schlecht ... Prozedurteil für Abschluss if (RcInit) { if (rec_end(&rec)!=RE_SUCCESS) { MessageBox(NULL, "rec_end() fehlerhaft", "Beispiel", MB_OK); return FALSE; } RcInit=FALSE; }
To help test your program and to collect character images from live documents, KADMOS provides some simple APIs in a
module RE_COLLECT
. Similar to other recognition functions, image collection initialization has to be
started using re_collect_init()
with the appropriate image file name to be created. End the process by
calling re_collect_end()
. Control of the actual process is handled using a recognition confidence
rec_value()
threshold setting. If characters from a text line are to be collected, the API
rel_collect_kernel()
is used. The API rec_collect_kernel()
is used to collect character
images following a call to rec_do()
. The calls of re_collect()
are described in the
sources of recwin
, recdemo ...
.
For good segmentation it is not sufficient to describe the segmented characters or lines by their surrounding
rectangles. If there is a need for direct access to the segmented images, then they must be stored separately.
This intermediate storage is activated by setting TYPO_KEEPIMG
in the related parameter structure
RelData
or RepData
under typograph
. In the line module REL after
each call to rel_do()
, the segmented images can be accessed through result_image
,
result_height
, and result_width
. By subsequent calls to rel_do()
or
rel_end()
these images are deleted and the allocated memory is freed. Alternatively, users can call
rel_freeimages()
to delete the images and free the memory directly. The images provided under
result_image
are binary images with one byte per pixel and stored line by line.
For a more detailed explanation of this procedure, see the sample program reldemo as provided with the developer kit and copy the related lines into your program. Inspection of the collected images can be performed with the program sichten.exe. If you have your own routines for performing line and character segmentation, inspection of the resulting isolated characters can provide valuable hints to possible line or character cuttings. If the images are ok, but classifier results are not, please do not hesitate at sending or e-mailing the images to Kadmos GmbH for further analysis.
// Modul REP, Initialisierung: if (re_collect_init("images.ras", 0, 0)!=RE_SUCCESS)...; rep->rel_hook=rel_collect_kernel; rep->parm.typograph|=TYPO_KEEPIMG; // Modul REP, Sammlung wird von rep_do() durch Hook-Funktion erledigt: if (rep_do(rep)!=RE_SUCCESS) ...; // Modul REP, Abschluss: if (re_collect_end()!=RE_SUCCESS)...;
For developers who want to use their own hook function.
// Modul REC oder REL, Initialisierung: if (re_collect_init("Bilder.ras", 0, 0)!=RE_SUCCESS)...; // Modul REC, Sammlung nach dem Aufruf von rec_do(): if (rec_do(&rec)!=RE_SUCCESS) ...; if (rec_collect_kernel(&rec)!=RE_SUCCESS) ...; // Modul REL, Sammlung nach dem Aufruf von rel_do(): rel->parm.typograph|=TYPO_KEEPIMG; if (rel_do(&rel)!=RE_SUCCESS) ...; if (rel_collect_kernel(&rel)!=RE_SUCCESS)...; if (rel_freeimages (&rel)!=RE_SUCCESS) ...; // Modul REC oder REL, Abschluss: if (re_collect_end()!=RE_SUCCESS) ...;
With every call to re_collect_init()
, re_collect_winit()
, an image file is created.
If this file already exists, it will first be cleared, i.e. overwritten. Unless terminated by re_collect_end()
,
this file will receive all collected images. rec_collect_kernel()
and rel_collect_kernel()
are able to handle as many data structures RecData
or RelData
as necessary,
allowing several different classifiers to be used simultaneously for data collection.
// Initialisierung: if (re_collect_init("Bilder.ras", value_min, value_max)!=RE_SUCCESSS) ...;
Samples with a confidence value rec_value[0]
between lower_bound
and upper_bound
will be collected. A single threshold different of zero can be used to collect all good (lower_bound==0
)
or bad (upper_bound==0
) image samples.
The KADMOS modules are looking at every initialization re?_init()
for the file kadmos.ini
in the following directories:
[saveimg]
mode= REC, REL, REP
mode= OFF
file=
[collect]
mode= REC, REL, REP
mode= OFF
file=
value_min=, value_max=
If specified and not zero, only images with rec_value[0] within the specified bounds are collected.
rec_init(), rel_init(), rep_init()
🗏rec_info(), rel_info(), rep_info()
🗏rec_filetitle(), rel_filetitle(), rep_filetitle()
🗏rec_do(), rel_do(), rep_do()
🗏rec_group_labels(), rel_group_labels(), rep_group_labels(), repr_group_labels()
🗏rec_end(), rel_end(), rep_end()
🗏rec_get_features()
🗏rel_freeimages()
rel_lineshadow()
🗏respell_init()
🗏respell_do()
🗏rel_do()
or rep_do()
by comparison with the content of a connected dictionary.respell_end()
🗏respell_codepage()
🗏respell_filetitle()
🗏respell_lookup()
🗏respell_wordchars()
🗏Most functions return the value RE_SUCCESS after correct work, in case of error a corresponding error type. The integration of the modules into a calling program always takes place according to the following scheme, which is shown here by way of example for the module REC:
#include "KADMOS.h" RecData rec={0}; ... rec_init&rec, "numpluseu.rec"); for (;;) { // hier eigenes Programm zur Besetzung von 'image' einfügen rec.image.data=...; rec_do(&rec); printf("\nrecognized: %s", rec.rec_char[0]); } rec_end(&rec);
The classifier used (in the example numpluseu.rec) is addressed via a data structure RecData. This structure is - like the structures RelData and RepData - declared in KADMOS.h. In practice, there are cases where there are multiple read fields on a form that need to be recognized with different classifiers. For each classifier you need your own data structure. with this then the specific initialization and detection is performed. In the following example of a line recognition, a typewriter field and an OCRA field can be recognized.
#include "KADMOS.h" RelData rel_ttfde={0}; RelData rel_ocra={0}; rel_ttfde.init.rel_graph_maxlen=...; rel_ttfde.init.rel_result_maxlen=...; rel_ttfde.rel_graph=...; rel_ttfde.rel_result=...; ... rel_init(&rel_ttfde, "ttfde.rec"); rel_ocra.init.rel_graph_maxlen=...; rel_ocra.init.rel_result_maxlen=...; rel_ocra.rel_graph=...; rel_ocra.rel_result=...; rel_init(&rel_ocra, "ocra.rec"); ... for (;;) { rel_ttfde.image.data=...; rel_ttfde.image.imagetype=...; rel_do(&rel_ttfde); ... rel_ocra.image.data=...; rel_ocra.imiage.imagetype=...; rel_do(&rel_ocra); ... } rel_end(&rel_ocra); rel_end(&rel_ttfde);