Changes to classify for 3.00

git-svn-id: https://tesseract-ocr.googlecode.com/svn/trunk@291 d0cd1f9f-072b-0410-8dd7-cf729c803f20
This commit is contained in:
theraysmith 2009-07-11 02:17:36 +00:00
parent 9e67cb0773
commit 694d3f2c20
54 changed files with 4436 additions and 4734 deletions

View File

@ -2,23 +2,29 @@ SUBDIRS =
AM_CPPFLAGS = \
-I$(top_srcdir)/cutil -I$(top_srcdir)/ccutil \
-I$(top_srcdir)/ccstruct -I$(top_srcdir)/dict \
-I$(top_srcdir)/viewer
-I$(top_srcdir)/image -I$(top_srcdir)/viewer
EXTRA_DIST = classify.vcproj
include_HEADERS = \
adaptive.h adaptmatch.h baseline.h blobclass.h chartoname.h \
cluster.h clusttool.h cutoffs.h extern.h extract.h featdefs.h \
flexfx.h float2int.h fpoint.h fxdefs.h fxid.h hideedge.h \
intfx.h intmatcher.h intproto.h kdtree.h mfdefs.h mf.h \
mfoutline.h mfx.h normfeat.h normmatch.h ocrfeatures.h \
outfeat.h picofeat.h protos.h sigmenu.h speckle.h xform2d.h
classify.h cluster.h clusttool.h cutoffs.h \
extern.h extract.h \
featdefs.h flexfx.h float2int.h fpoint.h fxdefs.h fxid.h \
hideedge.h intfx.h intmatcher.h intproto.h kdtree.h \
mf.h mfdefs.h mfoutline.h mfx.h \
normfeat.h normmatch.h \
ocrfeatures.h outfeat.h picofeat.h protos.h \
speckle.h xform2d.h
lib_LIBRARIES = libtesseract_classify.a
libtesseract_classify_a_SOURCES = \
adaptive.cpp adaptmatch.cpp baseline.cpp blobclass.cpp \
chartoname.cpp cluster.cpp clusttool.cpp cutoffs.cpp \
extract.cpp featdefs.cpp flexfx.cpp float2int.cpp \
fpoint.cpp fxdefs.cpp hideedge.cpp intfx.cpp intmatcher.cpp \
intproto.cpp kdtree.cpp mf.cpp mfdefs.cpp mfoutline.cpp \
mfx.cpp normfeat.cpp normmatch.cpp ocrfeatures.cpp \
outfeat.cpp picofeat.cpp protos.cpp sigmenu.cpp speckle.cpp \
xform2d.cpp
chartoname.cpp classify.cpp cluster.cpp clusttool.cpp cutoffs.cpp \
extract.cpp \
featdefs.cpp flexfx.cpp float2int.cpp fpoint.cpp fxdefs.cpp \
hideedge.cpp intfx.cpp intmatcher.cpp intproto.cpp kdtree.cpp \
mf.cpp mfdefs.cpp mfoutline.cpp mfx.cpp \
normfeat.cpp normmatch.cpp \
ocrfeatures.cpp outfeat.cpp picofeat.cpp protos.cpp \
speckle.cpp xform2d.cpp

View File

@ -59,15 +59,15 @@ libtesseract_classify_a_AR = $(AR) $(ARFLAGS)
libtesseract_classify_a_LIBADD =
am_libtesseract_classify_a_OBJECTS = adaptive.$(OBJEXT) \
adaptmatch.$(OBJEXT) baseline.$(OBJEXT) blobclass.$(OBJEXT) \
chartoname.$(OBJEXT) cluster.$(OBJEXT) clusttool.$(OBJEXT) \
cutoffs.$(OBJEXT) extract.$(OBJEXT) featdefs.$(OBJEXT) \
flexfx.$(OBJEXT) float2int.$(OBJEXT) fpoint.$(OBJEXT) \
fxdefs.$(OBJEXT) hideedge.$(OBJEXT) intfx.$(OBJEXT) \
intmatcher.$(OBJEXT) intproto.$(OBJEXT) kdtree.$(OBJEXT) \
mf.$(OBJEXT) mfdefs.$(OBJEXT) mfoutline.$(OBJEXT) \
mfx.$(OBJEXT) normfeat.$(OBJEXT) normmatch.$(OBJEXT) \
ocrfeatures.$(OBJEXT) outfeat.$(OBJEXT) picofeat.$(OBJEXT) \
protos.$(OBJEXT) sigmenu.$(OBJEXT) speckle.$(OBJEXT) \
chartoname.$(OBJEXT) classify.$(OBJEXT) cluster.$(OBJEXT) \
clusttool.$(OBJEXT) cutoffs.$(OBJEXT) extract.$(OBJEXT) \
featdefs.$(OBJEXT) flexfx.$(OBJEXT) float2int.$(OBJEXT) \
fpoint.$(OBJEXT) fxdefs.$(OBJEXT) hideedge.$(OBJEXT) \
intfx.$(OBJEXT) intmatcher.$(OBJEXT) intproto.$(OBJEXT) \
kdtree.$(OBJEXT) mf.$(OBJEXT) mfdefs.$(OBJEXT) \
mfoutline.$(OBJEXT) mfx.$(OBJEXT) normfeat.$(OBJEXT) \
normmatch.$(OBJEXT) ocrfeatures.$(OBJEXT) outfeat.$(OBJEXT) \
picofeat.$(OBJEXT) protos.$(OBJEXT) speckle.$(OBJEXT) \
xform2d.$(OBJEXT)
libtesseract_classify_a_OBJECTS = \
$(am_libtesseract_classify_a_OBJECTS)
@ -203,26 +203,31 @@ SUBDIRS =
AM_CPPFLAGS = \
-I$(top_srcdir)/cutil -I$(top_srcdir)/ccutil \
-I$(top_srcdir)/ccstruct -I$(top_srcdir)/dict \
-I$(top_srcdir)/viewer
-I$(top_srcdir)/image -I$(top_srcdir)/viewer
EXTRA_DIST = classify.vcproj
include_HEADERS = \
adaptive.h adaptmatch.h baseline.h blobclass.h chartoname.h \
cluster.h clusttool.h cutoffs.h extern.h extract.h featdefs.h \
flexfx.h float2int.h fpoint.h fxdefs.h fxid.h hideedge.h \
intfx.h intmatcher.h intproto.h kdtree.h mfdefs.h mf.h \
mfoutline.h mfx.h normfeat.h normmatch.h ocrfeatures.h \
outfeat.h picofeat.h protos.h sigmenu.h speckle.h xform2d.h
classify.h cluster.h clusttool.h cutoffs.h \
extern.h extract.h \
featdefs.h flexfx.h float2int.h fpoint.h fxdefs.h fxid.h \
hideedge.h intfx.h intmatcher.h intproto.h kdtree.h \
mf.h mfdefs.h mfoutline.h mfx.h \
normfeat.h normmatch.h \
ocrfeatures.h outfeat.h picofeat.h protos.h \
speckle.h xform2d.h
lib_LIBRARIES = libtesseract_classify.a
libtesseract_classify_a_SOURCES = \
adaptive.cpp adaptmatch.cpp baseline.cpp blobclass.cpp \
chartoname.cpp cluster.cpp clusttool.cpp cutoffs.cpp \
extract.cpp featdefs.cpp flexfx.cpp float2int.cpp \
fpoint.cpp fxdefs.cpp hideedge.cpp intfx.cpp intmatcher.cpp \
intproto.cpp kdtree.cpp mf.cpp mfdefs.cpp mfoutline.cpp \
mfx.cpp normfeat.cpp normmatch.cpp ocrfeatures.cpp \
outfeat.cpp picofeat.cpp protos.cpp sigmenu.cpp speckle.cpp \
xform2d.cpp
chartoname.cpp classify.cpp cluster.cpp clusttool.cpp cutoffs.cpp \
extract.cpp \
featdefs.cpp flexfx.cpp float2int.cpp fpoint.cpp fxdefs.cpp \
hideedge.cpp intfx.cpp intmatcher.cpp intproto.cpp kdtree.cpp \
mf.cpp mfdefs.cpp mfoutline.cpp mfx.cpp \
normfeat.cpp normmatch.cpp \
ocrfeatures.cpp outfeat.cpp picofeat.cpp protos.cpp \
speckle.cpp xform2d.cpp
all: all-recursive
@ -302,6 +307,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/baseline.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/blobclass.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chartoname.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/classify.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cluster.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/clusttool.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cutoffs.Po@am__quote@
@ -326,7 +332,6 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/outfeat.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/picofeat.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protos.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sigmenu.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/speckle.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xform2d.Po@am__quote@

View File

@ -1,10 +1,10 @@
/******************************************************************************
** Filename: adaptive.c
** Purpose: Adaptive matcher.
** Author: Dan Johnson
** History: Fri Mar 8 10:00:21 1991, DSJ, Created.
** Filename: adaptive.c
** Purpose: Adaptive matcher.
** Author: Dan Johnson
** History: Fri Mar 8 10:00:21 1991, DSJ, Created.
**
** (c) Copyright Hewlett-Packard Company, 1988.
** (c) Copyright Hewlett-Packard Company, 1988.
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
@ -23,6 +23,7 @@
#include "emalloc.h"
#include "freelist.h"
#include "globals.h"
#include "classify.h"
#ifdef __UNIX__
#include <assert.h>
@ -33,23 +34,22 @@
Public Code
----------------------------------------------------------------------------**/
/*---------------------------------------------------------------------------*/
int AddAdaptedClass(ADAPT_TEMPLATES Templates,
ADAPT_CLASS Class,
CLASS_ID ClassId) {
void AddAdaptedClass(ADAPT_TEMPLATES Templates,
ADAPT_CLASS Class,
CLASS_ID ClassId) {
/*
** Parameters:
** Templates set of templates to add new class to
** Class new class to add to templates
** ClassId class id to associate with new class
** Globals: none
** Operation: This routine adds a new adapted class to an existing
** set of adapted templates.
** Return: The class index of the new class.
** Exceptions: none
** History: Thu Mar 14 13:06:09 1991, DSJ, Created.
** Parameters:
** Templates set of templates to add new class to
** Class new class to add to templates
** ClassId class id to associate with new class
** Globals: none
** Operation: This routine adds a new adapted class to an existing
** set of adapted templates.
** Return: none
** Exceptions: none
** History: Thu Mar 14 13:06:09 1991, DSJ, Created.
*/
INT_CLASS IntClass;
CLASS_INDEX ClassIndex;
assert (Templates != NULL);
assert (Class != NULL);
@ -58,13 +58,10 @@ int AddAdaptedClass(ADAPT_TEMPLATES Templates,
assert (Class->NumPermConfigs == 0);
IntClass = NewIntClass (1, 1);
ClassIndex = AddIntClass (Templates->Templates, ClassId, IntClass);
AddIntClass (Templates->Templates, ClassId, IntClass);
assert (Templates->Class[ClassIndex] == NULL);
Templates->Class[ClassIndex] = Class;
return (ClassIndex);
assert (Templates->Class[ClassId] == NULL);
Templates->Class[ClassId] = Class;
} /* AddAdaptedClass */
@ -72,14 +69,14 @@ int AddAdaptedClass(ADAPT_TEMPLATES Templates,
/*---------------------------------------------------------------------------*/
void FreeTempConfig(TEMP_CONFIG Config) {
/*
** Parameters:
** Config config to be freed
** Globals: none
** Operation: This routine frees all memory consumed by a temporary
** configuration.
** Return: none
** Exceptions: none
** History: Thu Mar 14 13:34:23 1991, DSJ, Created.
** Parameters:
** Config config to be freed
** Globals: none
** Operation: This routine frees all memory consumed by a temporary
** configuration.
** Return: none
** Exceptions: none
** History: Thu Mar 14 13:34:23 1991, DSJ, Created.
*/
assert (Config != NULL);
@ -101,13 +98,13 @@ void FreeTempProto(void *arg) {
/*---------------------------------------------------------------------------*/
ADAPT_CLASS NewAdaptedClass() {
/*
** Parameters: none
** Globals: none
** Operation: This operation allocates and initializes a new adapted
** class data structure and returns a ptr to it.
** Return: Ptr to new class data structure.
** Exceptions: none
** History: Thu Mar 14 12:58:13 1991, DSJ, Created.
** Parameters: none
** Globals: none
** Operation: This operation allocates and initializes a new adapted
** class data structure and returns a ptr to it.
** Return: Ptr to new class data structure.
** Exceptions: none
** History: Thu Mar 14 12:58:13 1991, DSJ, Created.
*/
ADAPT_CLASS Class;
int i;
@ -149,14 +146,18 @@ void free_adapted_class(ADAPT_CLASS adapt_class) {
/*---------------------------------------------------------------------------*/
ADAPT_TEMPLATES NewAdaptedTemplates() {
namespace tesseract {
ADAPT_TEMPLATES Classify::NewAdaptedTemplates(bool InitFromUnicharset) {
/*
** Parameters: none
** Globals: none
** Operation:
** Return: none
** Exceptions: none
** History: Fri Mar 8 10:15:28 1991, DSJ, Created.
** Parameters:
** PopulateFromUnicharset if true, add an empty class for
** each char in unicharset to the
** newly created templates
** Globals: none
** Operation: Allocates memory for adapted tempates.
** Return: Ptr to new adapted templates.
** Exceptions: none
** History: Fri Mar 8 10:15:28 1991, DSJ, Created.
*/
ADAPT_TEMPLATES Templates;
int i;
@ -165,14 +166,20 @@ ADAPT_TEMPLATES NewAdaptedTemplates() {
Templates->Templates = NewIntTemplates ();
Templates->NumPermClasses = 0;
Templates->NumNonEmptyClasses = 0;
for (i = 0; i < MAX_NUM_CLASSES; i++)
/* Insert an empty class for each unichar id in unicharset */
for (i = 0; i < MAX_NUM_CLASSES; i++) {
Templates->Class[i] = NULL;
if (InitFromUnicharset && i < unicharset.size()) {
AddAdaptedClass(Templates, NewAdaptedClass(), i);
}
}
return (Templates);
} /* NewAdaptedTemplates */
} // namespace tesseract
/*----------------------------------------------------------------------------*/
void free_adapted_templates(ADAPT_TEMPLATES templates) {
@ -190,14 +197,14 @@ void free_adapted_templates(ADAPT_TEMPLATES templates) {
/*---------------------------------------------------------------------------*/
TEMP_CONFIG NewTempConfig(int MaxProtoId) {
/*
** Parameters:
** MaxProtoId max id of any proto in new config
** Globals: none
** Operation: This routine allocates and returns a new temporary
** config.
** Return: Ptr to new temp config.
** Exceptions: none
** History: Thu Mar 14 13:28:21 1991, DSJ, Created.
** Parameters:
** MaxProtoId max id of any proto in new config
** Globals: none
** Operation: This routine allocates and returns a new temporary
** config.
** Return: Ptr to new temp config.
** Exceptions: none
** History: Thu Mar 14 13:28:21 1991, DSJ, Created.
*/
TEMP_CONFIG Config;
int NumProtos = MaxProtoId + 1;
@ -221,12 +228,12 @@ TEMP_CONFIG NewTempConfig(int MaxProtoId) {
/*---------------------------------------------------------------------------*/
TEMP_PROTO NewTempProto() {
/*
** Parameters: none
** Globals: none
** Operation: This routine allocates and returns a new temporary proto.
** Return: Ptr to new temporary proto.
** Exceptions: none
** History: Thu Mar 14 13:31:31 1991, DSJ, Created.
** Parameters: none
** Globals: none
** Operation: This routine allocates and returns a new temporary proto.
** Return: Ptr to new temporary proto.
** Exceptions: none
** History: Thu Mar 14 13:31:31 1991, DSJ, Created.
*/
return ((TEMP_PROTO)
alloc_struct (sizeof (TEMP_PROTO_STRUCT), "TEMP_PROTO_STRUCT"));
@ -234,17 +241,18 @@ TEMP_PROTO NewTempProto() {
/*---------------------------------------------------------------------------*/
void PrintAdaptedTemplates(FILE *File, ADAPT_TEMPLATES Templates) {
namespace tesseract {
void Classify::PrintAdaptedTemplates(FILE *File, ADAPT_TEMPLATES Templates) {
/*
** Parameters:
** File open text file to print Templates to
** Templates adapted templates to print to File
** Globals: none
** Operation: This routine prints a summary of the adapted templates
** in Templates to File.
** Return: none
** Exceptions: none
** History: Wed Mar 20 13:35:29 1991, DSJ, Created.
** Parameters:
** File open text file to print Templates to
** Templates adapted templates to print to File
** Globals: none
** Operation: This routine prints a summary of the adapted templates
** in Templates to File.
** Return: none
** Exceptions: none
** History: Wed Mar 20 13:35:29 1991, DSJ, Created.
*/
int i;
INT_CLASS IClass;
@ -253,37 +261,39 @@ void PrintAdaptedTemplates(FILE *File, ADAPT_TEMPLATES Templates) {
#ifndef SECURE_NAMES
fprintf (File, "\n\nSUMMARY OF ADAPTED TEMPLATES:\n\n");
fprintf (File, "Num classes = %d; Num permanent classes = %d\n\n",
(Templates->Templates)->NumClasses, Templates->NumPermClasses);
fprintf (File, "Index Id NC NPC NP NPP\n");
Templates->NumNonEmptyClasses, Templates->NumPermClasses);
fprintf (File, " Id NC NPC NP NPP\n");
fprintf (File, "------------------------\n");
for (i = 0; i < (Templates->Templates)->NumClasses; i++) {
IClass = Templates->Templates->Class[i];
AClass = Templates->Class[i];
fprintf (File, "%5d %s %3d %3d %3d %3d\n",
i, unicharset.id_to_unichar(Templates->Templates->ClassIdFor[i]),
if (!IsEmptyAdaptedClass (AClass)) {
fprintf (File, "%5d %s %3d %3d %3d %3d\n",
i, unicharset.id_to_unichar(i),
IClass->NumConfigs, AClass->NumPermConfigs,
IClass->NumProtos,
IClass->NumProtos - count (AClass->TempProtos));
}
}
#endif
fprintf (File, "\n");
} /* PrintAdaptedTemplates */
} // namespace tesseract
/*---------------------------------------------------------------------------*/
ADAPT_CLASS ReadAdaptedClass(FILE *File) {
/*
** Parameters:
** File open file to read adapted class from
** Globals: none
** Operation: Read an adapted class description from File and return
** a ptr to the adapted class.
** Return: Ptr to new adapted class.
** Exceptions: none
** History: Tue Mar 19 14:11:01 1991, DSJ, Created.
** Parameters:
** File open file to read adapted class from
** Globals: none
** Operation: Read an adapted class description from File and return
** a ptr to the adapted class.
** Return: Ptr to new adapted class.
** Exceptions: none
** History: Tue Mar 19 14:11:01 1991, DSJ, Created.
*/
int NumTempProtos;
int NumConfigs;
@ -328,16 +338,17 @@ ADAPT_CLASS ReadAdaptedClass(FILE *File) {
/*---------------------------------------------------------------------------*/
ADAPT_TEMPLATES ReadAdaptedTemplates(FILE *File) {
namespace tesseract {
ADAPT_TEMPLATES Classify::ReadAdaptedTemplates(FILE *File) {
/*
** Parameters:
** File open text file to read adapted templates from
** Globals: none
** Operation: Read a set of adapted templates from File and return
** a ptr to the templates.
** Return: Ptr to adapted templates read from File.
** Exceptions: none
** History: Mon Mar 18 15:18:10 1991, DSJ, Created.
** Parameters:
** File open text file to read adapted templates from
** Globals: none
** Operation: Read a set of adapted templates from File and return
** a ptr to the templates.
** Return: Ptr to adapted templates read from File.
** Exceptions: none
** History: Mon Mar 18 15:18:10 1991, DSJ, Created.
*/
int i;
ADAPT_TEMPLATES Templates;
@ -347,7 +358,7 @@ ADAPT_TEMPLATES ReadAdaptedTemplates(FILE *File) {
fread ((char *) Templates, sizeof (ADAPT_TEMPLATES_STRUCT), 1, File);
/* then read in the basic integer templates */
Templates->Templates = ReadIntTemplates (File, FALSE);
Templates->Templates = ReadIntTemplates (File);
/* then read in the adaptive info for each class */
for (i = 0; i < (Templates->Templates)->NumClasses; i++) {
@ -356,25 +367,26 @@ ADAPT_TEMPLATES ReadAdaptedTemplates(FILE *File) {
return (Templates);
} /* ReadAdaptedTemplates */
} // namespace tesseract
/*---------------------------------------------------------------------------*/
PERM_CONFIG ReadPermConfig(FILE *File) {
/*
** Parameters:
** File open file to read permanent config from
** Globals: none
** Operation: Read a permanent configuration description from File
** and return a ptr to it.
** Return: Ptr to new permanent configuration description.
** Exceptions: none
** History: Tue Mar 19 14:25:26 1991, DSJ, Created.
** Parameters:
** File open file to read permanent config from
** Globals: none
** Operation: Read a permanent configuration description from File
** and return a ptr to it.
** Return: Ptr to new permanent configuration description.
** Exceptions: none
** History: Tue Mar 19 14:25:26 1991, DSJ, Created.
*/
PERM_CONFIG Config;
uinT8 NumAmbigs;
fread ((char *) &NumAmbigs, sizeof (uinT8), 1, File);
Config = (PERM_CONFIG) Emalloc (sizeof (char) * (NumAmbigs + 1));
Config = (PERM_CONFIG) Emalloc (sizeof (UNICHAR_ID) * (NumAmbigs + 1));
fread (Config, sizeof (UNICHAR_ID), NumAmbigs, File);
Config[NumAmbigs] = -1;
@ -386,14 +398,14 @@ PERM_CONFIG ReadPermConfig(FILE *File) {
/*---------------------------------------------------------------------------*/
TEMP_CONFIG ReadTempConfig(FILE *File) {
/*
** Parameters:
** File open file to read temporary config from
** Globals: none
** Operation: Read a temporary configuration description from File
** and return a ptr to it.
** Return: Ptr to new temporary configuration description.
** Exceptions: none
** History: Tue Mar 19 14:29:59 1991, DSJ, Created.
** Parameters:
** File open file to read temporary config from
** Globals: none
** Operation: Read a temporary configuration description from File
** and return a ptr to it.
** Return: Ptr to new temporary configuration description.
** Exceptions: none
** History: Tue Mar 19 14:29:59 1991, DSJ, Created.
*/
TEMP_CONFIG Config;
@ -414,16 +426,16 @@ TEMP_CONFIG ReadTempConfig(FILE *File) {
/*---------------------------------------------------------------------------*/
void WriteAdaptedClass(FILE *File, ADAPT_CLASS Class, int NumConfigs) {
/*
** Parameters:
** File open file to write Class to
** Class adapted class to write to File
** NumConfigs number of configs in Class
** Globals: none
** Operation: This routine writes a binary representation of Class
** to File.
** Return: none
** Exceptions: none
** History: Tue Mar 19 13:33:51 1991, DSJ, Created.
** Parameters:
** File open file to write Class to
** Class adapted class to write to File
** NumConfigs number of configs in Class
** Globals: none
** Operation: This routine writes a binary representation of Class
** to File.
** Return: none
** Exceptions: none
** History: Tue Mar 19 13:33:51 1991, DSJ, Created.
*/
int NumTempProtos;
LIST TempProtos;
@ -459,16 +471,17 @@ void WriteAdaptedClass(FILE *File, ADAPT_CLASS Class, int NumConfigs) {
/*---------------------------------------------------------------------------*/
void WriteAdaptedTemplates(FILE *File, ADAPT_TEMPLATES Templates) {
namespace tesseract {
void Classify::WriteAdaptedTemplates(FILE *File, ADAPT_TEMPLATES Templates) {
/*
** Parameters:
** File open text file to write Templates to
** Templates set of adapted templates to write to File
** Globals: none
** Operation: This routine saves Templates to File in a binary format.
** Return: none
** Exceptions: none
** History: Mon Mar 18 15:07:32 1991, DSJ, Created.
** Parameters:
** File open text file to write Templates to
** Templates set of adapted templates to write to File
** Globals: none
** Operation: This routine saves Templates to File in a binary format.
** Return: none
** Exceptions: none
** History: Mon Mar 18 15:07:32 1991, DSJ, Created.
*/
int i;
@ -484,20 +497,21 @@ void WriteAdaptedTemplates(FILE *File, ADAPT_TEMPLATES Templates) {
Templates->Templates->Class[i]->NumConfigs);
}
} /* WriteAdaptedTemplates */
} // namespace tesseract
/*---------------------------------------------------------------------------*/
void WritePermConfig(FILE *File, PERM_CONFIG Config) {
/*
** Parameters:
** File open file to write Config to
** Config permanent config to write to File
** Globals: none
** Operation: This routine writes a binary representation of a
** permanent configuration to File.
** Return: none
** Exceptions: none
** History: Tue Mar 19 13:55:44 1991, DSJ, Created.
** Parameters:
** File open file to write Config to
** Config permanent config to write to File
** Globals: none
** Operation: This routine writes a binary representation of a
** permanent configuration to File.
** Return: none
** Exceptions: none
** History: Tue Mar 19 13:55:44 1991, DSJ, Created.
*/
uinT8 NumAmbigs = 0;
@ -514,15 +528,15 @@ void WritePermConfig(FILE *File, PERM_CONFIG Config) {
/*---------------------------------------------------------------------------*/
void WriteTempConfig(FILE *File, TEMP_CONFIG Config) {
/*
** Parameters:
** File open file to write Config to
** Config temporary config to write to File
** Globals: none
** Operation: This routine writes a binary representation of a
** temporary configuration to File.
** Return: none
** Exceptions: none
** History: Tue Mar 19 14:00:28 1991, DSJ, Created.
** Parameters:
** File open file to write Config to
** Config temporary config to write to File
** Globals: none
** Operation: This routine writes a binary representation of a
** temporary configuration to File.
** Return: none
** Exceptions: none
** History: Tue Mar 19 14:00:28 1991, DSJ, Created.
*/
assert (Config != NULL);
/* contexts not yet implemented */

View File

@ -68,6 +68,7 @@ typedef ADAPT_CLASS_STRUCT *ADAPT_CLASS;
typedef struct
{
INT_TEMPLATES Templates;
int NumNonEmptyClasses;
uinT8 NumPermClasses;
uinT8 dummy[3];
ADAPT_CLASS Class[MAX_NUM_CLASSES];
@ -77,6 +78,11 @@ typedef ADAPT_TEMPLATES_STRUCT *ADAPT_TEMPLATES;
/**----------------------------------------------------------------------------
Public Function Prototypes
----------------------------------------------------------------------------**/
#define NumNonEmptyClassesIn(Template) ((Template)->NumNonEmptyClasses)
#define IsEmptyAdaptedClass(Class) ((Class)->NumPermConfigs == 0 && \
(Class)->TempProtos == NIL)
#define ConfigIsPermanent(Class,ConfigId) \
(test_bit ((Class)->PermConfigs, ConfigId))
@ -95,7 +101,7 @@ typedef ADAPT_TEMPLATES_STRUCT *ADAPT_TEMPLATES;
#define IncreaseConfidence(TempConfig) \
((TempConfig)->NumTimesSeen++)
int AddAdaptedClass(ADAPT_TEMPLATES Templates,
void AddAdaptedClass(ADAPT_TEMPLATES Templates,
ADAPT_CLASS Class,
CLASS_ID ClassId);
@ -107,93 +113,22 @@ ADAPT_CLASS NewAdaptedClass();
void free_adapted_class(ADAPT_CLASS adapt_class);
ADAPT_TEMPLATES NewAdaptedTemplates();
void free_adapted_templates(ADAPT_TEMPLATES templates);
TEMP_CONFIG NewTempConfig(int MaxProtoId);
TEMP_PROTO NewTempProto();
void PrintAdaptedTemplates(FILE *File, ADAPT_TEMPLATES Templates);
ADAPT_CLASS ReadAdaptedClass(FILE *File);
ADAPT_TEMPLATES ReadAdaptedTemplates(FILE *File);
PERM_CONFIG ReadPermConfig(FILE *File);
TEMP_CONFIG ReadTempConfig(FILE *File);
void WriteAdaptedClass(FILE *File, ADAPT_CLASS Class, int NumConfigs);
void WriteAdaptedTemplates(FILE *File, ADAPT_TEMPLATES Templates);
void WritePermConfig(FILE *File, PERM_CONFIG Config);
void WriteTempConfig(FILE *File, TEMP_CONFIG Config);
/*
#if defined(__STDC__) || defined(__cplusplus)
# define _ARGS(s) s
#else
# define _ARGS(s) ()
#endif*/
/* adaptive.c
int AddAdaptedClass
_ARGS((ADAPT_TEMPLATES Templates,
ADAPT_CLASS Class,
CLASS_ID ClassId));
void FreeTempConfig
_ARGS((TEMP_CONFIG Config));
ADAPT_CLASS NewAdaptedClass
_ARGS((void));
ADAPT_TEMPLATES NewAdaptedTemplates
_ARGS((void));
TEMP_CONFIG NewTempConfig
_ARGS((int MaxProtoId));
TEMP_PROTO NewTempProto
_ARGS((void));
void PrintAdaptedTemplates
_ARGS((FILE *File,
ADAPT_TEMPLATES Templates));
ADAPT_CLASS ReadAdaptedClass
_ARGS((FILE *File));
ADAPT_TEMPLATES ReadAdaptedTemplates
_ARGS((FILE *File));
PERM_CONFIG ReadPermConfig
_ARGS((FILE *File));
TEMP_CONFIG ReadTempConfig
_ARGS((FILE *File));
void WriteAdaptedClass
_ARGS((FILE *File,
ADAPT_CLASS Class,
int NumConfigs));
void WriteAdaptedTemplates
_ARGS((FILE *File,
ADAPT_TEMPLATES Templates));
void WritePermConfig
_ARGS((FILE *File,
PERM_CONFIG Config));
void WriteTempConfig
_ARGS((FILE *File,
TEMP_CONFIG Config));
#undef _ARGS
*/
#endif

File diff suppressed because it is too large Load Diff

View File

@ -32,54 +32,24 @@
/*---------------------------------------------------------------------------
Variables
----------------------------------------------------------------------------*/
extern float GoodAdaptiveMatch;
extern float GreatAdaptiveMatch;
extern int ReliableConfigThreshold;
extern int tess_cn_matching;
extern int tess_bn_matching;
extern int LearningDebugLevel;
extern double_VAR_H(matcher_good_threshold, 0.125, "Good Match (0-1)");
extern double_VAR_H(matcher_great_threshold, 0.0, "Great Match (0-1)");
extern INT_VAR_H(matcher_failed_adaptations_before_reset, 150,
"Number of failed adaptions before adapted templates reset");
extern INT_VAR_H(matcher_min_examples_for_prototyping, 2,
"Reliable Config Threshold");
extern BOOL_VAR_H(tess_cn_matching, 0, "Character Normalized Matching");
extern BOOL_VAR_H(tess_bn_matching, 0, "Baseline Normalized Matching");
extern INT_VAR_H(classify_learning_debug_level, 0, "Learning Debug Level: ");
/**----------------------------------------------------------------------------
Public Function Prototypes
----------------------------------------------------------------------------**/
LIST AdaptiveClassifier(TBLOB *Blob, TBLOB *DotBlob, TEXTROW *Row);
/**/
void AdaptToWord(TWERD *Word,
TEXTROW *Row,
const WERD_CHOICE& BestChoice,
const WERD_CHOICE& BestRawChoice,
const char *rejmap);
void EndAdaptiveClassifier();
void InitAdaptiveClassifier();
void ResetAdaptiveClassifier();
void InitAdaptiveClassifierVars();
void PrintAdaptiveStatistics(FILE *File);
void SettupPass1();
void SettupPass2();
void MakeNewAdaptedClass(TBLOB *Blob,
LINE_STATS *LineStats,
CLASS_ID ClassId,
ADAPT_TEMPLATES Templates);
int GetAdaptiveFeatures(TBLOB *Blob,
LINE_STATS *LineStats,
INT_FEATURE_ARRAY IntFeatures,
FEATURE_SET *FloatFeatures);
int AdaptableWord(TWERD *Word,
const char *BestChoice,
const char *BestChoice_lengths,
const char *BestRawChoice,
const char *BestRawChoice_lengths);
/**----------------------------------------------------------------------------
Global Data Definitions and Declarations
----------------------------------------------------------------------------**/

View File

@ -27,9 +27,8 @@
I n c l u d e s
---------------------------------------------------------------------*/
#include "baseline.h"
//#include "blobs.h"
#include "debug.h"
#include "hideedge.h"
#include "varable.h"
/*----------------------------------------------------------------------
T y p e s
@ -39,20 +38,5 @@ typedef TPOINT SCALE;
/*----------------------------------------------------------------------
V a r i a b l e s
----------------------------------------------------------------------*/
inT8 baseline_normalized = TRUE;
make_int_var (baseline_enable, 1, make_baseline_enable,
4, 3, set_baseline_enable, "Baseline Enable");
/*----------------------------------------------------------------------
F u n c t i o n s
----------------------------------------------------------------------*/
/**********************************************************************
* init_baseline
*
* Initialize the needed baseline variables.
**********************************************************************/
void init_baseline() {
make_baseline_enable();
baseline_normalized = baseline_enable;
}
INT_VAR(classify_baseline_normalized, 1, "Baseline Enable");

View File

@ -30,6 +30,7 @@
----------------------------------------------------------------------*/
#include "general.h"
#include "tessclas.h"
#include "varable.h"
/*----------------------------------------------------------------------
T y p e s
@ -40,52 +41,7 @@
/*----------------------------------------------------------------------
V a r i a b l e s
----------------------------------------------------------------------*/
extern inT8 baseline_normalized;
extern int baseline_enable;
/*----------------------------------------------------------------------
M a c r o s
----------------------------------------------------------------------*/
/**********************************************************************
* is_baseline_normalized
*
* Check the baseline_normalized flag to see if it is set.
**********************************************************************/
#define is_baseline_normalized() \
(baseline_normalized)
extern INT_VAR_H(classify_baseline_normalized, 1, "Baseline Enable");
/**********************************************************************
* reset_baseline_normalized
*
* Reset the baseline_normalized flag to show that it is not being done.
**********************************************************************/
#define reset_baseline_normalized() \
(baseline_normalized = FALSE)
/**********************************************************************
* set_baseline_normalized
*
* Set the baseline_normalized flag to show that it is being done.
**********************************************************************/
#define set_baseline_normalized() \
(baseline_normalized = TRUE)
/*----------------------------------------------------------------------
F u n c t i o n s
----------------------------------------------------------------------*/
void init_baseline();
/*
#if defined(__STDC__) || defined(__cplusplus)
# define _ARGS(s) s
#else
# define _ARGS(s) ()
#endif*/
/* baseline.c
void init_baseline
_ARGS((void));
#undef _ARGS
*/
#endif

View File

@ -21,7 +21,6 @@
----------------------------------------------------------------------------**/
#include "blobclass.h"
#include "fxdefs.h"
#include "variables.h"
#include "extract.h"
#include "efio.h"
#include "callcpp.h"
@ -34,8 +33,8 @@
#define MAXFILENAME 80
#define MAXMATCHES 10
// define default font name to be used in training
#define FONT_NAME "UnknownFont"
STRING_VAR(classify_font_name, "UnknownFont",
"Default font name to be used in training");
/**----------------------------------------------------------------------------
Global Data Definitions and Declarations
@ -43,34 +42,14 @@
/* name of current image file being processed */
extern char imagefile[];
/* parameters used to control the training process */
static const char *FontName = FONT_NAME;
/**----------------------------------------------------------------------------
Public Code
----------------------------------------------------------------------------**/
/*---------------------------------------------------------------------------*/
void InitBlobClassifierVars() {
/*
** Parameters: none
** Globals:
** FontName name of font being trained on
** Operation: Install blob classifier variables into the wiseowl
** variable system.
** Return: none
** Exceptions: none
** History: Fri Jan 19 16:13:33 1990, DSJ, Created.
*/
VALUE dummy;
string_variable (FontName, "FontName", FONT_NAME);
} /* InitBlobClassifierVars */
/*---------------------------------------------------------------------------*/
void
LearnBlob (TBLOB * Blob, TEXTROW * Row, char BlobText[])
LearnBlob (const STRING& filename,
TBLOB * Blob, TEXTROW * Row, char BlobText[])
/*
** Parameters:
** Blob blob whose micro-features are to be learned
@ -79,7 +58,8 @@ LearnBlob (TBLOB * Blob, TEXTROW * Row, char BlobText[])
** TextLength number of characters in blob
** Globals:
** imagefile base filename of the page being learned
** FontName name of font currently being trained on
** classify_font_name
** name of font currently being trained on
** Operation:
** Extract micro-features from the specified blob and append
** them to the appropriate file.
@ -87,13 +67,10 @@ LearnBlob (TBLOB * Blob, TEXTROW * Row, char BlobText[])
** Exceptions: none
** History: 7/28/89, DSJ, Created.
*/
#define MAXFILENAME 80
#define MAXCHARNAME 20
#define MAXFONTNAME 20
#define TRAIN_SUFFIX ".tr"
{
static FILE *FeatureFile = NULL;
char Filename[MAXFILENAME];
STRING Filename(filename);
CHAR_DESC CharDesc;
LINE_STATS LineStats;
@ -102,19 +79,35 @@ LearnBlob (TBLOB * Blob, TEXTROW * Row, char BlobText[])
GetLineStatsFromRow(Row, &LineStats);
CharDesc = ExtractBlobFeatures (Blob, &LineStats);
if (CharDesc == NULL) {
cprintf("LearnBLob: CharDesc was NULL. Aborting.\n");
return;
}
// If no fontname was set, try to extract it from the filename
char CurrFontName[32] = "";
strncpy(CurrFontName, static_cast<STRING>(classify_font_name).string(), 32);
if (!strcmp(CurrFontName, "UnknownFont")) {
// filename is expected to be of the form [lang].[fontname].exp[num]
// The [lang], [fontname] and [num] fields should not have '.' characters.
const char *basename = strrchr(filename.string(), '/');
const char *firstdot = strchr(basename, '.');
const char *lastdot = strrchr(filename.string(), '.');
if (firstdot != lastdot && firstdot != NULL && lastdot != NULL) {
strncpy(CurrFontName, firstdot + 1, lastdot - firstdot - 1);
}
}
// if a feature file is not yet open, open it
// the name of the file is the name of the image plus TRAIN_SUFFIX
if (FeatureFile == NULL) {
strcpy(Filename, imagefile);
strcat(Filename, TRAIN_SUFFIX);
FeatureFile = Efopen (Filename, "w");
cprintf ("TRAINING ... Font name = %s.\n", FontName);
Filename += TRAIN_SUFFIX;
FeatureFile = Efopen (Filename.string(), "w");
cprintf ("TRAINING ... Font name = %s\n", CurrFontName);
}
// label the features with a class name and font name
fprintf (FeatureFile, "\n%s %s ", FontName, BlobText);
fprintf (FeatureFile, "\n%s %s ", CurrFontName, BlobText);
// write micro-features to file and clean up
WriteCharDescription(FeatureFile, CharDesc);

View File

@ -38,9 +38,8 @@
/**----------------------------------------------------------------------------
Public Function Prototypes
----------------------------------------------------------------------------**/
void InitBlobClassifierVars();
void LearnBlob (TBLOB * Blob, TEXTROW * Row, char BlobText[]);
void LearnBlob (const STRING& filename,
TBLOB * Blob, TEXTROW * Row, char BlobText[]);
/**----------------------------------------------------------------------------
Global Data Definitions and Declarations

86
classify/classify.cpp Normal file
View File

@ -0,0 +1,86 @@
///////////////////////////////////////////////////////////////////////
// File: classify.cpp
// Description: classify class.
// Author: Samuel Charron
//
// (C) Copyright 2006, Google Inc.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
///////////////////////////////////////////////////////////////////////
#include "classify.h"
#include "intproto.h"
#include "unicity_table.h"
#include <string.h>
namespace {
// Compare FontInfo structures.
bool compare_fontinfo(const FontInfo& fi1, const FontInfo& fi2) {
// The font properties are required to be the same for two font with the same
// name, so there is no need to test them.
// Consequently, querying the table with only its font name as information is
// enough to retrieve its properties.
return strcmp(fi1.name, fi2.name) == 0;
}
// Compare FontSet structures.
bool compare_font_set(const FontSet& fs1, const FontSet& fs2) {
if (fs1.size != fs2.size)
return false;
for (int i = 0; i < fs1.size; ++i) {
if (fs1.configs[i] != fs2.configs[i])
return false;
}
return true;
}
void delete_callback(FontInfo f) {
delete[] f.name;
}
void delete_callback_fs(FontSet fs) {
delete[] fs.configs;
}
}
namespace tesseract {
Classify::Classify()
: INT_MEMBER(tessedit_single_match, FALSE, "Top choice only from CP"),
BOOL_MEMBER(classify_enable_learning, true, "Enable adaptive classifier"),
BOOL_MEMBER(classify_recog_devanagari, false,
"Whether recognizing a language with devanagari script."),
EnableLearning(true),
dict_(&image_) {
fontinfo_table_.set_compare_callback(
NewPermanentCallback(compare_fontinfo));
fontinfo_table_.set_clear_callback(
NewPermanentCallback(delete_callback));
fontset_table_.set_compare_callback(
NewPermanentCallback(compare_font_set));
fontset_table_.set_clear_callback(
NewPermanentCallback(delete_callback_fs));
AdaptedTemplates = NULL;
PreTrainedTemplates = NULL;
inttemp_loaded_ = false;
AllProtosOn = NULL;
PrunedProtos = NULL;
AllConfigsOn = NULL;
AllProtosOff = NULL;
AllConfigsOff = NULL;
TempProtoMask = NULL;
NormProtos = NULL;
}
Classify::~Classify() {
EndAdaptiveClassifier();
}
} // namespace tesseract

230
classify/classify.h Normal file
View File

@ -0,0 +1,230 @@
///////////////////////////////////////////////////////////////////////
// File: classify.h
// Description: classify class.
// Author: Samuel Charron
//
// (C) Copyright 2006, Google Inc.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
///////////////////////////////////////////////////////////////////////
#ifndef TESSERACT_CLASSIFY_CLASSIFY_H__
#define TESSERACT_CLASSIFY_CLASSIFY_H__
#include "adaptive.h"
#include "ccstruct.h"
#include "classify.h"
#include "dict.h"
#include "fxdefs.h"
#include "intmatcher.h"
#include "ratngs.h"
#include "ocrfeatures.h"
#include "unicity_table.h"
class WERD_CHOICE;
struct ADAPT_RESULTS;
struct NORM_PROTOS;
namespace tesseract {
class Classify : public CCStruct {
public:
Classify();
~Classify();
Dict& getDict() {
return dict_;
}
/* adaptive.cpp ************************************************************/
ADAPT_TEMPLATES NewAdaptedTemplates(bool InitFromUnicharset);
int ClassPruner(INT_TEMPLATES IntTemplates,
inT16 NumFeatures,
INT_FEATURE_ARRAY Features,
CLASS_NORMALIZATION_ARRAY NormalizationFactors,
CLASS_CUTOFF_ARRAY ExpectedNumFeatures,
CLASS_PRUNER_RESULTS Results,
int Debug);
void ReadNewCutoffs(FILE *CutoffFile, inT64 end_offset,
CLASS_CUTOFF_ARRAY Cutoffs);
void PrintAdaptedTemplates(FILE *File, ADAPT_TEMPLATES Templates);
void WriteAdaptedTemplates(FILE *File, ADAPT_TEMPLATES Templates);
ADAPT_TEMPLATES ReadAdaptedTemplates(FILE *File);
/* normmatch.cpp ************************************************************/
FLOAT32 ComputeNormMatch(CLASS_ID ClassId, FEATURE Feature, BOOL8 DebugMatch);
void FreeNormProtos();
NORM_PROTOS *ReadNormProtos(FILE *File, inT64 end_offset);
/* protos.cpp ***************************************************************/
void ReadClassFile();
INT_TEMPLATES
CreateIntTemplates(CLASSES FloatProtos,
const UNICHARSET& target_unicharset);
/* adaptmatch.cpp ***********************************************************/
void AdaptToWord(TWERD *Word,
TEXTROW *Row,
const WERD_CHOICE& BestChoice,
const WERD_CHOICE& BestRawChoice,
const char *rejmap);
void InitAdaptiveClassifier();
void InitAdaptedClass(TBLOB *Blob,
LINE_STATS *LineStats,
CLASS_ID ClassId,
ADAPT_CLASS Class,
ADAPT_TEMPLATES Templates);
void AdaptToPunc(TBLOB *Blob,
LINE_STATS *LineStats,
CLASS_ID ClassId,
FLOAT32 Threshold);
void AmbigClassifier(TBLOB *Blob,
LINE_STATS *LineStats,
INT_TEMPLATES Templates,
UNICHAR_ID *Ambiguities,
ADAPT_RESULTS *Results);
void MasterMatcher(INT_TEMPLATES templates,
inT16 num_features,
INT_FEATURE_ARRAY features,
CLASS_NORMALIZATION_ARRAY norm_factors,
ADAPT_CLASS* classes,
int debug,
int num_classes,
CLASS_PRUNER_RESULTS results,
ADAPT_RESULTS* final_results);
void ConvertMatchesToChoices(ADAPT_RESULTS *Results,
BLOB_CHOICE_LIST *Choices);
void AddNewResult(ADAPT_RESULTS *Results,
CLASS_ID ClassId,
FLOAT32 Rating,
int ConfigId);
#ifndef GRAPHICS_DISABLED
void DebugAdaptiveClassifier(TBLOB *Blob,
LINE_STATS *LineStats,
ADAPT_RESULTS *Results);
#endif
void GetAdaptThresholds (TWERD * Word,
LINE_STATS * LineStats,
const WERD_CHOICE& BestChoice,
const WERD_CHOICE& BestRawChoice,
FLOAT32 Thresholds[]);
int MakeNewTemporaryConfig(ADAPT_TEMPLATES Templates,
CLASS_ID ClassId,
int NumFeatures,
INT_FEATURE_ARRAY Features,
FEATURE_SET FloatFeatures);
void MakePermanent(ADAPT_TEMPLATES Templates,
CLASS_ID ClassId,
int ConfigId,
TBLOB *Blob,
LINE_STATS *LineStats);
void PrintAdaptiveMatchResults(FILE *File, ADAPT_RESULTS *Results);
void RemoveExtraPuncs(ADAPT_RESULTS *Results);
void RemoveBadMatches(ADAPT_RESULTS *Results);
void ShowBestMatchFor(TBLOB *Blob,
LINE_STATS *LineStats,
CLASS_ID ClassId,
BOOL8 AdaptiveOn,
BOOL8 PreTrainedOn);
UNICHAR_ID *BaselineClassifier(TBLOB *Blob,
LINE_STATS *LineStats,
ADAPT_TEMPLATES Templates,
ADAPT_RESULTS *Results);
int CharNormClassifier(TBLOB *Blob,
LINE_STATS *LineStats,
INT_TEMPLATES Templates,
ADAPT_RESULTS *Results);
UNICHAR_ID *GetAmbiguities(TBLOB *Blob,
LINE_STATS *LineStats,
CLASS_ID CorrectClass);
void DoAdaptiveMatch(TBLOB *Blob,
LINE_STATS *LineStats,
ADAPT_RESULTS *Results);
void AdaptToChar(TBLOB *Blob,
LINE_STATS *LineStats,
CLASS_ID ClassId,
FLOAT32 Threshold);
int AdaptableWord(TWERD *Word,
const WERD_CHOICE &BestChoiceWord,
const WERD_CHOICE &RawChoiceWord);
void EndAdaptiveClassifier();
void PrintAdaptiveStatistics(FILE *File);
void SettupPass1();
void SettupPass2();
void AdaptiveClassifier(TBLOB *Blob,
TBLOB *DotBlob,
TEXTROW *Row,
BLOB_CHOICE_LIST *Choices,
CLASS_PRUNER_RESULTS cp_results);
void ClassifyAsNoise(ADAPT_RESULTS *Results);
void ResetAdaptiveClassifier();
FLOAT32 GetBestRatingFor(TBLOB *Blob,
LINE_STATS *LineStats,
CLASS_ID ClassId);
int GetCharNormFeatures(TBLOB *Blob,
LINE_STATS *LineStats,
INT_TEMPLATES Templates,
INT_FEATURE_ARRAY IntFeatures,
CLASS_NORMALIZATION_ARRAY CharNormArray,
inT32 *BlobLength);
int GetIntCharNormFeatures(TBLOB *Blob,
LINE_STATS *LineStats,
INT_TEMPLATES Templates,
INT_FEATURE_ARRAY IntFeatures,
CLASS_NORMALIZATION_ARRAY CharNormArray,
inT32 *BlobLength);
/* float2int.cpp ************************************************************/
void ComputeIntCharNormArray(FEATURE NormFeature,
INT_TEMPLATES Templates,
CLASS_NORMALIZATION_ARRAY CharNormArray);
/* intproto.cpp *************************************************************/
INT_TEMPLATES ReadIntTemplates(FILE *File);
void WriteIntTemplates(FILE *File, INT_TEMPLATES Templates,
const UNICHARSET& target_unicharset);
CLASS_ID GetClassToDebug(const char *Prompt);
/* font detection ***********************************************************/
UnicityTable<FontInfo>& get_fontinfo_table() {
return fontinfo_table_;
}
UnicityTable<FontSet>& get_fontset_table() {
return fontset_table_;
}
/* adaptmatch.cpp ***********************************************************/
/* name of current image file being processed */
INT_VAR_H(tessedit_single_match, FALSE, "Top choice only from CP");
/* use class variables to hold onto built-in templates and adapted
templates */
INT_TEMPLATES PreTrainedTemplates;
ADAPT_TEMPLATES AdaptedTemplates;
// Successful load of inttemp allows base tesseract classfier to be used.
bool inttemp_loaded_;
/* create dummy proto and config masks for use with the built-in templates */
BIT_VECTOR AllProtosOn;
BIT_VECTOR PrunedProtos;
BIT_VECTOR AllConfigsOn;
BIT_VECTOR AllProtosOff;
BIT_VECTOR AllConfigsOff;
BIT_VECTOR TempProtoMask;
// External control of adaption.
BOOL_VAR_H(classify_enable_learning, true, "Enable adaptive classifier");
// Internal control of Adaption so it doesn't work on pass2.
BOOL_VAR_H(classify_recog_devanagari, false,
"Whether recognizing a language with devanagari script.");
bool EnableLearning;
/* normmatch.cpp */
NORM_PROTOS *NormProtos;
/* font detection ***********************************************************/
UnicityTable<FontInfo> fontinfo_table_;
UnicityTable<FontSet> fontset_table_;
private:
Dict dict_;
};
} // namespace tesseract
#endif // TESSERACT_CLASSIFY_CLASSIFY_H__

433
classify/classify.vcproj Executable file
View File

@ -0,0 +1,433 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="classify"
ProjectGUID="{C7C7FBB5-7082-428C-8F81-8FBA7A37AC85}"
RootNamespace="classify"
Keyword="Win32Proj"
TargetFrameworkVersion="196613"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\ccutil,..\cutil,..\viewer,..\image,..\ccstruct,..\dict"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;__MSW32__;_CRT_SECURE_NO_WARNINGS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="2"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
AdditionalIncludeDirectories="..\ccutil,..\cutil,..\viewer,..\image,..\ccstruct,..\dict"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;__MSW32__;_CRT_SECURE_NO_WARNINGS"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\adaptive.cpp"
>
</File>
<File
RelativePath=".\adaptmatch.cpp"
>
</File>
<File
RelativePath=".\baseline.cpp"
>
</File>
<File
RelativePath=".\blobclass.cpp"
>
</File>
<File
RelativePath=".\chartoname.cpp"
>
</File>
<File
RelativePath=".\classify.cpp"
>
</File>
<File
RelativePath=".\cluster.cpp"
>
</File>
<File
RelativePath=".\clusttool.cpp"
>
</File>
<File
RelativePath=".\cutoffs.cpp"
>
</File>
<File
RelativePath=".\extract.cpp"
>
</File>
<File
RelativePath=".\featdefs.cpp"
>
</File>
<File
RelativePath=".\flexfx.cpp"
>
</File>
<File
RelativePath=".\float2int.cpp"
>
</File>
<File
RelativePath=".\fpoint.cpp"
>
</File>
<File
RelativePath=".\fxdefs.cpp"
>
</File>
<File
RelativePath=".\hideedge.cpp"
>
</File>
<File
RelativePath=".\intfx.cpp"
>
</File>
<File
RelativePath=".\intmatcher.cpp"
>
</File>
<File
RelativePath=".\intproto.cpp"
>
</File>
<File
RelativePath=".\kdtree.cpp"
>
</File>
<File
RelativePath=".\mf.cpp"
>
</File>
<File
RelativePath=".\mfdefs.cpp"
>
</File>
<File
RelativePath=".\mfoutline.cpp"
>
</File>
<File
RelativePath=".\mfx.cpp"
>
</File>
<File
RelativePath=".\normfeat.cpp"
>
</File>
<File
RelativePath=".\normmatch.cpp"
>
</File>
<File
RelativePath=".\ocrfeatures.cpp"
>
</File>
<File
RelativePath=".\outfeat.cpp"
>
</File>
<File
RelativePath=".\picofeat.cpp"
>
</File>
<File
RelativePath=".\protos.cpp"
>
</File>
<File
RelativePath=".\speckle.cpp"
>
</File>
<File
RelativePath=".\xform2d.cpp"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\adaptive.h"
>
</File>
<File
RelativePath=".\adaptmatch.h"
>
</File>
<File
RelativePath=".\baseline.h"
>
</File>
<File
RelativePath=".\blobclass.h"
>
</File>
<File
RelativePath=".\chartoname.h"
>
</File>
<File
RelativePath=".\classify.h"
>
</File>
<File
RelativePath=".\cluster.h"
>
</File>
<File
RelativePath=".\clusttool.h"
>
</File>
<File
RelativePath=".\cutoffs.h"
>
</File>
<File
RelativePath=".\extern.h"
>
</File>
<File
RelativePath=".\extract.h"
>
</File>
<File
RelativePath=".\featdefs.h"
>
</File>
<File
RelativePath=".\flexfx.h"
>
</File>
<File
RelativePath=".\float2int.h"
>
</File>
<File
RelativePath=".\fpoint.h"
>
</File>
<File
RelativePath=".\fxdefs.h"
>
</File>
<File
RelativePath=".\fxid.h"
>
</File>
<File
RelativePath=".\hideedge.h"
>
</File>
<File
RelativePath=".\intfx.h"
>
</File>
<File
RelativePath=".\intmatcher.h"
>
</File>
<File
RelativePath=".\intproto.h"
>
</File>
<File
RelativePath=".\kdtree.h"
>
</File>
<File
RelativePath=".\mf.h"
>
</File>
<File
RelativePath=".\mfdefs.h"
>
</File>
<File
RelativePath=".\mfoutline.h"
>
</File>
<File
RelativePath=".\mfx.h"
>
</File>
<File
RelativePath=".\normfeat.h"
>
</File>
<File
RelativePath=".\normmatch.h"
>
</File>
<File
RelativePath=".\ocrfeatures.h"
>
</File>
<File
RelativePath=".\outfeat.h"
>
</File>
<File
RelativePath=".\picofeat.h"
>
</File>
<File
RelativePath=".\protos.h"
>
</File>
<File
RelativePath=".\speckle.h"
>
</File>
<File
RelativePath=".\xform2d.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -78,7 +78,7 @@ typedef union
FLOATUNION;
typedef struct proto
typedef struct
{
unsigned Significant:1; // TRUE if prototype is significant
unsigned Merged:1; // Merged after clustering so do not output

View File

@ -19,12 +19,16 @@
Include Files and Type Defines
----------------------------------------------------------------------------**/
#include "cutoffs.h"
#include <stdio.h>
#include "classify.h"
#include "efio.h"
#include "globals.h"
#include "helpers.h"
#include "scanutils.h"
#include "serialis.h"
#include "unichar.h"
#include "globals.h"
#include <stdio.h>
#define REALLY_QUOTE_IT(x) QUOTE_IT(x)
@ -34,40 +38,41 @@
Public Code
----------------------------------------------------------------------------**/
/*---------------------------------------------------------------------------*/
void ReadNewCutoffs(const char *Filename,
CLASS_TO_INDEX ClassMapper,
CLASS_CUTOFF_ARRAY Cutoffs) {
namespace tesseract {
void Classify::ReadNewCutoffs(FILE *CutoffFile, inT64 end_offset,
CLASS_CUTOFF_ARRAY Cutoffs) {
/*
** Parameters:
** Filename name of file containing cutoff definitions
** ClassMapper array which maps class id's to class indexes
** Cutoffs array to put cutoffs into
** Globals: none
** Operation: Open Filename, read in all of the class-id/cutoff pairs
** and insert them into the Cutoffs array. Cutoffs are
** inserted in the array so that the array is indexed by
** class index rather than class id. Unused entries in the
** indexed in the array by class id. Unused entries in the
** array are set to an arbitrarily high cutoff value.
** Return: none
** Exceptions: none
** History: Wed Feb 20 09:38:26 1991, DSJ, Created.
*/
FILE *CutoffFile;
char Class[UNICHAR_LEN + 1];
CLASS_ID ClassId;
int Cutoff;
int i;
CutoffFile = Efopen (Filename, "r");
for (i = 0; i < MAX_NUM_CLASSES; i++)
Cutoffs[i] = MAX_CUTOFF;
while (fscanf (CutoffFile, "%" REALLY_QUOTE_IT(UNICHAR_LEN) "s %d",
Class, &Cutoff) == 2) {
ClassId = unicharset.unichar_to_id(Class);
Cutoffs[ClassMapper[ClassId]] = Cutoff;
while ((end_offset < 0 || ftell(CutoffFile) < end_offset) &&
fscanf(CutoffFile, "%" REALLY_QUOTE_IT(UNICHAR_LEN) "s %d",
Class, &Cutoff) == 2) {
if (strcmp(Class, "NULL") == 0) {
ClassId = unicharset.unichar_to_id(" ");
} else {
ClassId = unicharset.unichar_to_id(Class);
}
Cutoffs[ClassId] = Cutoff;
SkipNewline(CutoffFile);
}
fclose(CutoffFile);
} /* ReadNewCutoffs */
} // namespace tesseract

View File

@ -28,9 +28,6 @@ typedef uinT16 CLASS_CUTOFF_ARRAY[MAX_NUM_CLASSES];
/**----------------------------------------------------------------------------
Public Function Prototypes
----------------------------------------------------------------------------**/
void ReadNewCutoffs(const char *Filename,
CLASS_TO_INDEX ClassMapper,
CLASS_CUTOFF_ARRAY Cutoffs);
/*
#if defined(__STDC__) || defined(__cplusplus)
@ -42,7 +39,6 @@ void ReadNewCutoffs(const char *Filename,
/* cutoffs.c
void ReadNewCutoffs
_ARGS((char *Filename,
CLASS_TO_INDEX ClassMapper,
CLASS_CUTOFF_ARRAY Cutoffs));
#undef _ARGS
*/

View File

@ -19,7 +19,6 @@
Include Files and Type Defines
----------------------------------------------------------------------------**/
#include "extract.h"
#include "variables.h"
#include "flexfx.h"
#include "funcdefs.h"
#include "danerror.h"
@ -61,24 +60,6 @@ CHAR_DESC ExtractBlobFeatures(TBLOB *Blob, LINE_STATS *LineStats) {
return (ExtractFlexFeatures (Blob, LineStats));
} /* ExtractBlobFeatures */
/*---------------------------------------------------------------------------*/
void InitExtractorVars() {
/*
** Parameters: none
** Globals: none
** Operation: Install global extractor variables into the variable
** system.
** Return: none
** Exceptions: none
** History: Sun Jan 21 10:19:59 1990, DSJ, Created.
*/
// VALUE dummy;
InitFlexFXVars();
} /* InitExtractorVars */
/**----------------------------------------------------------------------------
Private Code
----------------------------------------------------------------------------**/

View File

@ -25,12 +25,10 @@
/**----------------------------------------------------------------------------
Public Function Prototypes
----------------------------------------------------------------------------**/
CHAR_DESC ExtractBlobFeatures(TBLOB *Blob, LINE_STATS *LineStats);
void InitExtractorVars();
CHAR_DESC ExtractBlobFeatures(TBLOB *Blob, LINE_STATS *LineStats);
/*---------------------------------------------------------------------------
Private Function Prototypes
----------------------------------------------------------------------------*/
void ExtractorStub();
void ExtractorStub();
#endif

View File

@ -22,8 +22,6 @@
#include "emalloc.h"
#include "danerror.h"
#include "scanutils.h"
#include "variables.h"
#include "sigmenu.h"
#include <string.h>
#include <stdio.h>

View File

@ -20,8 +20,6 @@
----------------------------------------------------------------------------**/
#include "flexfx.h"
#include "featdefs.h"
#include "variables.h"
#include "sigmenu.h"
#include "emalloc.h"
#include <string.h>
#include <stdio.h>
@ -49,39 +47,15 @@ CHAR_DESC ExtractFlexFeatures(TBLOB *Blob, LINE_STATS *LineStats) {
for (Type = 0; Type < CharDesc->NumFeatureSets; Type++)
if (FeatureDefs.FeatureExtractors[Type] != NULL &&
FeatureDefs.FeatureExtractors[Type]->Extractor != NULL)
FeatureDefs.FeatureExtractors[Type]->Extractor != NULL) {
CharDesc->FeatureSets[Type] =
(FeatureDefs.FeatureExtractors[Type])->Extractor (Blob, LineStats);
(FeatureDefs.FeatureExtractors[Type])->Extractor(Blob, LineStats);
if (CharDesc->FeatureSets[Type] == NULL) {
FreeCharDescription(CharDesc);
return NULL;
}
}
return (CharDesc);
} /* ExtractFlexFeatures */
/*---------------------------------------------------------------------------*/
void
InitFlexFXVars ()
/*
** Parameters: none
** Globals: none
** Operation: Add any control variables used by the feature extractors
** to the variable system. This includes the enable flag for
** each individual extractor. This routine needs to create
** a separate name for the enable for each feature extractor
** and allocate a string to contain that name. This is
** necessary since the "variables" routines do not create
** copies of the string names passed to them.
** Return: none
** Exceptions: none
** History: Wed May 23 15:59:23 1990, DSJ, Created.
*/
#define NamePrefix "Enable"
#define NameSuffix "Features"
{
int Type;
SetupExtractors();
for (Type = 0; Type < FeatureDefs.NumFeatureTypes; Type++) {
(FeatureDefs.FeatureExtractors[Type])->InitExtractorVars ();
}
} /* InitFlexFXVars */

View File

@ -28,7 +28,6 @@
/**----------------------------------------------------------------------------
Public Function Prototypes
----------------------------------------------------------------------------**/
CHAR_DESC ExtractFlexFeatures(TBLOB *Blob, LINE_STATS *LineStats);
CHAR_DESC ExtractFlexFeatures(TBLOB *Blob, LINE_STATS *LineStats);
void InitFlexFXVars();
#endif

View File

@ -21,6 +21,7 @@
#include "float2int.h"
#include "normmatch.h"
#include "mfoutline.h"
#include "classify.h"
#include "picofeat.h"
#define MAX_INT_CHAR_NORM (INT_CHAR_NORM_RANGE - 1)
@ -29,6 +30,8 @@
Public Code
----------------------------------------------------------------------------**/
/*---------------------------------------------------------------------------*/
namespace tesseract {
void ClearCharNormArray(INT_TEMPLATES Templates,
CLASS_NORMALIZATION_ARRAY CharNormArray) {
/*
@ -53,9 +56,9 @@ void ClearCharNormArray(INT_TEMPLATES Templates,
/*---------------------------------------------------------------------------*/
void ComputeIntCharNormArray(FEATURE NormFeature,
INT_TEMPLATES Templates,
CLASS_NORMALIZATION_ARRAY CharNormArray) {
void Classify::ComputeIntCharNormArray(
FEATURE NormFeature, INT_TEMPLATES Templates,
CLASS_NORMALIZATION_ARRAY CharNormArray) {
/*
** Parameters:
** NormFeature character normalization feature
@ -76,8 +79,7 @@ void ComputeIntCharNormArray(FEATURE NormFeature,
for (i = 0; i < Templates->NumClasses; i++) {
NormAdjust = (int) (INT_CHAR_NORM_RANGE *
ComputeNormMatch (Templates->ClassIdFor[i],
NormFeature, FALSE));
ComputeNormMatch (i, NormFeature, FALSE));
if (NormAdjust < 0)
NormAdjust = 0;
else if (NormAdjust > MAX_INT_CHAR_NORM)
@ -85,9 +87,9 @@ void ComputeIntCharNormArray(FEATURE NormFeature,
CharNormArray[i] = NormAdjust;
}
} /* ComputeIntCharNormArray */
} // namespace tesseract
/*---------------------------------------------------------------------------*/
void ComputeIntFeatures(FEATURE_SET Features, INT_FEATURE_ARRAY IntFeatures) {
@ -107,7 +109,7 @@ void ComputeIntFeatures(FEATURE_SET Features, INT_FEATURE_ARRAY IntFeatures) {
FEATURE Feature;
FLOAT32 YShift;
if (NormMethod == baseline)
if (classify_norm_method == baseline)
YShift = BASELINE_Y_SHIFT;
else
YShift = Y_SHIFT;

View File

@ -30,36 +30,11 @@
/**----------------------------------------------------------------------------
Public Function Prototypes
----------------------------------------------------------------------------**/
namespace tesseract {
void ClearCharNormArray(INT_TEMPLATES Templates,
CLASS_NORMALIZATION_ARRAY CharNormArray);
} // namespace tesseract.
void ComputeIntCharNormArray(FEATURE NormFeature,
INT_TEMPLATES Templates,
CLASS_NORMALIZATION_ARRAY CharNormArray);
void ComputeIntFeatures(FEATURE_SET Features, INT_FEATURE_ARRAY IntFeatures);
void ComputeIntFeatures(FEATURE_SET Features, INT_FEATURE_ARRAY IntFeatures);
/*
#if defined(__STDC__) || defined(__cplusplus)
# define _ARGS(s) s
#else
# define _ARGS(s) ()
#endif*/
/* float2int.c
void ClearCharNormArray
_ARGS((INT_TEMPLATES Templates,
CLASS_NORMALIZATION_ARRAY CharNormArray));
void ComputeIntCharNormArray
_ARGS((FEATURE NormFeature,
INT_TEMPLATES Templates,
CLASS_NORMALIZATION_ARRAY CharNormArray));
void ComputeIntFeatures
_ARGS((FEATURE_SET Features,
INT_FEATURE_ARRAY IntFeatures));
#undef _ARGS
*/
#endif

View File

@ -28,18 +28,10 @@
----------------------------------------------------------------------------**/
/*---------------------------------------------------------------------------*/
void FillPoint(FPOINT &P, FLOAT32 X, FLOAT32 Y) {
P.x = X;
P.y = Y;
}
/* Commented out, because there is also a same function for TPOINT and this gets resolved to it.
void CopyPoint(FPOINT &A, FPOINT &B) {
B.x = A.x;
B.y = A.y;
}
*/
FLOAT32 DistanceBetween(FPOINT A, FPOINT B) {
return sqrt ((double) (XDelta(A,B) * XDelta(A,B) + YDelta(A,B) * YDelta(A,B)));
double xd = XDelta(A, B);
double yd = YDelta(A, B);
return sqrt(static_cast<double>(xd * xd + yd * yd));
}

View File

@ -35,16 +35,9 @@ typedef FPOINT FVECTOR;
/**----------------------------------------------------------------------------
Macros
----------------------------------------------------------------------------**/
/* macros for manipulating simple point data structures */
//#define Xof(P) ( (P).x )
//#define Yof(P) ( (P).y )
//#define YofP(P) ((P)->y)
//#define XofP(P) ((P)->x)
/* macros for computing miscellaneous functions of 2 points */
#define XDelta(A,B) ( (B).x - (A).x )
#define YDelta(A,B) ( (B).y - (A).y )
#define CopyPoint(A, B) ((B).x = (A).x, (B).y = (A).y) // FIXME, gets expanded for FPOINT and TPOINT.
#define SlopeFrom(A,B) ( YDelta(A,B) / XDelta(A,B) )
#define AngleFrom(A,B) ( atan2((double) YDelta(A,B), \
(double) XDelta(A,B) ) )
@ -55,8 +48,6 @@ typedef FPOINT FVECTOR;
Public Function Prototypes
---------------------------------------------------------------------------*/
void FillPoint(FPOINT &P, FLOAT32 X, FLOAT32 Y);
FLOAT32 DistanceBetween(FPOINT A, FPOINT B);
FLOAT32 NormalizedAngleFrom(FPOINT *Point1, FPOINT *Point2, FLOAT32 FullScale);

View File

@ -29,10 +29,10 @@
int ExtractMode;
// Definitions of extractors separated from feature definitions.
DefineFeatureExt (MicroFeatureExt, ExtractMicros, InitMicroFXVars)
DefineFeatureExt (PicoFeatExt, NULL, DefaultInitFXVars)
DefineFeatureExt (CharNormExt, ExtractCharNormFeatures, DefaultInitFXVars)
DefineFeatureExt (OutlineFeatExt, NULL, DefaultInitFXVars)
DefineFeatureExt (MicroFeatureExt, ExtractMicros)
DefineFeatureExt (PicoFeatExt, NULL)
DefineFeatureExt (CharNormExt, ExtractCharNormFeatures)
DefineFeatureExt (OutlineFeatExt, NULL)
FEATURE_EXT_STRUCT* ExtractorDefs[NUM_FEATURE_TYPES] = {
&MicroFeatureExt,
@ -48,7 +48,7 @@ FEATURE_EXT_STRUCT* ExtractorDefs[NUM_FEATURE_TYPES] = {
/*---------------------------------------------------------------------------*/
void SetupExtractors() {
for (int i = 0; i < NUM_FEATURE_TYPES; ++i)
FeatureDefs.FeatureExtractors[i] = ExtractorDefs[i];
FeatureDefs.FeatureExtractors[i] = ExtractorDefs[i];
}
void GetLineStatsFromRow(TEXTROW *Row, LINE_STATS *LineStats) {

View File

@ -30,6 +30,4 @@
----------------------------------------------------------------------
*/
/*#include "stdafx.h"*/
#include "hideedge.h"
#include "debug.h"

View File

@ -22,7 +22,6 @@
#include "intmatcher.h"
#include "const.h"
#ifdef __UNIX__
#include <assert.h>
#endif
/**----------------------------------------------------------------------------
@ -33,21 +32,17 @@ uinT8 TableLookup();
uinT8 MySqrt2();
void ClipRadius();
make_int_var (RadiusGyrMinMan, 255, MakeRadiusGyrMinMan,
16, 10, SetRadiusGyrMinMan,
"Minimum Radius of Gyration Mantissa 0-255: ");
INT_VAR(classify_radius_gyr_min_man, 255,
"Minimum Radius of Gyration Mantissa 0-255: ");
make_int_var (RadiusGyrMinExp, 0, MakeRadiusGyrMinExp,
16, 11, SetRadiusGyrMinExp,
"Minimum Radius of Gyration Exponent 0-255: ");
INT_VAR(classify_radius_gyr_min_exp, 0,
"Minimum Radius of Gyration Exponent 0-255: ");
make_int_var (RadiusGyrMaxMan, 158, MakeRadiusGyrMaxMan,
16, 12, SetRadiusGyrMaxMan,
"Maximum Radius of Gyration Mantissa 0-255: ");
INT_VAR(classify_radius_gyr_max_man, 158,
"Maximum Radius of Gyration Mantissa 0-255: ");
make_int_var (RadiusGyrMaxExp, 8, MakeRadiusGyrMaxExp,
16, 13, SetRadiusGyrMaxExp,
"Maximum Radius of Gyration Exponent 0-255: ");
INT_VAR(classify_radius_gyr_max_exp, 8,
"Maximum Radius of Gyration Exponent 0-255: ");
/**----------------------------------------------------------------------------
Global Data Definitions and Declarations
@ -220,6 +215,13 @@ int ExtractIntFeat(TBLOB *Blob,
Results->Rx = (inT16) (51.2 / (double) RxInv * pow (2.0, (double) RxExp));
Results->Ry = (inT16) (51.2 / (double) RyInv * pow (2.0, (double) RyExp));
if (Results->Ry == 0) {
/*
This would result in features having 'nan' values.
Since the expression is always > 0, assign a value of 1.
*/
Results->Ry = 1;
}
Results->NumBL = NumBLFeatures;
/* extract character normalized features */
@ -460,8 +462,8 @@ void ClipRadius(uinT8 *RxInv, uinT8 *RxExp, uinT8 *RyInv, uinT8 *RyExp) {
register uinT8 BitN, LastCarry;
int RxInvLarge, RyInvSmall;
AM = RadiusGyrMinMan;
AE = RadiusGyrMinExp;
AM = classify_radius_gyr_min_man;
AE = classify_radius_gyr_min_exp;
BM = *RxInv;
BE = *RxExp;
LastCarry = 1;
@ -491,12 +493,12 @@ void ClipRadius(uinT8 *RxInv, uinT8 *RxExp, uinT8 *RyInv, uinT8 *RyExp) {
BitN = BitN & 1;
if (BitN == 1) {
*RxInv = RadiusGyrMinMan;
*RxExp = RadiusGyrMinExp;
*RxInv = classify_radius_gyr_min_man;
*RxExp = classify_radius_gyr_min_exp;
}
AM = RadiusGyrMinMan;
AE = RadiusGyrMinExp;
AM = classify_radius_gyr_min_man;
AE = classify_radius_gyr_min_exp;
BM = *RyInv;
BE = *RyExp;
LastCarry = 1;
@ -526,12 +528,12 @@ void ClipRadius(uinT8 *RxInv, uinT8 *RxExp, uinT8 *RyInv, uinT8 *RyExp) {
BitN = BitN & 1;
if (BitN == 1) {
*RyInv = RadiusGyrMinMan;
*RyExp = RadiusGyrMinExp;
*RyInv = classify_radius_gyr_min_man;
*RyExp = classify_radius_gyr_min_exp;
}
AM = RadiusGyrMaxMan;
AE = RadiusGyrMaxExp;
AM = classify_radius_gyr_max_man;
AE = classify_radius_gyr_max_exp;
BM = *RxInv;
BE = *RxExp;
LastCarry = 1;
@ -567,8 +569,8 @@ void ClipRadius(uinT8 *RxInv, uinT8 *RxExp, uinT8 *RyInv, uinT8 *RyExp) {
AM = *RyInv;
AE = *RyExp;
BM = RadiusGyrMaxMan;
BE = RadiusGyrMaxExp;
BM = classify_radius_gyr_max_man;
BE = classify_radius_gyr_max_exp;
LastCarry = 1;
while ((AM != 0) || (BM != 0)) {
if (AE > BE) {
@ -601,8 +603,8 @@ void ClipRadius(uinT8 *RxInv, uinT8 *RxExp, uinT8 *RyInv, uinT8 *RyExp) {
RyInvSmall = 0;
if (RxInvLarge && RyInvSmall) {
*RyInv = RadiusGyrMaxMan;
*RyExp = RadiusGyrMaxExp;
*RyInv = classify_radius_gyr_max_man;
*RyExp = classify_radius_gyr_max_exp;
}
}

View File

@ -20,10 +20,12 @@
Include Files and Type Defines
----------------------------------------------------------------------------**/
#include "intmatcher.h"
#include "intproto.h"
#include "tordvars.h"
#include "callcpp.h"
#include "scrollview.h"
#include "globals.h"
#include "classify.h"
#include <math.h>
#define CLASS_MASK_SIZE ((MAX_NUM_CLASSES*NUM_BITS_PER_CLASS \
@ -98,50 +100,46 @@ uinT32 EvidenceMultMask;
static inT16 LocalMatcherMultiplier;
make_int_var (ClassPrunerThreshold, 229, MakeClassPrunerThreshold,
16, 20, SetClassPrunerThreshold,
"Class Pruner Threshold 0-255: ");
INT_VAR(classify_class_pruner_threshold, 229,
"Class Pruner Threshold 0-255: ");
make_int_var (ClassPrunerMultiplier, 30, MakeClassPrunerMultiplier,
16, 21, SetClassPrunerMultiplier,
"Class Pruner Multiplier 0-255: ");
INT_VAR(classify_class_pruner_multiplier, 30,
"Class Pruner Multiplier 0-255: ");
make_int_var (IntegerMatcherMultiplier, 14, MakeIntegerMatcherMultiplier,
16, 22, SetIntegerMatcherMultiplier,
"Integer Matcher Multiplier 0-255: ");
INT_VAR(classify_integer_matcher_multiplier, 14,
"Integer Matcher Multiplier 0-255: ");
make_int_var (IntThetaFudge, 128, MakeIntThetaFudge,
16, 23, SetIntThetaFudge,
"Integer Matcher Theta Fudge 0-255: ");
INT_VAR(classify_int_theta_fudge, 128,
"Integer Matcher Theta Fudge 0-255: ");
make_int_var (CPCutoffStrength, 7, MakeCPCutoffStrength,
16, 24, SetCPCutoffStrength,
"Class Pruner CutoffStrength: ");
INT_VAR(classify_cp_cutoff_strength, 7,
"Class Pruner CutoffStrength: ");
make_int_var (EvidenceTableBits, 9, MakeEvidenceTableBits,
16, 25, SetEvidenceTableBits,
"Bits in Similarity to Evidence Lookup 8-9: ");
INT_VAR(classify_evidence_table_bits, 9,
"Bits in Similarity to Evidence Lookup 8-9: ");
make_int_var (IntEvidenceTruncBits, 14, MakeIntEvidenceTruncBits,
16, 26, SetIntEvidenceTruncBits,
"Integer Evidence Truncation Bits (Distance) 8-14: ");
INT_VAR(classify_int_evidence_trunc_bits, 14,
"Integer Evidence Truncation Bits (Distance) 8-14: ");
make_float_var (SEExponentialMultiplier, 0, MakeSEExponentialMultiplier,
16, 27, SetSEExponentialMultiplier,
"Similarity to Evidence Table Exponential Multiplier: ");
double_VAR(classify_se_exponential_multiplier, 0,
"Similarity to Evidence Table Exponential Multiplier: ");
make_float_var (SimilarityCenter, 0.0075, MakeSimilarityCenter,
16, 28, SetSimilarityCenter, "Center of Similarity Curve: ");
double_VAR(classify_similarity_center, 0.0075,
"Center of Similarity Curve: ");
make_int_var (AdaptProtoThresh, 230, MakeAdaptProtoThresh,
16, 29, SetAdaptProtoThresh,
"Threshold for good protos during adaptive 0-255: ");
INT_VAR(classify_adapt_proto_thresh, 230,
"Threshold for good protos during adaptive 0-255: ");
make_int_var (AdaptFeatureThresh, 230, MakeAdaptFeatureThresh,
16, 30, SetAdaptFeatureThresh,
"Threshold for good features during adaptive 0-255: ");
//extern int display_ratings;
//extern inT32 cp_maps[4];
INT_VAR(classify_adapt_feature_thresh, 230,
"Threshold for good features during adaptive 0-255: ");
BOOL_VAR(disable_character_fragments, FALSE,
"Do not include character fragments in the"
" results of the classifier");
BOOL_VAR(matcher_debug_separate_windows, FALSE,
"Use two different windows for debugging the matching: "
"One for the protos and one for the features.");
int protoword_lookups;
int zero_protowords;
@ -154,13 +152,14 @@ int set_config_bits;
Public Code
----------------------------------------------------------------------------**/
/*---------------------------------------------------------------------------*/
int ClassPruner(INT_TEMPLATES IntTemplates,
inT16 NumFeatures,
INT_FEATURE_ARRAY Features,
CLASS_NORMALIZATION_ARRAY NormalizationFactors,
CLASS_CUTOFF_ARRAY ExpectedNumFeatures,
CLASS_PRUNER_RESULTS Results,
int Debug) {
namespace tesseract {
int Classify::ClassPruner(INT_TEMPLATES IntTemplates,
inT16 NumFeatures,
INT_FEATURE_ARRAY Features,
CLASS_NORMALIZATION_ARRAY NormalizationFactors,
CLASS_CUTOFF_ARRAY ExpectedNumFeatures,
CLASS_PRUNER_RESULTS Results,
int Debug) {
/*
** Parameters:
** IntTemplates Class pruner tables
@ -176,8 +175,8 @@ int ClassPruner(INT_TEMPLATES IntTemplates,
** (by CLASS_ID)
** Debug Debugger flag: 1=debugger on
** Globals:
** ClassPrunerThreshold Cutoff threshold
** ClassPrunerMultiplier Normalization factor multiplier
** classify_class_pruner_threshold Cutoff threshold
** classify_class_pruner_multiplier Normalization factor multiplier
** Operation:
** Prune the classes using a modified fast match table.
** Return a sorted list of classes along with the number
@ -201,20 +200,19 @@ int ClassPruner(INT_TEMPLATES IntTemplates,
static int NormCount[MAX_NUM_CLASSES];
static int SortKey[MAX_NUM_CLASSES + 1];
static int SortIndex[MAX_NUM_CLASSES + 1];
CLASS_INDEX Class;
int out_class;
int MaxNumClasses;
int MaxCount;
int NumClasses;
FLOAT32 max_rating; //max allowed rating
int *ClassCountPtr;
CLASS_ID classch;
CLASS_ID class_id;
MaxNumClasses = IntTemplates->NumClasses;
/* Clear Class Counts */
ClassCountPtr = &(ClassCount[0]);
for (Class = 0; Class < MaxNumClasses; Class++) {
for (class_id = 0; class_id < MaxNumClasses; class_id++) {
*ClassCountPtr++ = 0;
}
@ -222,18 +220,27 @@ int ClassPruner(INT_TEMPLATES IntTemplates,
NumPruners = IntTemplates->NumClassPruners;
for (feature_index = 0; feature_index < NumFeatures; feature_index++) {
feature = &Features[feature_index];
feature_address = (((feature->X * NUM_CP_BUCKETS >> 8) * NUM_CP_BUCKETS
+
(feature->Y * NUM_CP_BUCKETS >> 8)) *
NUM_CP_BUCKETS +
(feature->Theta * NUM_CP_BUCKETS >> 8)) << 1;
feature_address = (((feature->X * NUM_CP_BUCKETS >> 8) * NUM_CP_BUCKETS +
(feature->Y * NUM_CP_BUCKETS >> 8)) * NUM_CP_BUCKETS +
(feature->Theta * NUM_CP_BUCKETS >> 8)) << 1;
ClassPruner = IntTemplates->ClassPruner;
class_index = 0;
for (PrunerSet = 0; PrunerSet < NumPruners; PrunerSet++, ClassPruner++) {
BasePrunerAddress = (uinT32 *) (*ClassPruner) + feature_address;
for (Word = 0; Word < WERDS_PER_CP_VECTOR; Word++) {
PrunerWord = *BasePrunerAddress++;
// This inner loop is unrolled to speed up the ClassPruner.
// Currently gcc would not unroll it unless it is set to O3
// level of optimization or -funroll-loops is specified.
/*
uinT32 class_mask = (1 << NUM_BITS_PER_CLASS) - 1;
for (int bit = 0; bit < BITS_PER_WERD/NUM_BITS_PER_CLASS; bit++) {
ClassCount[class_index++] += PrunerWord & class_mask;
PrunerWord >>= NUM_BITS_PER_CLASS;
}
*/
ClassCount[class_index++] += cp_maps[PrunerWord & 3];
PrunerWord >>= 2;
ClassCount[class_index++] += cp_maps[PrunerWord & 3];
@ -270,57 +277,70 @@ int ClassPruner(INT_TEMPLATES IntTemplates,
}
/* Adjust Class Counts for Number of Expected Features */
for (Class = 0; Class < MaxNumClasses; Class++) {
if (NumFeatures < ExpectedNumFeatures[Class]) {
int deficit = ExpectedNumFeatures[Class] - NumFeatures;
ClassCount[Class] -= ClassCount[Class] * deficit /
(NumFeatures*CPCutoffStrength + deficit);
for (class_id = 0; class_id < MaxNumClasses; class_id++) {
if (NumFeatures < ExpectedNumFeatures[class_id]) {
int deficit = ExpectedNumFeatures[class_id] - NumFeatures;
ClassCount[class_id] -= ClassCount[class_id] * deficit /
(NumFeatures*classify_cp_cutoff_strength + deficit);
}
if (!unicharset.get_enabled(class_id))
ClassCount[class_id] = 0; // This char is disabled!
// Do not include character fragments in the class pruner
// results if disable_character_fragments is true.
if (disable_character_fragments && unicharset.get_fragment(class_id)) {
ClassCount[class_id] = 0;
}
if (!unicharset.get_enabled(IntTemplates->ClassIdFor[Class]))
ClassCount[Class] = 0; // This char is disabled!
}
/* Adjust Class Counts for Normalization Factors */
MaxCount = 0;
for (Class = 0; Class < MaxNumClasses; Class++) {
NormCount[Class] = ClassCount[Class]
- ((ClassPrunerMultiplier * NormalizationFactors[Class]) >> 8)
for (class_id = 0; class_id < MaxNumClasses; class_id++) {
NormCount[class_id] = ClassCount[class_id]
- ((classify_class_pruner_multiplier * NormalizationFactors[class_id]) >> 8)
* cp_maps[3] / 3;
if (NormCount[Class] > MaxCount)
MaxCount = NormCount[Class];
if (NormCount[class_id] > MaxCount &&
// This additional check is added in order to ensure that
// the classifier will return at least one non-fragmented
// character match.
// TODO(daria): verify that this helps accuracy and does not
// hurt performance.
!unicharset.get_fragment(class_id)) {
MaxCount = NormCount[class_id];
}
}
/* Prune Classes */
MaxCount *= ClassPrunerThreshold;
MaxCount *= classify_class_pruner_threshold;
MaxCount >>= 8;
/* Select Classes */
if (MaxCount < 1)
MaxCount = 1;
NumClasses = 0;
for (Class = 0; Class < MaxNumClasses; Class++)
if (NormCount[Class] >= MaxCount) {
NumClasses++;
SortIndex[NumClasses] = Class;
SortKey[NumClasses] = NormCount[Class];
for (class_id = 0; class_id < MaxNumClasses; class_id++) {
if (NormCount[class_id] >= MaxCount) {
NumClasses++;
SortIndex[NumClasses] = class_id;
SortKey[NumClasses] = NormCount[class_id];
}
}
/* Sort Classes using Heapsort Algorithm */
if (NumClasses > 1)
HeapSort(NumClasses, SortKey, SortIndex);
if (display_ratings > 1) {
if (tord_display_ratings > 1) {
cprintf ("CP:%d classes, %d features:\n", NumClasses, NumFeatures);
for (Class = 0; Class < NumClasses; Class++) {
classch = IntTemplates->ClassIdFor[SortIndex[NumClasses - Class]];
for (class_id = 0; class_id < NumClasses; class_id++) {
cprintf ("%s:C=%d, E=%d, N=%d, Rat=%d\n",
unicharset.id_to_unichar(classch),
ClassCount[SortIndex[NumClasses - Class]],
ExpectedNumFeatures[SortIndex[NumClasses - Class]],
SortKey[NumClasses - Class],
1010 - 1000 * SortKey[NumClasses - Class] /
unicharset.debug_str(SortIndex[NumClasses - class_id]).string(),
ClassCount[SortIndex[NumClasses - class_id]],
ExpectedNumFeatures[SortIndex[NumClasses - class_id]],
SortKey[NumClasses - class_id],
1010 - 1000 * SortKey[NumClasses - class_id] /
(cp_maps[3] * NumFeatures));
}
if (display_ratings > 2) {
if (tord_display_ratings > 2) {
NumPruners = IntTemplates->NumClassPruners;
for (feature_index = 0; feature_index < NumFeatures;
feature_index++) {
@ -339,10 +359,10 @@ int ClassPruner(INT_TEMPLATES IntTemplates,
for (Word = 0; Word < WERDS_PER_CP_VECTOR; Word++) {
PrunerWord = *BasePrunerAddress++;
for (Class = 0; Class < 16; Class++, class_index++) {
for (class_id = 0; class_id < 16; class_id++, class_index++) {
if (NormCount[class_index] >= MaxCount)
cprintf (" %s=%d,",
unicharset.id_to_unichar(IntTemplates->ClassIdFor[class_index]),
unicharset.id_to_unichar(class_index),
PrunerWord & 3);
PrunerWord >>= 2;
}
@ -351,13 +371,12 @@ int ClassPruner(INT_TEMPLATES IntTemplates,
cprintf ("\n");
}
cprintf ("Adjustments:");
for (Class = 0; Class < MaxNumClasses; Class++) {
if (NormCount[Class] > MaxCount)
for (class_id = 0; class_id < MaxNumClasses; class_id++) {
if (NormCount[class_id] > MaxCount)
cprintf (" %s=%d,",
unicharset.id_to_unichar(IntTemplates->ClassIdFor[Class]),
-((ClassPrunerMultiplier *
NormalizationFactors[Class]) >> 8) * cp_maps[3] /
3);
unicharset.id_to_unichar(class_id),
-((classify_class_pruner_multiplier *
NormalizationFactors[class_id]) >> 8) * cp_maps[3] / 3);
}
cprintf ("\n");
}
@ -365,19 +384,18 @@ int ClassPruner(INT_TEMPLATES IntTemplates,
/* Set Up Results */
max_rating = 0.0f;
for (Class = 0, out_class = 0; Class < NumClasses; Class++) {
Results[out_class].Class =
IntTemplates->ClassIdFor[SortIndex[NumClasses - Class]];
for (class_id = 0, out_class = 0; class_id < NumClasses; class_id++) {
Results[out_class].Class = SortIndex[NumClasses - class_id];
Results[out_class].Rating =
1.0 - SortKey[NumClasses -
Class] / ((float) cp_maps[3] * NumFeatures);
class_id] / ((float) cp_maps[3] * NumFeatures);
out_class++;
}
NumClasses = out_class;
return NumClasses;
}
} // namespace tesseract
/*---------------------------------------------------------------------------*/
void IntegerMatcher(INT_CLASS ClassTemplate,
@ -402,7 +420,7 @@ void IntegerMatcher(INT_CLASS ClassTemplate,
** Debug Debugger flag: 1=debugger on
** Globals:
** LocalMatcherMultiplier Normalization factor multiplier
** IntThetaFudge Theta fudge factor used for
** classify_int_theta_fudge Theta fudge factor used for
** evidence calculation
** Operation:
** IntegerMatcher returns the best configuration and rating
@ -511,12 +529,12 @@ int FindGoodProtos(INT_CLASS ClassTemplate,
** Debug Debugger flag: 1=debugger on
** Globals:
** LocalMatcherMultiplier Normalization factor multiplier
** IntThetaFudge Theta fudge factor used for
** classify_int_theta_fudge Theta fudge factor used for
** evidence calculation
** AdaptProtoThresh Threshold for good protos
** classify_adapt_proto_thresh Threshold for good protos
** Operation:
** FindGoodProtos finds all protos whose normalized proto-evidence
** exceed AdaptProtoThresh. The list is ordered by increasing
** exceed classify_adapt_proto_thresh. The list is ordered by increasing
** proto id number.
** Return:
** Number of good protos in ProtoArray.
@ -571,7 +589,7 @@ int FindGoodProtos(INT_CLASS ClassTemplate,
Temp /= ClassTemplate->ProtoLengths[ActualProtoNum];
/* Find Good Protos */
if (Temp >= AdaptProtoThresh) {
if (Temp >= classify_adapt_proto_thresh) {
*ProtoArray = ActualProtoNum;
ProtoArray++;
NumGoodProtos++;
@ -606,12 +624,12 @@ int FindBadFeatures(INT_CLASS ClassTemplate,
** Debug Debugger flag: 1=debugger on
** Globals:
** LocalMatcherMultiplier Normalization factor multiplier
** IntThetaFudge Theta fudge factor used for
** classify_int_theta_fudge Theta fudge factor used for
** evidence calculation
** AdaptFeatureThresh Threshold for bad features
** classify_adapt_feature_thresh Threshold for bad features
** Operation:
** FindBadFeatures finds all features whose maximum feature-evidence
** was less than AdaptFeatureThresh. The list is ordered by increasing
** was less than classify_adapt_feature_thresh. The list is ordered by increasing
** feature number.
** Return:
** Number of bad features in FeatureArray.
@ -650,7 +668,7 @@ int FindBadFeatures(INT_CLASS ClassTemplate,
Temp = *UINT8Pointer;
/* Find Bad Features */
if (Temp < AdaptFeatureThresh) {
if (Temp < classify_adapt_feature_thresh) {
*FeatureArray = Feature;
FeatureArray++;
NumBadFeatures++;
@ -691,15 +709,15 @@ void InitIntegerMatcher() {
for (i = 0; i < SE_TABLE_SIZE; i++) {
IntSimilarity = i << (27 - SE_TABLE_BITS);
Similarity = ((double) IntSimilarity) / 65536.0 / 65536.0;
Evidence = Similarity / SimilarityCenter;
Evidence = Similarity / classify_similarity_center;
Evidence *= Evidence;
Evidence += 1.0;
Evidence = 1.0 / Evidence;
Evidence *= 255.0;
if (SEExponentialMultiplier > 0.0) {
ScaleFactor = 1.0 - exp (-SEExponentialMultiplier) *
exp (SEExponentialMultiplier * ((double) i / SE_TABLE_SIZE));
if (classify_se_exponential_multiplier > 0.0) {
ScaleFactor = 1.0 - exp (-classify_se_exponential_multiplier) *
exp (classify_se_exponential_multiplier * ((double) i / SE_TABLE_SIZE));
if (ScaleFactor > 1.0)
ScaleFactor = 1.0;
if (ScaleFactor < 0.0)
@ -712,28 +730,13 @@ void InitIntegerMatcher() {
/* Initialize evidence computation variables */
EvidenceTableMask =
((1 << EvidenceTableBits) - 1) << (9 - EvidenceTableBits);
MultTruncShiftBits = (14 - IntEvidenceTruncBits);
((1 << classify_evidence_table_bits) - 1) << (9 - classify_evidence_table_bits);
MultTruncShiftBits = (14 - classify_int_evidence_trunc_bits);
TableTruncShiftBits = (27 - SE_TABLE_BITS - (MultTruncShiftBits << 1));
EvidenceMultMask = ((1 << IntEvidenceTruncBits) - 1);
EvidenceMultMask = ((1 << classify_int_evidence_trunc_bits) - 1);
}
/*---------------------------------------------------------------------------*/
void InitIntegerMatcherVars() {
MakeClassPrunerThreshold();
MakeClassPrunerMultiplier();
MakeIntegerMatcherMultiplier();
MakeIntThetaFudge();
MakeCPCutoffStrength();
MakeEvidenceTableBits();
MakeIntEvidenceTruncBits();
MakeSEExponentialMultiplier();
MakeSimilarityCenter();
}
/*-------------------------------------------------------------------------*/
void PrintIntMatcherStats(FILE *f) {
fprintf (f, "protoword_lookups=%d, zero_protowords=%d, proto_shifts=%d\n",
@ -745,21 +748,21 @@ void PrintIntMatcherStats(FILE *f) {
/*-------------------------------------------------------------------------*/
void SetProtoThresh(FLOAT32 Threshold) {
AdaptProtoThresh = (int) (255 * Threshold);
if (AdaptProtoThresh < 0)
AdaptProtoThresh = 0;
if (AdaptProtoThresh > 255)
AdaptProtoThresh = 255;
classify_adapt_proto_thresh.set_value(255 * Threshold);
if (classify_adapt_proto_thresh < 0)
classify_adapt_proto_thresh.set_value(0);
if (classify_adapt_proto_thresh > 255)
classify_adapt_proto_thresh.set_value(255);
}
/*---------------------------------------------------------------------------*/
void SetFeatureThresh(FLOAT32 Threshold) {
AdaptFeatureThresh = (int) (255 * Threshold);
if (AdaptFeatureThresh < 0)
AdaptFeatureThresh = 0;
if (AdaptFeatureThresh > 255)
AdaptFeatureThresh = 255;
classify_adapt_feature_thresh.set_value(255 * Threshold);
if (classify_adapt_feature_thresh < 0)
classify_adapt_feature_thresh.set_value(0);
if (classify_adapt_feature_thresh > 255)
classify_adapt_feature_thresh.set_value(255);
}
@ -771,7 +774,7 @@ void SetBaseLineMatch() {
/*--------------------------------------------------------------------------*/
void SetCharNormMatch() {
LocalMatcherMultiplier = IntegerMatcherMultiplier;
LocalMatcherMultiplier = classify_integer_matcher_multiplier;
}
@ -972,7 +975,7 @@ int Debug) {
- (Proto->B * (Feature->Y - 128)) + (Proto->C << 9));
M3 =
(((inT8) (Feature->Theta - Proto->Angle)) *
IntThetaFudge) << 1;
classify_int_theta_fudge) << 1;
if (A3 < 0)
A3 = ~A3;
@ -1203,13 +1206,12 @@ int Debug) {
int NumProtos;
register int Temp;
extern ScrollView *IntMatchWindow;
if (IntMatchWindow == NULL) {
IntMatchWindow = c_create_window ("IntMatchWindow", 50, 200,
520, 520,
-130.0, 130.0, -130.0, 130.0);
InitIntMatchWindowIfReqd();
if (matcher_debug_separate_windows) {
InitFeatureDisplayWindowIfReqd();
InitProtoDisplayWindowIfReqd();
}
NumProtos = ClassTemplate->NumProtos;
for (ProtoSetIndex = 0; ProtoSetIndex < ClassTemplate->NumProtoSets;
@ -1233,7 +1235,7 @@ int Debug) {
if (ConfigWord) {
/* Update display for current proto */
if (ClipMatchEvidenceOn (Debug)) {
if (Temp < AdaptProtoThresh)
if (Temp < classify_adapt_proto_thresh)
DisplayIntProto (ClassTemplate, ActualProtoNum,
(Temp / 255.0));
else
@ -1268,6 +1270,12 @@ void IMDisplayFeatureDebugInfo(INT_CLASS ClassTemplate,
IMClearTables(ClassTemplate, SumOfFeatureEvidence, ProtoEvidence);
InitIntMatchWindowIfReqd();
if (matcher_debug_separate_windows) {
InitFeatureDisplayWindowIfReqd();
InitProtoDisplayWindowIfReqd();
}
NumConfigs = ClassTemplate->NumConfigs;
for (Feature = 0; Feature < NumFeatures; Feature++) {
IMUpdateTablesForFeature (ClassTemplate, ProtoMask, ConfigMask, Feature,
@ -1283,7 +1291,7 @@ void IMDisplayFeatureDebugInfo(INT_CLASS ClassTemplate,
/* Update display for current feature */
if (ClipMatchEvidenceOn (Debug)) {
if (Temp < AdaptFeatureThresh)
if (Temp < classify_adapt_feature_thresh)
DisplayIntFeature (&(Features[Feature]), 0.0);
else
DisplayIntFeature (&(Features[Feature]), 1.0);
@ -1412,7 +1420,7 @@ uinT8 NormalizationFactor, INT_RESULT Result) {
Best2Match = 0;
IntPointer = SumOfFeatureEvidence;
for (ConfigNum = 0; ConfigNum < NumConfigs; ConfigNum++, IntPointer++) {
if (display_ratings > 1)
if (tord_display_ratings > 1)
cprintf ("Config %d, rating=%d\n", ConfigNum, *IntPointer);
if (*IntPointer > BestMatch) {
if (BestMatch > 0) {

View File

@ -18,10 +18,23 @@
#ifndef INTMATCHER_H
#define INTMATCHER_H
#include "varable.h"
// Character fragments could be present in the trained templaes
// but turned on/off on the language-by-language basis or depending
// on particular properties of the corpus (e.g. when we expect the
// images to have low exposure).
extern BOOL_VAR_H(disable_character_fragments, FALSE,
"Do not include character fragments in the"
" results of the classifier");
extern INT_VAR_H(classify_integer_matcher_multiplier, 14,
"Integer Matcher Multiplier 0-255: ");
/**----------------------------------------------------------------------------
Include Files and Type Defines
----------------------------------------------------------------------------**/
#include "debug.h"
#include "intproto.h"
#include "cutoffs.h"
@ -54,19 +67,16 @@ typedef uinT8 CLASS_NORMALIZATION_ARRAY[MAX_NUM_CLASSES];
/*----------------------------------------------------------------------------
Variables
-----------------------------------------------------------------------------*/
extern int AdaptProtoThresh;
extern int AdaptFeatureThresh;
extern INT_VAR_H(classify_adapt_proto_thresh, 230,
"Threshold for good protos during adaptive 0-255: ");
extern INT_VAR_H(classify_adapt_feature_thresh, 230,
"Threshold for good features during adaptive 0-255: ");
/**----------------------------------------------------------------------------
Public Function Prototypes
----------------------------------------------------------------------------**/
int ClassPruner(INT_TEMPLATES IntTemplates,
inT16 NumFeatures,
INT_FEATURE_ARRAY Features,
CLASS_NORMALIZATION_ARRAY NormalizationFactors,
CLASS_CUTOFF_ARRAY ExpectedNumFeatures,
CLASS_PRUNER_RESULTS Results,
int Debug);
void IntegerMatcher(INT_CLASS ClassTemplate,
BIT_VECTOR ProtoMask,
@ -98,8 +108,6 @@ int FindBadFeatures(INT_CLASS ClassTemplate,
void InitIntegerMatcher();
void InitIntegerMatcherVars();
void PrintIntMatcherStats(FILE *f);
void SetProtoThresh(FLOAT32 Threshold);
@ -193,7 +201,5 @@ void HeapSort (int n, register int ra[], register int rb[]);
/**----------------------------------------------------------------------------
Global Data Definitions and Declarations
----------------------------------------------------------------------------**/
extern int IntegerMatcherMultiplier;
extern uinT32 EvidenceMultMask;
#endif

File diff suppressed because it is too large Load Diff

View File

@ -38,7 +38,8 @@
#define MAX_PROTO_INDEX 24
#define BITS_PER_WERD (8 * sizeof (uinT32))
#define MAX_NUM_CONFIGS 32
/* Script detection: increase this number to 128 */
#define MAX_NUM_CONFIGS 64
#define MAX_NUM_PROTOS 512
#define PROTOS_PER_PROTO_SET 64
#define MAX_NUM_PROTO_SETS (MAX_NUM_PROTOS / PROTOS_PER_PROTO_SET)
@ -62,6 +63,11 @@
#define WERDS_PER_CONFIG_VEC ((MAX_NUM_CONFIGS + BITS_PER_WERD - 1) / \
BITS_PER_WERD)
/* The first 3 dimensions of the CLASS_PRUNER_STRUCT are the
* 3 axes of the quantized feature space.
* The position of the the bits recorded for each class in the
* 4th dimension is determined by using CPrunerWordIndexFor(c),
* where c is the corresponding class id. */
typedef uinT32 CLASS_PRUNER_STRUCT
[NUM_CP_BUCKETS][NUM_CP_BUCKETS][NUM_CP_BUCKETS][WERDS_PER_CP_VECTOR];
@ -80,9 +86,11 @@ typedef struct
INT_PROTO_STRUCT, *INT_PROTO;
typedef uinT32 PROTO_PRUNER[NUM_PP_PARAMS][NUM_PP_BUCKETS][WERDS_PER_PP_VECTOR];
typedef struct
{
uinT32 ProtoPruner[NUM_PP_PARAMS][NUM_PP_BUCKETS][WERDS_PER_PP_VECTOR];
PROTO_PRUNER ProtoPruner;
INT_PROTO_STRUCT Protos[PROTOS_PER_PROTO_SET];
}
@ -91,6 +99,35 @@ PROTO_SET_STRUCT, *PROTO_SET;
typedef uinT32 CONFIG_PRUNER[NUM_PP_PARAMS][NUM_PP_BUCKETS][4];
/*
* font_properties contains properties about boldness, italicness, fixed pitch,
* serif, fraktur
*/
struct FontInfo {
char* name;
uinT32 properties;
bool is_italic() { return properties & 1; }
bool is_bold() { return (properties & 2) != 0; }
bool is_fixed_pitch() { return (properties & 4) != 0; }
bool is_serif() { return (properties & 8) != 0; }
bool is_fraktur() { return (properties & 16) != 0; }
};
// Every class (character) owns a FontSet that represents all the fonts that can
// render this character.
// Since almost all the characters from the same script share the same set of
// fonts, the sets are shared over multiple classes (see
// Classify::fontset_table_). Thus, a class only store an id to a set.
// Because some fonts cannot render just one character of a set, there are a
// lot of FontSet that differ only by one font. Rather than storing directly
// the FontInfo in the FontSet structure, it's better to share FontInfos among
// FontSets (Classify::fontinfo_table_).
struct FontSet {
int size;
int* configs; // FontInfo ids
};
typedef struct
{
uinT16 NumProtos;
@ -99,6 +136,7 @@ typedef struct
PROTO_SET ProtoSets[MAX_NUM_PROTO_SETS];
uinT8 *ProtoLengths;
uinT16 ConfigLengths[MAX_NUM_CONFIGS];
int font_set_id; // FontSet id, see above
}
@ -108,8 +146,6 @@ typedef struct
{
int NumClasses;
int NumClassPruners;
CLASS_TO_INDEX IndexFor;
INDEX_TO_CLASS ClassIdFor;
INT_CLASS Class[MAX_NUM_CLASSES];
CLASS_PRUNER ClassPruner[MAX_NUM_CLASS_PRUNERS];
}
@ -121,20 +157,24 @@ INT_TEMPLATES_STRUCT, *INT_TEMPLATES;
#define MAX_NUM_INT_FEATURES 512
#define INT_CHAR_NORM_RANGE 256
typedef struct
struct INT_FEATURE_STRUCT
{
uinT8 X;
uinT8 Y;
uinT8 Theta;
inT8 CP_misses;
}
};
INT_FEATURE_STRUCT;
typedef INT_FEATURE_STRUCT *INT_FEATURE;
typedef INT_FEATURE_STRUCT INT_FEATURE_ARRAY[MAX_NUM_INT_FEATURES];
enum IntmatcherDebugAction {
IDA_ADAPTIVE,
IDA_STATIC,
IDA_BOTH
};
/**----------------------------------------------------------------------------
Macros
----------------------------------------------------------------------------**/
@ -150,13 +190,15 @@ typedef INT_FEATURE_STRUCT INT_FEATURE_ARRAY[MAX_NUM_INT_FEATURES];
#define PPrunerMaskFor(I) (1 << PPrunerBitIndexFor (I))
#define MaxNumClassesIn(T) (T->NumClassPruners * CLASSES_PER_CP)
#define LegalClassId(C) ((C) > 0 && (C) <= MAX_CLASS_ID)
#define UnusedClassIdIn(T,C) (T->IndexFor[C] == ILLEGAL_CLASS)
#define ClassForClassId(T,C) (T->Class[(T->IndexFor[C])])
#define CPrunerIdFor(I) ((I) / CLASSES_PER_CP)
#define CPrunerWordIndexFor(I) (((I) % CLASSES_PER_CP) / CLASSES_PER_CP_WERD)
#define CPrunerBitIndexFor(I) (((I) % CLASSES_PER_CP) % CLASSES_PER_CP_WERD)
#define CPrunerMaskFor(L,I) (((L)+1) << CPrunerBitIndexFor (I) * NUM_BITS_PER_CLASS)
#define LegalClassId(c) ((c) >= 0 && (c) <= MAX_CLASS_ID)
#define UnusedClassIdIn(T,c) ((T)->Class[c] == NULL)
#define ClassForClassId(T,c) ((T)->Class[c])
#define ClassPrunersFor(T) ((T)->ClassPruner)
#define CPrunerIdFor(c) ((c) / CLASSES_PER_CP)
#define CPrunerFor(T,c) ((T)->ClassPruner [CPrunerIdFor (c)])
#define CPrunerWordIndexFor(c) (((c) % CLASSES_PER_CP) / CLASSES_PER_CP_WERD)
#define CPrunerBitIndexFor(c) (((c) % CLASSES_PER_CP) % CLASSES_PER_CP_WERD)
#define CPrunerMaskFor(L,c) (((L)+1) << CPrunerBitIndexFor (c) * NUM_BITS_PER_CLASS)
/* DEBUG macros*/
#define PRINT_MATCH_SUMMARY 0x001
@ -177,7 +219,7 @@ typedef INT_FEATURE_STRUCT INT_FEATURE_ARRAY[MAX_NUM_INT_FEATURES];
/**----------------------------------------------------------------------------
Public Function Prototypes
----------------------------------------------------------------------------**/
int AddIntClass(INT_TEMPLATES Templates, CLASS_ID ClassId, INT_CLASS Class);
void AddIntClass(INT_TEMPLATES Templates, CLASS_ID ClassId, INT_CLASS Class);
int AddIntConfig(INT_CLASS Class);
@ -199,122 +241,24 @@ void ConvertConfig(BIT_VECTOR Config, int ConfigId, INT_CLASS Class);
void ConvertProto(PROTO Proto, int ProtoId, INT_CLASS Class);
INT_TEMPLATES CreateIntTemplates(CLASSES FloatProtos,
const UNICHARSET& target_unicharset);
void DisplayIntFeature(INT_FEATURE Feature, FLOAT32 Evidence);
void DisplayIntProto(INT_CLASS Class, PROTO_ID ProtoId, FLOAT32 Evidence);
void InitIntProtoVars();
INT_CLASS NewIntClass(int MaxNumProtos, int MaxNumConfigs);
void free_int_class(INT_CLASS int_class);
INT_TEMPLATES NewIntTemplates();
void free_int_templates(INT_TEMPLATES templates);
INT_TEMPLATES ReadIntTemplates(FILE *File, BOOL8 swap);
void ShowMatchDisplay();
CLASS_ID GetClassToDebug(const char *Prompt);
/*----------------------------------------------------------------------------*/
void WriteIntTemplates(FILE *File, INT_TEMPLATES Templates,
const UNICHARSET& target_unicharset);
void InitIntMatchWindowIfReqd();
/*
#if defined(__STDC__) || defined(__cplusplus)
# define _ARGS(s) s
#else
# define _ARGS(s) ()
#endif*/
void InitProtoDisplayWindowIfReqd();
/* intproto.c
int AddIntClass
_ARGS((INT_TEMPLATES Templates,
CLASS_ID ClassId,
INT_CLASS Class));
void InitFeatureDisplayWindowIfReqd();
int AddIntConfig
_ARGS((INT_CLASS Class));
int AddIntProto
_ARGS((INT_CLASS Class));
void AddProtoToClassPruner
_ARGS((PROTO Proto,
CLASS_ID ClassId,
INT_TEMPLATES Templates));
void AddProtoToProtoPruner
_ARGS((PROTO Proto,
int ProtoId,
INT_CLASS Class));
int BucketFor
_ARGS((FLOAT32 Param,
FLOAT32 Offset,
int NumBuckets));
int CircBucketFor
_ARGS((FLOAT32 Param,
FLOAT32 Offset,
int NumBuckets));
void UpdateMatchDisplay
_ARGS((void));
void ConvertConfig
_ARGS((BIT_VECTOR Config,
int ConfigId,
INT_CLASS Class));
void ConvertProto
_ARGS((PROTO Proto,
int ProtoId,
INT_CLASS Class));
INT_TEMPLATES CreateIntTemplates
_ARGS((CLASSES FloatProtos));
void DisplayIntFeature
_ARGS((INT_FEATURE Feature,
FLOAT32 Evidence));
void DisplayIntProto
_ARGS((INT_CLASS Class,
PROTO_ID ProtoId,
FLOAT32 Evidence));
void InitIntProtoVars
_ARGS((void));
INT_CLASS NewIntClass
_ARGS((int MaxNumProtos,
int MaxNumConfigs));
INT_TEMPLATES NewIntTemplates
_ARGS((void));
INT_TEMPLATES ReadIntTemplates
_ARGS((FILE *File));
void ShowMatchDisplay
_ARGS((void));
void WriteIntTemplates
_ARGS((FILE *File,
INT_TEMPLATES Templates));
CLASS_ID GetClassToDebug
_ARGS((char *Prompt));
C_COL GetMatchColorFor
_ARGS((FLOAT32 Evidence));
#undef _ARGS
*/
#endif

View File

@ -19,7 +19,6 @@
Include Files and Type Defines
----------------------------------------------------------------------------**/
#include "mfdefs.h"
#include "variables.h"
#include "mf.h"
#include "fxdefs.h"
#include "mfx.h"
@ -52,6 +51,8 @@ FEATURE_SET ExtractMicros(TBLOB *Blob, LINE_STATS *LineStats) {
MICROFEATURE OldFeature;
OldFeatures = (MICROFEATURES) BlobMicroFeatures (Blob, LineStats);
if (OldFeatures == NULL)
return NULL;
NumFeatures = count (OldFeatures);
FeatureSet = NewFeatureSet (NumFeatures);
@ -70,37 +71,16 @@ FEATURE_SET ExtractMicros(TBLOB *Blob, LINE_STATS *LineStats) {
// ParamOf (Feature, MFBulge2) = SecondBulgeOf (OldFeature);
Feature->Params[MFBulge1] = 0.0f;
Feature->Params[MFBulge2] = 0.0f;
#ifndef __MSW32__
// Assert that feature parameters are well defined.
int i;
for (i = 0; i < Feature->Type->NumParams; i++) {
assert(!isnan(Feature->Params[i]));
}
#endif
AddFeature(FeatureSet, Feature);
}
FreeMicroFeatures(OldFeatures);
return (FeatureSet);
} /* ExtractMicros */
/*---------------------------------------------------------------------------*/
void InitMicroFXVars() {
/*
** Parameters: none
** Globals:
** ExtraPenaltyMagnitude controls for adjusting extra penalty
** ExtraPenaltyWeight
** ExtraPenaltyOrder
** Operation: Initialize the microfeature extractor variables that can
** be tuned without recompiling.
** Return: none
** Exceptions: none
** History: Thu May 24 10:50:46 1990, DSJ, Created.
*/
/*
float_variable (ExtraPenaltyMagnitude, "MFExtraPenaltyMag",
EXTRA_PENALTY_MAGNITUDE);
float_variable (ExtraPenaltyWeight, "MFExtraPenaltyWeight",
EXTRA_PENALTY_WEIGHT);
float_variable (ExtraPenaltyOrder, "MFExtraPenaltyOrder",
EXTRA_PENALTY_ORDER);
*/
InitMicroFxVars();
} /* InitMicroFXVars */

View File

@ -32,9 +32,7 @@ typedef enum {
/*----------------------------------------------------------------------------
Private Function Prototypes
-----------------------------------------------------------------------------*/
FEATURE_SET ExtractMicros(TBLOB *Blob, LINE_STATS *LineStats);
void InitMicroFXVars();
FEATURE_SET ExtractMicros(TBLOB *Blob, LINE_STATS *LineStats);
/**----------------------------------------------------------------------------
Global Data Definitions and Declarations

View File

@ -1,10 +1,10 @@
/******************************************************************************
** Filename: mfoutline.c
** Purpose: Interface to outline struct used for extracting features
** Author: Dan Johnson
** History: Thu May 17 08:14:18 1990, DSJ, Created.
** Filename: mfoutline.c
** Purpose: Interface to outline struct used for extracting features
** Author: Dan Johnson
** History: Thu May 17 08:14:18 1990, DSJ, Created.
**
** (c) Copyright Hewlett-Packard Company, 1988.
** (c) Copyright Hewlett-Packard Company, 1988.
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
@ -21,61 +21,17 @@
#include "clusttool.h" //If remove you get cought in a loop somewhere
#include "emalloc.h"
#include "mfoutline.h"
#include "debug.h"
#include "hideedge.h"
#include "blobs.h"
#include "const.h"
#include "mfx.h"
#include "varable.h"
#include <math.h>
#include <stdio.h>
#define MIN_INERTIA (0.00001)
/**----------------------------------------------------------------------------
Private Function Prototypes
----------------------------------------------------------------------------**/
/*
#if defined(__STDC__) || defined(__cplusplus)
# define _ARGS(s) s
#else
# define _ARGS(s) ()
#endif*/
/* /users/danj/wiseowl/src/danj/microfeatures/mfoutline.c
void ChangeDirection
_ARGS((MFOUTLINE Start,
MFOUTLINE End,
DIRECTION Direction));
void CharNormalizeOutline
_ARGS((MFOUTLINE Outline,
OUTLINE_STATS *OutlineStats));
void ComputeDirection
_ARGS((MFEDGEPT *Start,
MFEDGEPT *Finish,
FLOAT32 MinSlope,
FLOAT32 MaxSlope));
void FinishOutlineStats
_ARGS((OUTLINE_STATS *OutlineStats));
void InitOutlineStats
_ARGS((OUTLINE_STATS *OutlineStats));
MFOUTLINE NextDirectionChange
_ARGS((MFOUTLINE EdgePoint));
void UpdateOutlineStats
_ARGS((OUTLINE_STATS *OutlineStats,
FLOAT32 x1,
FLOAT32 y1,
FLOAT32 x2,
FLOAT32 y2));
#undef _ARGS
*/
/**----------------------------------------------------------------------------
Global Data Definitions and Declarations
----------------------------------------------------------------------------**/
@ -83,23 +39,21 @@ void UpdateOutlineStats
expanded blobs */
static TPOINT BlobCenter;
/**----------------------------------------------------------------------------
Variables
----------------------------------------------------------------------------**/
/* control knobs used to control normalization of outlines */
make_int_var (NormMethod, character, MakeNormMethod,
15, 10, SetNormMethod, "Normalization Method ...")
INT_VAR(classify_norm_method, character, "Normalization Method ...");
/* PREV DEFAULT "baseline" */
make_float_var (CharNormRange, 0.2, MakeCharNormRange,
15, 11, SetCharNormRange, "Character Normalization Range ...")
make_float_var (MinNormScaleX, 0.0, MakeMinNormScaleX,
15, 12, SetMinNormScaleX, "Min char x-norm scale ...")
double_VAR(classify_char_norm_range, 0.2, "Character Normalization Range ...");
double_VAR(classify_min_norm_scale_x, 0.0, "Min char x-norm scale ...");
/* PREV DEFAULT 0.1 */
make_float_var (MaxNormScaleX, 0.325, MakeMaxNormScaleX,
15, 13, SetMaxNormScaleX, "Max char x-norm scale ...")
double_VAR(classify_max_norm_scale_x, 0.325, "Max char x-norm scale ...");
/* PREV DEFAULT 0.3 */
make_float_var (MinNormScaleY, 0.0, MakeMinNormScaleY,
15, 14, SetMinNormScaleY, "Min char y-norm scale ...")
double_VAR(classify_min_norm_scale_y, 0.0, "Min char y-norm scale ...");
/* PREV DEFAULT 0.1 */
make_float_var (MaxNormScaleY, 0.325, MakeMaxNormScaleY,
15, 15, SetMaxNormScaleY, "Max char y-norm scale ...")
double_VAR(classify_max_norm_scale_y, 0.325, "Max char y-norm scale ...");
/* PREV DEFAULT 0.3 */
/**----------------------------------------------------------------------------
Public Code
@ -107,19 +61,19 @@ make_float_var (MaxNormScaleY, 0.325, MakeMaxNormScaleY,
/*---------------------------------------------------------------------------*/
void ComputeBlobCenter(TBLOB *Blob, TPOINT *BlobCenter) {
/*
** Parameters:
** Blob blob to compute centerpoint of
** BlobCenter data struct to place results in
** Globals: none
** Operation:
** This routine computes the center point of the specified
** blob using the bounding box of all top level outlines in the
** blob. The center point is computed in a coordinate system
** which is scaled up by VECSCALE from the page coordinate
** system.
** Return: none
** Exceptions: none
** History: Fri Sep 8 10:45:39 1989, DSJ, Created.
** Parameters:
** Blob blob to compute centerpoint of
** BlobCenter data struct to place results in
** Globals: none
** Operation:
** This routine computes the center point of the specified
** blob using the bounding box of all top level outlines in the
** blob. The center point is computed in a coordinate system
** which is scaled up by VECSCALE from the page coordinate
** system.
** Return: none
** Exceptions: none
** History: Fri Sep 8 10:45:39 1989, DSJ, Created.
*/
TPOINT TopLeft;
TPOINT BottomRight;
@ -135,13 +89,13 @@ void ComputeBlobCenter(TBLOB *Blob, TPOINT *BlobCenter) {
/*---------------------------------------------------------------------------*/
LIST ConvertBlob(TBLOB *Blob) {
/*
** Parameters:
** Blob blob to be converted
** Globals: none
** Operation: Convert Blob into a list of outlines.
** Return: List of outlines representing blob.
** Exceptions: none
** History: Thu Dec 13 15:40:17 1990, DSJ, Created.
** Parameters:
** Blob blob to be converted
** Globals: none
** Operation: Convert Blob into a list of outlines.
** Return: List of outlines representing blob.
** Exceptions: none
** History: Thu Dec 13 15:40:17 1990, DSJ, Created.
*/
LIST ConvertedOutlines = NIL;
@ -158,30 +112,30 @@ LIST ConvertBlob(TBLOB *Blob) {
/*---------------------------------------------------------------------------*/
MFOUTLINE ConvertOutline(TESSLINE *Outline) {
/*
** Parameters:
** Outline outline to be converted
** Globals:
** BlobCenter pre-computed center of current blob
** Operation:
** This routine converts the specified outline into a special
** data structure which is used for extracting micro-features.
** If the outline has been pre-normalized by the splitter,
** then it is assumed to be in expanded form and all we must
** do is copy the points. Otherwise,
** if the outline is expanded, then the expanded form is used
** and the coordinates of the points are returned to page
** coordinates using the global variable BlobCenter and the
** scaling factor REALSCALE. If the outline is not expanded,
** then the compressed form is used.
** Return: Outline converted into special micro-features format.
** Exceptions: none
** History: 8/2/89, DSJ, Created.
** 9/8/89, DSJ, Added ability to convert expanded blobs.
** 1/11/90, DSJ, Changed to use REALSCALE instead of VECSCALE
** to eliminate round-off problems.
** 2/21/91, DSJ, Added ability to work with pre-normalized
** blobs.
** 4/30/91, DSJ, Added concept of "hidden" segments.
** Parameters:
** Outline outline to be converted
** Globals:
** BlobCenter pre-computed center of current blob
** Operation:
** This routine converts the specified outline into a special
** data structure which is used for extracting micro-features.
** If the outline has been pre-normalized by the splitter,
** then it is assumed to be in expanded form and all we must
** do is copy the points. Otherwise,
** if the outline is expanded, then the expanded form is used
** and the coordinates of the points are returned to page
** coordinates using the global variable BlobCenter and the
** scaling factor REALSCALE. If the outline is not expanded,
** then the compressed form is used.
** Return: Outline converted into special micro-features format.
** Exceptions: none
** History: 8/2/89, DSJ, Created.
** 9/8/89, DSJ, Added ability to convert expanded blobs.
** 1/11/90, DSJ, Changed to use REALSCALE instead of VECSCALE
** to eliminate round-off problems.
** 2/21/91, DSJ, Added ability to work with pre-normalized
** blobs.
** 4/30/91, DSJ, Added concept of "hidden" segments.
*/
register BYTEVEC *Vector;
TPOINT Position;
@ -197,7 +151,7 @@ MFOUTLINE ConvertOutline(TESSLINE *Outline) {
return (MFOutline);
/* have outlines been prenormalized */
if (is_baseline_normalized ()) {
if (classify_baseline_normalized) {
StartPoint = Outline->loop;
EdgePoint = StartPoint;
do {
@ -228,7 +182,8 @@ MFOUTLINE ConvertOutline(TESSLINE *Outline) {
ClearMark(NewPoint);
/* all edges are visible */
NewPoint->Hidden = FALSE;
CopyPoint (Position, NewPoint->Point);
NewPoint->Point.x = Position.x;
NewPoint->Point.y = Position.y;
MFOutline = push (MFOutline, NewPoint);
}
Position.x += Vector->dx;
@ -272,21 +227,21 @@ LIST ConvertOutlines(TESSLINE *Outline,
LIST ConvertedOutlines,
OUTLINETYPE OutlineType) {
/*
** Parameters:
** Outline first outline to be converted
** ConvertedOutlines list to add converted outlines to
** OutlineType are the outlines outer or holes?
** Globals: none
** Operation:
** Parameters:
** Outline first outline to be converted
** ConvertedOutlines list to add converted outlines to
** OutlineType are the outlines outer or holes?
** Globals: none
** Operation:
** This routine converts all given outlines into a new format.
** of outlines. Outline points to a list of the top level
** outlines to be converted. The children of these outlines
** are also recursively converted. All converted outlines
** are added to ConvertedOutlines. This is a list of outlines,
** one for each outline that was converted.
** Return: Updated list of converted outlines.
** Exceptions: none
** History: Thu Dec 13 15:57:38 1990, DSJ, Created.
** outlines to be converted. The children of these outlines
** are also recursively converted. All converted outlines
** are added to ConvertedOutlines. This is a list of outlines,
** one for each outline that was converted.
** Return: Updated list of converted outlines.
** Exceptions: none
** History: Thu Dec 13 15:57:38 1990, DSJ, Created.
*/
MFOUTLINE MFOutline;
@ -311,22 +266,22 @@ LIST ConvertOutlines(TESSLINE *Outline,
/*---------------------------------------------------------------------------*/
void ComputeOutlineStats(LIST Outlines, OUTLINE_STATS *OutlineStats) {
/*
** Parameters:
** Outlines list of outlines to compute stats for
** OutlineStats place to put results
** Globals: none
** Operation: This routine computes several statistics about the outlines
** in Outlines. These statistics are usually used to perform
** anistropic normalization of all of the outlines. The
** statistics generated are:
** first moments about x and y axes
** total length of all outlines
** center of mass of all outlines
** second moments about center of mass axes
** radius of gyration about center of mass axes
** Return: none (results are returned in OutlineStats)
** Exceptions: none
** History: Fri Dec 14 08:32:03 1990, DSJ, Created.
** Parameters:
** Outlines list of outlines to compute stats for
** OutlineStats place to put results
** Globals: none
** Operation: This routine computes several statistics about the outlines
** in Outlines. These statistics are usually used to perform
** anistropic normalization of all of the outlines. The
** statistics generated are:
** first moments about x and y axes
** total length of all outlines
** center of mass of all outlines
** second moments about center of mass axes
** radius of gyration about center of mass axes
** Return: none (results are returned in OutlineStats)
** Exceptions: none
** History: Fri Dec 14 08:32:03 1990, DSJ, Created.
*/
MFOUTLINE Outline;
MFOUTLINE EdgePoint;
@ -360,17 +315,17 @@ void ComputeOutlineStats(LIST Outlines, OUTLINE_STATS *OutlineStats) {
/*---------------------------------------------------------------------------*/
void FilterEdgeNoise(MFOUTLINE Outline, FLOAT32 NoiseSegmentLength) {
/*
** Parameters:
** Outline outline to be filtered
** NoiseSegmentLength maximum length of a "noise" segment
** Globals: none
** Operation: Filter out noise from the specified outline. This is
** done by changing the direction of short segments of the
** outline to the same direction as the preceding outline
** segment.
** Return: none
** Exceptions: none
** History: Fri May 4 10:23:45 1990, DSJ, Created.
** Parameters:
** Outline outline to be filtered
** NoiseSegmentLength maximum length of a "noise" segment
** Globals: none
** Operation: Filter out noise from the specified outline. This is
** done by changing the direction of short segments of the
** outline to the same direction as the preceding outline
** segment.
** Return: none
** Exceptions: none
** History: Fri May 4 10:23:45 1990, DSJ, Created.
*/
MFOUTLINE Current;
MFOUTLINE Last;
@ -427,21 +382,21 @@ void FindDirectionChanges(MFOUTLINE Outline,
FLOAT32 MinSlope,
FLOAT32 MaxSlope) {
/*
** Parameters:
** Outline micro-feature outline to analyze
** MinSlope controls "snapping" of segments to horizontal
** MaxSlope controls "snapping" of segments to vertical
** Globals: none
** Operation:
** This routine searches thru the specified outline, computes
** a slope for each vector in the outline, and marks each
** vector as having one of the following directions:
** N, S, E, W, NE, NW, SE, SW
** This information is then stored in the outline and the
** outline is returned.
** Return: none
** Exceptions: none
** History: 7/21/89, DSJ, Created.
** Parameters:
** Outline micro-feature outline to analyze
** MinSlope controls "snapping" of segments to horizontal
** MaxSlope controls "snapping" of segments to vertical
** Globals: none
** Operation:
** This routine searches thru the specified outline, computes
** a slope for each vector in the outline, and marks each
** vector as having one of the following directions:
** N, S, E, W, NE, NW, SE, SW
** This information is then stored in the outline and the
** outline is returned.
** Return: none
** Exceptions: none
** History: 7/21/89, DSJ, Created.
*/
MFEDGEPT *Current;
MFEDGEPT *Last;
@ -468,15 +423,15 @@ void FindDirectionChanges(MFOUTLINE Outline,
/*---------------------------------------------------------------------------*/
void FreeMFOutline(void *arg) { //MFOUTLINE Outline)
/*
** Parameters:
** Outline micro-feature outline to be freed
** Globals: none
** Operation:
** This routine deallocates all of the memory consumed by
** a micro-feature outline.
** Return: none
** Exceptions: none
** History: 7/27/89, DSJ, Created.
** Parameters:
** Outline micro-feature outline to be freed
** Globals: none
** Operation:
** This routine deallocates all of the memory consumed by
** a micro-feature outline.
** Return: none
** Exceptions: none
** History: 7/27/89, DSJ, Created.
*/
MFOUTLINE Start;
MFOUTLINE Outline = (MFOUTLINE) arg;
@ -495,56 +450,36 @@ void FreeMFOutline(void *arg) { //MFOUTLINE Outline
/*---------------------------------------------------------------------------*/
void FreeOutlines(LIST Outlines) {
/*
** Parameters:
** Outlines list of mf-outlines to be freed
** Globals: none
** Operation: Release all memory consumed by the specified list
** of outlines.
** Return: none
** Exceptions: none
** History: Thu Dec 13 16:14:50 1990, DSJ, Created.
** Parameters:
** Outlines list of mf-outlines to be freed
** Globals: none
** Operation: Release all memory consumed by the specified list
** of outlines.
** Return: none
** Exceptions: none
** History: Thu Dec 13 16:14:50 1990, DSJ, Created.
*/
destroy_nodes(Outlines, FreeMFOutline);
} /* FreeOutlines */
/*---------------------------------------------------------------------------*/
void InitMFOutlineVars() {
/*
** Parameters: none
** Globals: none
** Operation: This routine initializes the global control knobs for
** all routines in this file.
** Return: none
** Exceptions: none
** History: Fri Dec 14 10:50:12 1990, DSJ, Created.
*/
MakeNormMethod();
MakeCharNormRange();
MakeMinNormScaleX();
MakeMaxNormScaleX();
MakeMinNormScaleY();
MakeMaxNormScaleY();
} /* InitMFOutlineVars */
/*---------------------------------------------------------------------------*/
void MarkDirectionChanges(MFOUTLINE Outline) {
/*
** Parameters:
** Outline micro-feature outline to analyze
** Globals: none
** Operation:
** This routine searches thru the specified outline and finds
** the points at which the outline changes direction. These
** points are then marked as "extremities". This routine is
** used as an alternative to FindExtremities(). It forces the
** endpoints of the microfeatures to be at the direction
** changes rather than at the midpoint between direction
** changes.
** Return: none
** Exceptions: none
** History: 6/29/90, DSJ, Created.
** Parameters:
** Outline micro-feature outline to analyze
** Globals: none
** Operation:
** This routine searches thru the specified outline and finds
** the points at which the outline changes direction. These
** points are then marked as "extremities". This routine is
** used as an alternative to FindExtremities(). It forces the
** endpoints of the microfeatures to be at the direction
** changes rather than at the midpoint between direction
** changes.
** Return: none
** Exceptions: none
** History: 6/29/90, DSJ, Created.
*/
MFOUTLINE Current;
MFOUTLINE Last;
@ -568,14 +503,14 @@ void MarkDirectionChanges(MFOUTLINE Outline) {
/*---------------------------------------------------------------------------*/
MFEDGEPT *NewEdgePoint() {
/*
** Parameters: none
** Globals: none
** Operation:
** This routine allocates and returns a new edge point for
** a micro-feature outline.
** Return: New edge point.
** Exceptions: none
** History: 7/21/89, DSJ, Created.
** Parameters: none
** Globals: none
** Operation:
** This routine allocates and returns a new edge point for
** a micro-feature outline.
** Return: New edge point.
** Exceptions: none
** History: 7/21/89, DSJ, Created.
*/
return ((MFEDGEPT *) alloc_struct (sizeof (MFEDGEPT), "MFEDGEPT"));
@ -585,18 +520,18 @@ MFEDGEPT *NewEdgePoint() {
/*---------------------------------------------------------------------------*/
MFOUTLINE NextExtremity(MFOUTLINE EdgePoint) {
/*
** Parameters:
** EdgePoint start search from this point
** Globals: none
** Operation:
** This routine returns the next point in the micro-feature
** outline that is an extremity. The search starts after
** EdgePoint. The routine assumes that the outline being
** searched is not a degenerate outline (i.e. it must have
** 2 or more edge points).
** Return: Next extremity in the outline after EdgePoint.
** Exceptions: none
** History: 7/26/89, DSJ, Created.
** Parameters:
** EdgePoint start search from this point
** Globals: none
** Operation:
** This routine returns the next point in the micro-feature
** outline that is an extremity. The search starts after
** EdgePoint. The routine assumes that the outline being
** searched is not a degenerate outline (i.e. it must have
** 2 or more edge points).
** Return: Next extremity in the outline after EdgePoint.
** Exceptions: none
** History: 7/26/89, DSJ, Created.
*/
EdgePoint = NextPointAfter (EdgePoint);
while (!PointAt (EdgePoint)->ExtremityMark)
@ -612,24 +547,24 @@ void NormalizeOutline(MFOUTLINE Outline,
LINE_STATS *LineStats,
FLOAT32 XOrigin) {
/*
** Parameters:
** Outline outline to be normalized
** LineStats statistics for text line normalization
** XOrigin x-origin of text
** Globals: none
** Operation:
** This routine normalizes the coordinates of the specified
** outline so that the outline is deskewed down to the
** baseline, translated so that x=0 is at XOrigin, and scaled
** so that the height of a character cell from descender to
** ascender is 1. Of this height, 0.25 is for the descender,
** 0.25 for the ascender, and 0.5 for the x-height. The
** y coordinate of the baseline is 0.
** Return: none
** Exceptions: none
** History: 8/2/89, DSJ, Created.
** 10/23/89, DSJ, Added ascender/descender stretching.
** 11/89, DSJ, Removed ascender/descender stretching.
** Parameters:
** Outline outline to be normalized
** LineStats statistics for text line normalization
** XOrigin x-origin of text
** Globals: none
** Operation:
** This routine normalizes the coordinates of the specified
** outline so that the outline is deskewed down to the
** baseline, translated so that x=0 is at XOrigin, and scaled
** so that the height of a character cell from descender to
** ascender is 1. Of this height, 0.25 is for the descender,
** 0.25 for the ascender, and 0.5 for the x-height. The
** y coordinate of the baseline is 0.
** Return: none
** Exceptions: none
** History: 8/2/89, DSJ, Created.
** 10/23/89, DSJ, Added ascender/descender stretching.
** 11/89, DSJ, Removed ascender/descender stretching.
*/
MFEDGEPT *Current;
MFOUTLINE EdgePoint;
@ -674,29 +609,29 @@ void NormalizeOutlines(LIST Outlines,
FLOAT32 *XScale,
FLOAT32 *YScale) {
/*
** Parameters:
** Outlines list of outlines to be normalized
** LineStats statistics for text line normalization
** XScale x-direction scale factor used by routine
** YScale y-direction scale factor used by routine
** Globals:
** NormMethod method being used for normalization
** CharNormRange map radius of gyration to this value
** Operation: This routine normalizes every outline in Outlines
** according to the currently selected normalization method.
** It also returns the scale factors that it used to do this
** scaling. The scale factors returned represent the x and
** y sizes in the normalized coordinate system that correspond
** to 1 pixel in the original coordinate system.
** Return: none (Outlines are changed and XScale and YScale are updated)
** Exceptions: none
** History: Fri Dec 14 08:14:55 1990, DSJ, Created.
** Parameters:
** Outlines list of outlines to be normalized
** LineStats statistics for text line normalization
** XScale x-direction scale factor used by routine
** YScale y-direction scale factor used by routine
** Globals:
** classify_norm_method method being used for normalization
** classify_char_norm_range map radius of gyration to this value
** Operation: This routine normalizes every outline in Outlines
** according to the currently selected normalization method.
** It also returns the scale factors that it used to do this
** scaling. The scale factors returned represent the x and
** y sizes in the normalized coordinate system that correspond
** to 1 pixel in the original coordinate system.
** Return: none (Outlines are changed and XScale and YScale are updated)
** Exceptions: none
** History: Fri Dec 14 08:14:55 1990, DSJ, Created.
*/
MFOUTLINE Outline;
OUTLINE_STATS OutlineStats;
FLOAT32 BaselineScale;
switch (NormMethod) {
switch (classify_norm_method) {
case character:
ComputeOutlineStats(Outlines, &OutlineStats);
@ -705,14 +640,15 @@ void NormalizeOutlines(LIST Outlines,
*XScale = *YScale = BaselineScale = ComputeScaleFactor (LineStats);
*XScale *= OutlineStats.Ry;
*YScale *= OutlineStats.Rx;
if (*XScale < MinNormScaleX)
*XScale = MinNormScaleX;
if (*YScale < MinNormScaleY)
*YScale = MinNormScaleY;
if (*XScale > MaxNormScaleX && *YScale <= MaxNormScaleY)
*XScale = MaxNormScaleX;
*XScale = CharNormRange * BaselineScale / *XScale;
*YScale = CharNormRange * BaselineScale / *YScale;
if (*XScale < classify_min_norm_scale_x)
*XScale = classify_min_norm_scale_x;
if (*YScale < classify_min_norm_scale_y)
*YScale = classify_min_norm_scale_y;
if (*XScale > classify_max_norm_scale_x &&
*YScale <= classify_max_norm_scale_y)
*XScale = classify_max_norm_scale_x;
*XScale = classify_char_norm_range * BaselineScale / *XScale;
*YScale = classify_char_norm_range * BaselineScale / *YScale;
iterate(Outlines) {
Outline = (MFOUTLINE) first_node (Outlines);
@ -736,41 +672,40 @@ void NormalizeOutlines(LIST Outlines,
/*---------------------------------------------------------------------------*/
void SettupBlobConversion(TBLOB *Blob) {
/*
** Parameters:
** Blob blob that is to be converted
** Globals:
** BlobCenter center of blob to be converted
** Operation: Compute the center of the blob's bounding box and save
** it in a global variable. This routine must be called before
** any calls to ConvertOutline. It must be called once per
** blob.
** Return: none
** Exceptions: none
** History: Thu May 17 11:06:17 1990, DSJ, Created.
** Parameters:
** Blob blob that is to be converted
** Globals:
** BlobCenter center of blob to be converted
** Operation: Compute the center of the blob's bounding box and save
** it in a global variable. This routine must be called before
** any calls to ConvertOutline. It must be called once per
** blob.
** Return: none
** Exceptions: none
** History: Thu May 17 11:06:17 1990, DSJ, Created.
*/
ComputeBlobCenter(Blob, &BlobCenter);
} /* SettupBlobConversion */
/*---------------------------------------------------------------------------*/
void SmearExtremities(MFOUTLINE Outline, FLOAT32 XScale, FLOAT32 YScale) {
/*
** Parameters:
** Outline outline whose extremities are to be smeared
** XScale factor used to normalize outline in x dir
** YScale factor used to normalize outline in y dir
** Globals: none
** Operation:
** This routine smears the extremities of the specified outline.
** It does this by adding a random number between
** -0.5 and 0.5 pixels (that is why X/YScale are needed) to
** the x and y position of the point. This is done so that
** the discrete nature of the original scanned image does not
** affect the statistical clustering used during training.
** Return: none
** Exceptions: none
** History: 1/11/90, DSJ, Created.
** Parameters:
** Outline outline whose extremities are to be smeared
** XScale factor used to normalize outline in x dir
** YScale factor used to normalize outline in y dir
** Globals: none
** Operation:
** This routine smears the extremities of the specified outline.
** It does this by adding a random number between
** -0.5 and 0.5 pixels (that is why X/YScale are needed) to
** the x and y position of the point. This is done so that
** the discrete nature of the original scanned image does not
** affect the statistical clustering used during training.
** Return: none
** Exceptions: none
** History: 1/11/90, DSJ, Created.
*/
MFEDGEPT *Current;
MFOUTLINE EdgePoint;
@ -807,18 +742,18 @@ void SmearExtremities(MFOUTLINE Outline, FLOAT32 XScale, FLOAT32 YScale) {
/*---------------------------------------------------------------------------*/
void ChangeDirection(MFOUTLINE Start, MFOUTLINE End, DIRECTION Direction) {
/*
** Parameters:
** Start, End defines segment of outline to be modified
** Direction new direction to assign to segment
** Globals: none
** Operation: Change the direction of every vector in the specified
** outline segment to Direction. The segment to be changed
** starts at Start and ends at End. Note that the previous
** direction of End must also be changed to reflect the
** change in direction of the point before it.
** Return: none
** Exceptions: none
** History: Fri May 4 10:42:04 1990, DSJ, Created.
** Parameters:
** Start, End defines segment of outline to be modified
** Direction new direction to assign to segment
** Globals: none
** Operation: Change the direction of every vector in the specified
** outline segment to Direction. The segment to be changed
** starts at Start and ends at End. Note that the previous
** direction of End must also be changed to reflect the
** change in direction of the point before it.
** Return: none
** Exceptions: none
** History: Fri May 4 10:42:04 1990, DSJ, Created.
*/
MFOUTLINE Current;
@ -837,17 +772,17 @@ void CharNormalizeOutline(MFOUTLINE Outline,
FLOAT32 XScale,
FLOAT32 YScale) {
/*
** Parameters:
** Outline outline to be character normalized
** XCenter, YCenter center point for normalization
** XScale, YScale scale factors for normalization
** Globals: none
** Operation: This routine normalizes each point in Outline by
** translating it to the specified center and scaling it
** anisotropically according to the given scale factors.
** Return: none
** Exceptions: none
** History: Fri Dec 14 10:27:11 1990, DSJ, Created.
** Parameters:
** Outline outline to be character normalized
** XCenter, YCenter center point for normalization
** XScale, YScale scale factors for normalization
** Globals: none
** Operation: This routine normalizes each point in Outline by
** translating it to the specified center and scaling it
** anisotropically according to the given scale factors.
** Return: none
** Exceptions: none
** History: Fri Dec 14 10:27:11 1990, DSJ, Created.
*/
MFOUTLINE First, Current;
MFEDGEPT *CurrentPoint;
@ -877,25 +812,25 @@ void ComputeDirection(MFEDGEPT *Start,
FLOAT32 MinSlope,
FLOAT32 MaxSlope) {
/*
** Parameters:
** Start starting point to compute direction from
** Finish finishing point to compute direction to
** MinSlope slope below which lines are horizontal
** MaxSlope slope above which lines are vertical
** Globals: none
** Operation:
** This routine computes the slope from Start to Finish and
** and then computes the approximate direction of the line
** segment from Start to Finish. The direction is quantized
** into 8 buckets:
** N, S, E, W, NE, NW, SE, SW
** Both the slope and the direction are then stored into
** the appropriate fields of the Start edge point. The
** direction is also stored into the PreviousDirection field
** of the Finish edge point.
** Return: none
** Exceptions: none
** History: 7/25/89, DSJ, Created.
** Parameters:
** Start starting point to compute direction from
** Finish finishing point to compute direction to
** MinSlope slope below which lines are horizontal
** MaxSlope slope above which lines are vertical
** Globals: none
** Operation:
** This routine computes the slope from Start to Finish and
** and then computes the approximate direction of the line
** segment from Start to Finish. The direction is quantized
** into 8 buckets:
** N, S, E, W, NE, NW, SE, SW
** Both the slope and the direction are then stored into
** the appropriate fields of the Start edge point. The
** direction is also stored into the PreviousDirection field
** of the Finish edge point.
** Return: none
** Exceptions: none
** History: 7/25/89, DSJ, Created.
*/
FVECTOR Delta;
@ -951,16 +886,16 @@ void ComputeDirection(MFEDGEPT *Start,
/*---------------------------------------------------------------------------*/
void FinishOutlineStats(register OUTLINE_STATS *OutlineStats) {
/*
** Parameters:
** OutlineStats statistics about a set of outlines
** Globals: none
** Operation: Use the preliminary statistics accumulated in OutlineStats
** to compute the final statistics.
** (see Dan Johnson's Tesseract lab
** notebook #2, pgs. 74-78).
** Return: none
** Exceptions: none
** History: Fri Dec 14 10:13:36 1990, DSJ, Created.
** Parameters:
** OutlineStats statistics about a set of outlines
** Globals: none
** Operation: Use the preliminary statistics accumulated in OutlineStats
** to compute the final statistics.
** (see Dan Johnson's Tesseract lab
** notebook #2, pgs. 74-78).
** Return: none
** Exceptions: none
** History: Fri Dec 14 10:13:36 1990, DSJ, Created.
*/
OutlineStats->x = 0.5 * OutlineStats->My / OutlineStats->L;
OutlineStats->y = 0.5 * OutlineStats->Mx / OutlineStats->L;
@ -991,14 +926,14 @@ void FinishOutlineStats(register OUTLINE_STATS *OutlineStats) {
/*---------------------------------------------------------------------------*/
void InitOutlineStats(OUTLINE_STATS *OutlineStats) {
/*
** Parameters:
** OutlineStats stats data structure to be initialized
** Globals: none
** Operation: Initialize the outline statistics data structure so
** that it is ready to start accumulating statistics.
** Return: none
** Exceptions: none
** History: Fri Dec 14 08:55:22 1990, DSJ, Created.
** Parameters:
** OutlineStats stats data structure to be initialized
** Globals: none
** Operation: Initialize the outline statistics data structure so
** that it is ready to start accumulating statistics.
** Return: none
** Exceptions: none
** History: Fri Dec 14 08:55:22 1990, DSJ, Created.
*/
OutlineStats->Mx = 0.0;
OutlineStats->My = 0.0;
@ -1015,17 +950,17 @@ void InitOutlineStats(OUTLINE_STATS *OutlineStats) {
/*---------------------------------------------------------------------------*/
MFOUTLINE NextDirectionChange(MFOUTLINE EdgePoint) {
/*
** Parameters:
** EdgePoint start search from this point
** Globals: none
** Operation:
** This routine returns the next point in the micro-feature
** outline that has a direction different than EdgePoint. The
** routine assumes that the outline being searched is not a
** degenerate outline (i.e. it must have 2 or more edge points).
** Return: Point of next direction change in micro-feature outline.
** Exceptions: none
** History: 7/25/89, DSJ, Created.
** Parameters:
** EdgePoint start search from this point
** Globals: none
** Operation:
** This routine returns the next point in the micro-feature
** outline that has a direction different than EdgePoint. The
** routine assumes that the outline being searched is not a
** degenerate outline (i.e. it must have 2 or more edge points).
** Return: Point of next direction change in micro-feature outline.
** Exceptions: none
** History: 7/25/89, DSJ, Created.
*/
DIRECTION InitialDirection;
@ -1046,25 +981,25 @@ void UpdateOutlineStats(register OUTLINE_STATS *OutlineStats,
register FLOAT32 y1,
register FLOAT32 y2) {
/*
** Parameters:
** OutlineStats statistics to add this segment to
** x1, y1, x2, y2 segment to be added to statistics
** Globals: none
** Operation: This routine adds the statistics for the specified
** line segment to OutlineStats. The statistics that are
** kept are:
** sum of length of all segments
** sum of 2*Mx for all segments
** sum of 2*My for all segments
** sum of 2*Mx*(y1+y2) - L*y1*y2 for all segments
** sum of 2*My*(x1+x2) - L*x1*x2 for all segments
** These numbers, once collected can later be used to easily
** compute the center of mass, first and second moments,
** and radii of gyration. (see Dan Johnson's Tesseract lab
** notebook #2, pgs. 74-78).
** Return: none
** Exceptions: none
** History: Fri Dec 14 08:59:17 1990, DSJ, Created.
** Parameters:
** OutlineStats statistics to add this segment to
** x1, y1, x2, y2 segment to be added to statistics
** Globals: none
** Operation: This routine adds the statistics for the specified
** line segment to OutlineStats. The statistics that are
** kept are:
** sum of length of all segments
** sum of 2*Mx for all segments
** sum of 2*My for all segments
** sum of 2*Mx*(y1+y2) - L*y1*y2 for all segments
** sum of 2*My*(x1+x2) - L*x1*x2 for all segments
** These numbers, once collected can later be used to easily
** compute the center of mass, first and second moments,
** and radii of gyration. (see Dan Johnson's Tesseract lab
** notebook #2, pgs. 74-78).
** Return: none
** Exceptions: none
** History: Fri Dec 14 08:59:17 1990, DSJ, Created.
*/
register FLOAT64 L;
register FLOAT64 Mx2;

View File

@ -26,6 +26,7 @@
#include "fpoint.h"
#include "fxdefs.h"
#include "baseline.h"
#include "varable.h"
#define NORMAL_X_HEIGHT (0.5)
#define NORMAL_BASELINE (0.0)
@ -38,13 +39,7 @@ typedef enum {
DIRECTION;
/*
typedef enum
{
False, True
}
BOOLEAN;
*/
typedef struct
{
FPOINT Point;
@ -88,7 +83,24 @@ NORM_METHOD;
/*----------------------------------------------------------------------------
Variables
------------------------------------------------------------------------------*/
extern int NormMethod;
/* control knobs used to control normalization of outlines */
extern INT_VAR_H(classify_norm_method, character,
"Normalization Method ...");
/* PREV DEFAULT "baseline" */
extern double_VAR_H(classify_char_norm_range, 0.2,
"Character Normalization Range ...");
extern double_VAR_H(classify_min_norm_scale_x, 0.0,
"Min char x-norm scale ...");
/* PREV DEFAULT 0.1 */
extern double_VAR_H(classify_max_norm_scale_x, 0.325,
"Max char x-norm scale ...");
/* PREV DEFAULT 0.3 */
extern double_VAR_H(classify_min_norm_scale_y, 0.0,
"Min char y-norm scale ...");
/* PREV DEFAULT 0.1 */
extern double_VAR_H(classify_max_norm_scale_y, 0.325,
"Max char y-norm scale ...");
/* PREV DEFAULT 0.3 */
/**----------------------------------------------------------------------------
Macros
@ -100,7 +112,7 @@ extern int NormMethod;
/* macro for computing the scale factor to use to normalize characters */
#define ComputeScaleFactor(L) \
(NORMAL_X_HEIGHT / ((is_baseline_normalized ())? \
(NORMAL_X_HEIGHT / ((classify_baseline_normalized)? \
(BASELINE_SCALE): \
((L)->xheight)))
@ -111,17 +123,8 @@ extern int NormMethod;
#define MakeOutlineCircular(O) (set_rest (last (O), (O)))
/* macros for manipulating micro-feature outline edge points */
//#define PositionOf(P) ((P)->Point)
//#define XPositionOf(P) ((P)->Point.x)
//#define YPositionOf(P) ((P)->Point.y)
//#define DirectionOf(P) ((P)->Direction)
//#define PreviousDirectionOf(P) ((P)->PreviousDirection)
#define ClearMark(P) ((P)->ExtremityMark = FALSE)
#define MarkPoint(P) ((P)->ExtremityMark = TRUE)
//#define IsExtremity(P) ((P)->ExtremityMark)
//#define NotExtremity(P) (!(P->ExtremityMark))
//#define IsVisible(E) (! (E->Hidden))
//#define IsHidden(E) ((E)->Hidden)
/**----------------------------------------------------------------------------
Public Function Prototypes
@ -148,8 +151,6 @@ void FreeMFOutline(void *agr); //MFOUTLINE Outline)
void FreeOutlines(LIST Outlines);
void InitMFOutlineVars();
void MarkDirectionChanges(MFOUTLINE Outline);
MFEDGEPT *NewEdgePoint();
@ -197,81 +198,4 @@ void UpdateOutlineStats(register OUTLINE_STATS *OutlineStats,
register FLOAT32 y1,
register FLOAT32 y2);
/*
#if defined(__STDC__) || defined(__cplusplus)
# define _ARGS(s) s
#else
# define _ARGS(s) ()
#endif*/
/* mfoutline.c
void ComputeBlobCenter
_ARGS((BLOB *Blob,
TPOINT *BlobCenter));
LIST ConvertBlob
_ARGS((BLOB *Blob));
MFOUTLINE ConvertOutline
_ARGS((TESSLINE *Outline));
LIST ConvertOutlines
_ARGS((TESSLINE *Outline,
LIST ConvertedOutlines,
OUTLINETYPE OutlineType));
void ComputeOutlineStats
_ARGS((LIST Outlines,
OUTLINE_STATS *OutlineStats));
void FilterEdgeNoise
_ARGS((MFOUTLINE Outline,
FLOAT32 NoiseSegmentLength));
void FindDirectionChanges
_ARGS((MFOUTLINE Outline,
FLOAT32 MinSlope,
FLOAT32 MaxSlope));
void FreeMFOutline
_ARGS((MFOUTLINE Outline));
void FreeOutlines
_ARGS((LIST Outlines));
void InitMFOutlineVars
_ARGS((void));
void MarkDirectionChanges
_ARGS((MFOUTLINE Outline));
MFEDGEPT *NewEdgePoint
_ARGS((void));
MFOUTLINE NextExtremity
_ARGS((MFOUTLINE EdgePoint));
void NormalizeOutline
_ARGS((MFOUTLINE Outline,
LINE_STATS *LineStats,
FLOAT32 XOrigin));
void NormalizeOutlines
_ARGS((LIST Outlines,
LINE_STATS *LineStats));
void SettupBlobConversion
_ARGS((BLOB *Blob));
void SmearExtremities
_ARGS((MFOUTLINE Outline,
FLOAT32 XScale,
FLOAT32 YScale));
#undef _ARGS
*/
/**----------------------------------------------------------------------------
Global Data Definitions and Declarations
----------------------------------------------------------------------------**/
extern int NormMethod; /* normalized method currently selected */
#endif

View File

@ -19,24 +19,25 @@
Include Files and Type Defines
----------------------------------------------------------------------------**/
#include "mfdefs.h"
#include "variables.h"
#include "sigmenu.h"
#include "mfoutline.h"
#include "clusttool.h" //NEEDED
#include "const.h"
#include "intfx.h"
#include "varable.h"
#include <math.h>
/* default values for tunable knobs */
/**----------------------------------------------------------------------------
Variables
----------------------------------------------------------------------------**/
/* old numbers corresponded to 10.0 degrees and 80.0 degrees */
/* PREV DEFAULT 0.176326981 approx. 10.0 degrees */
#define MIN_SLOPE 0.414213562
/* PREV DEFAULT 5.671281820 approx. 80.0 degrees */
#define MAX_SLOPE 2.414213562
/* no noise filtering */
#define NOISE_SEGMENT_LENGTH (0.00)
/* no feature splitting */
#define MAX_FEATURE_LENGTH (MAXFLOAT)
double_VAR(classify_min_slope, 0.414213562,
"Slope below which lines are called horizontal");
double_VAR(classify_max_slope, 2.414213562,
"Slope above which lines are called vertical");
double_VAR(classify_noise_segment_length, 0.00,
"Length below which outline segments are treated as noise");
/**----------------------------------------------------------------------------
Macros
@ -58,77 +59,9 @@ MICROFEATURE ExtractMicroFeature(MFOUTLINE Start, MFOUTLINE End);
void SmearBulges(MICROFEATURES MicroFeatures, FLOAT32 XScale, FLOAT32 YScale);
/*
#if defined(__STDC__) || defined(__cplusplus)
# define _ARGS(s) s
#else
# define _ARGS(s) ()
#endif*/
/* /users/danj/wiseowl/src/danj/microfeatures/mfx.c
void ComputeBulges
_ARGS((MFOUTLINE Start,
MFOUTLINE End,
MICROFEATURE MicroFeature));
FLOAT32 ComputeOrientation
_ARGS((MFEDGEPT *Start,
MFEDGEPT *End));
MICROFEATURES ConvertToMicroFeatures
_ARGS((MFOUTLINE Outline,
MICROFEATURES MicroFeatures));
MICROFEATURE ExtractMicroFeature
_ARGS((MFOUTLINE Start,
MFOUTLINE End));
void SmearBulges
_ARGS((MICROFEATURES MicroFeatures,
FLOAT32 XScale,
FLOAT32 YScale));
#undef _ARGS
*/
/**----------------------------------------------------------------------------
Global Data Definitions and Declarations
----------------------------------------------------------------------------**/
/* tuning knobs that can be adjusted without recompilation */
static FLOAT32 MinSlope;
static FLOAT32 MaxSlope;
static FLOAT32 NoiseSegmentLength;
/**----------------------------------------------------------------------------
Public Code
----------------------------------------------------------------------------**/
/*---------------------------------------------------------------------------*/
void InitMicroFxVars() {
/*
** Parameters: none
** Globals:
** MinSlope slope below which lines are called horizontal
** MaxSlope slope above which lines are called vertical
** NoiseSegmentLength length below which outline segments
** are treated as noise
** MaxFeatureLength length above which a feature will
** be split into 2 equal pieces
** ExtremityMode controls how extremities are defined
** XHeightAdjust allows xheight of line to be adjusted
** Operation: Initialize the micro-feature extractor variables (knobs)
** that can be tuned without recompiling.
** Return: none
** Exceptions: none
** History: Mon May 14 11:24:40 1990, DSJ, Created.
*/
VALUE dummy;
float_variable (MinSlope, "MinSlope", MIN_SLOPE);
float_variable (MaxSlope, "MaxSlope", MAX_SLOPE);
float_variable (NoiseSegmentLength, "NoiseSegmentLength",
NOISE_SEGMENT_LENGTH);
} /* InitMicroFxVars */
/*---------------------------------------------------------------------------*/
CHAR_FEATURES BlobMicroFeatures(TBLOB *Blob, LINE_STATS *LineStats) {
@ -136,8 +69,6 @@ CHAR_FEATURES BlobMicroFeatures(TBLOB *Blob, LINE_STATS *LineStats) {
** Parameters:
** Blob blob to extract micro-features from
** LineStats statistics for text line normalization
** Globals:
** XHeightAdjust used for manually adjusting xheight
** Operation:
** This routine extracts micro-features from the specified
** blob and returns a list of the micro-features. All
@ -159,7 +90,8 @@ CHAR_FEATURES BlobMicroFeatures(TBLOB *Blob, LINE_STATS *LineStats) {
if (Blob != NULL) {
Outlines = ConvertBlob (Blob);
// NormalizeOutlines(Outlines, LineStats, &XScale, &YScale);
ExtractIntFeat(Blob, blfeatures, cnfeatures, &results);
if (!ExtractIntFeat(Blob, blfeatures, cnfeatures, &results))
return NULL;
XScale = 0.2f / results.Ry;
YScale = 0.2f / results.Rx;
@ -174,8 +106,8 @@ CHAR_FEATURES BlobMicroFeatures(TBLOB *Blob, LINE_STATS *LineStats) {
RemainingOutlines = Outlines;
iterate(RemainingOutlines) {
Outline = (MFOUTLINE) first_node (RemainingOutlines);
FindDirectionChanges(Outline, MinSlope, MaxSlope);
FilterEdgeNoise(Outline, NoiseSegmentLength);
FindDirectionChanges(Outline, classify_min_slope, classify_max_slope);
FilterEdgeNoise(Outline, classify_noise_segment_length);
MarkDirectionChanges(Outline);
SmearExtremities(Outline, XScale, YScale);
MicroFeatures = ConvertToMicroFeatures (Outline, MicroFeatures);
@ -197,8 +129,8 @@ CHAR_FEATURES BlobMicroFeatures(TBLOB *Blob, LINE_STATS *LineStats) {
**********************************************************************/
#define angle_of(x1,y1,x2,y2) \
((x2-x1) ? \
(atan2 (y2-y1, x2-x1)) : \
((y2<y1) ? (- PI / 2.0) : (PI / 2.0))) \
(atan2 (y2-y1, x2-x1)) : \
((y2<y1) ? (- PI / 2.0) : (PI / 2.0))) \
/**********************************************************************
@ -257,15 +189,16 @@ void ComputeBulges(MFOUTLINE Start, MFOUTLINE End, MICROFEATURE MicroFeature) {
TranslateMatrix (&Matrix, -Origin->Point.x, -Origin->Point.y);
SegmentEnd = Start;
FillPoint (CurrentPoint, 0, 0);
CurrentPoint.x = 0.0f;
CurrentPoint.y = 0.0f;
BulgePosition = MicroFeature[MFLENGTH] / 3;
CopyPoint(CurrentPoint, LastPoint);
LastPoint = CurrentPoint;
while (CurrentPoint.x < BulgePosition) {
SegmentStart = SegmentEnd;
SegmentEnd = NextPointAfter (SegmentStart);
CopyPoint(CurrentPoint, LastPoint);
LastPoint = CurrentPoint;
MapPoint (&Matrix, PointAt (SegmentEnd)->Point, CurrentPoint);
MapPoint(&Matrix, PointAt(SegmentEnd)->Point, &CurrentPoint);
}
MicroFeature[FIRSTBULGE] =
XIntersectionOf(LastPoint, CurrentPoint, BulgePosition);
@ -276,12 +209,12 @@ void ComputeBulges(MFOUTLINE Start, MFOUTLINE End, MICROFEATURE MicroFeature) {
// CurrentPoint will not change. (Which would cause to output nan
// for the SecondBulge.)
if (CurrentPoint.x < BulgePosition)
CopyPoint(CurrentPoint, LastPoint);
LastPoint = CurrentPoint;
while (CurrentPoint.x < BulgePosition) {
SegmentStart = SegmentEnd;
SegmentEnd = NextPointAfter (SegmentStart);
CopyPoint(CurrentPoint, LastPoint);
MapPoint (&Matrix, PointAt (SegmentEnd)->Point, CurrentPoint);
LastPoint = CurrentPoint;
MapPoint(&Matrix, PointAt(SegmentEnd)->Point, &CurrentPoint);
}
MicroFeature[SECONDBULGE] =
XIntersectionOf(LastPoint, CurrentPoint, BulgePosition);
@ -314,8 +247,7 @@ FLOAT32 ComputeOrientation(MFEDGEPT *Start, MFEDGEPT *End) {
*/
FLOAT32 Orientation;
Orientation = NormalizeAngle (AngleFrom (Start->Point,
End->Point));
Orientation = NormalizeAngle (AngleFrom (Start->Point, End->Point));
/* ensure that round-off errors do not put circular param out of range */
if ((Orientation < 0) || (Orientation >= 1))
@ -391,8 +323,7 @@ MICROFEATURE ExtractMicroFeature(MFOUTLINE Start, MFOUTLINE End) {
NewFeature[XPOSITION] = AverageOf (P1->Point.x, P2->Point.x);
NewFeature[YPOSITION] = AverageOf (P1->Point.y, P2->Point.y);
NewFeature[MFLENGTH] = DistanceBetween (P1->Point, P2->Point);
NewFeature[ORIENTATION] =
NormalizedAngleFrom (&((P1)->Point), &((P2)->Point), 1.0);
NewFeature[ORIENTATION] = NormalizedAngleFrom(&P1->Point, &P2->Point, 1.0);
ComputeBulges(Start, End, NewFeature);
return (NewFeature);
} /* ExtractMicroFeature */
@ -403,8 +334,8 @@ void SmearBulges(MICROFEATURES MicroFeatures, FLOAT32 XScale, FLOAT32 YScale) {
/*
** Parameters:
** MicroFeatures features to be smeared
** XScale # of normalized units per pixel in x dir
** YScale # of normalized units per pixel in y dir
** XScale # of normalized units per pixel in x dir
** YScale # of normalized units per pixel in y dir
** Globals: none
** Operation: Add a random amount to each bulge parameter of each
** feature. The amount added is between -0.5 pixels and
@ -423,8 +354,8 @@ void SmearBulges(MICROFEATURES MicroFeatures, FLOAT32 XScale, FLOAT32 YScale) {
iterate(MicroFeatures) {
MicroFeature = NextFeatureOf (MicroFeatures);
Cos = fabs (cos (2.0 * PI * MicroFeature[ORIENTATION]));
Sin = fabs (sin (2.0 * PI * MicroFeature[ORIENTATION]));
Cos = fabs(cos(2.0 * PI * MicroFeature[ORIENTATION]));
Sin = fabs(sin(2.0 * PI * MicroFeature[ORIENTATION]));
Scale = YScale * Cos + XScale * Sin;
MinSmear = -0.5 * Scale / (BULGENORMALIZER * MicroFeature[MFLENGTH]);

View File

@ -22,31 +22,23 @@
Include Files and Type Defines
----------------------------------------------------------------------------**/
#include "fxdefs.h"
#include "varable.h"
/**----------------------------------------------------------------------------
Variables
----------------------------------------------------------------------------**/
/* old numbers corresponded to 10.0 degrees and 80.0 degrees */
extern double_VAR_H(classify_min_slope, 0.414213562,
"Slope below which lines are called horizontal");
extern double_VAR_H(classify_max_slope, 2.414213562,
"Slope above which lines are called vertical");
extern double_VAR_H(classify_noise_segment_length, 0.00,
"Length below which outline segments"
"are treated as noise");
extern FLOAT32 MinSlope;
extern FLOAT32 MaxSlope;
/**----------------------------------------------------------------------------
Public Function Prototypes
----------------------------------------------------------------------------**/
void InitMicroFxVars();
CHAR_FEATURES BlobMicroFeatures(TBLOB *Blob, LINE_STATS *LineStats);
CHAR_FEATURES BlobMicroFeatures(TBLOB *Blob, LINE_STATS *LineStats);
/*
#if defined(__STDC__) || defined(__cplusplus)
# define _ARGS(s) s
#else
# define _ARGS(s) ()
#endif*/
/* mfx.c
void InitMicroFxVars
_ARGS((void));
CHAR_FEATURES BlobMicroFeatures
_ARGS((BLOB *Blob,
LINE_STATS *LineStats));
#undef _ARGS
*/
#endif

View File

@ -19,28 +19,29 @@
Include Files and Type Defines
----------------------------------------------------------------------------**/
#include "normmatch.h"
#include "clusttool.h"
#include "normfeat.h"
#include "debug.h"
#include "const.h"
#include "efio.h"
#include "emalloc.h"
#include "globals.h"
#include "scanutils.h"
#include <stdio.h>
#include <math.h>
/* define default filenames for training data */
#define NORM_PROTO_FILE "normproto"
#include "classify.h"
#include "clusttool.h"
#include "const.h"
#include "efio.h"
#include "emalloc.h"
#include "globals.h"
#include "helpers.h"
#include "normfeat.h"
#include "scanutils.h"
#include "unicharset.h"
#include "varable.h"
typedef struct
struct NORM_PROTOS
{
int NumParams;
PARAM_DESC *ParamDesc;
LIST* Protos;
int NumProtos;
} NORM_PROTOS;
};
/**----------------------------------------------------------------------------
Private Function Prototypes
@ -55,24 +56,20 @@ void PrintNormMatch(FILE *File,
NORM_PROTOS *ReadNormProtos(FILE *File);
/**----------------------------------------------------------------------------
Global Data Definitions and Declarations
Variables
----------------------------------------------------------------------------**/
/* global data structure to hold char normalization protos */
static NORM_PROTOS *NormProtos;
/* name of file containing char normalization protos */
static const char *NormProtoFile = NORM_PROTO_FILE;
/* control knobs used to control the normalization adjustment process */
make_float_var (NormAdjMidpoint, 32.0, MakeNormAdjMidpoint,
15, 16, SetNormAdjMidpoint, "Norm adjust midpoint ...")
make_float_var (NormAdjCurl, 2.0, MakeNormAdjCurl,
15, 17, SetNormAdjCurl, "Norm adjust curl ...")
double_VAR(classify_norm_adj_midpoint, 32.0, "Norm adjust midpoint ...");
double_VAR(classify_norm_adj_curl, 2.0, "Norm adjust curl ...");
/**----------------------------------------------------------------------------
Public Code
----------------------------------------------------------------------------**/
/*---------------------------------------------------------------------------*/
FLOAT32 ComputeNormMatch(CLASS_ID ClassId, FEATURE Feature, BOOL8 DebugMatch) {
namespace tesseract {
FLOAT32 Classify::ComputeNormMatch(CLASS_ID ClassId, FEATURE Feature,
BOOL8 DebugMatch) {
/*
** Parameters:
** ClassId id of class to match against
@ -139,32 +136,7 @@ FLOAT32 ComputeNormMatch(CLASS_ID ClassId, FEATURE Feature, BOOL8 DebugMatch) {
return (1.0 - NormEvidenceOf (BestMatch));
} /* ComputeNormMatch */
/*---------------------------------------------------------------------------*/
void GetNormProtos() {
/*
** Parameters: none
** Globals:
** NormProtoFile name of file containing normalization protos
** NormProtos global data structure to hold protos
** Operation: This routine reads in a set of character normalization
** protos from NormProtoFile and places them into NormProtos.
** Return: none
** Exceptions: none
** History: Wed Dec 19 16:24:25 1990, DSJ, Created.
*/
FILE *File;
STRING name;
name = language_data_path_prefix;
name += NormProtoFile;
File = Efopen (name.string(), "r");
NormProtos = ReadNormProtos (File);
fclose(File);
} /* GetNormProtos */
void FreeNormProtos() {
void Classify::FreeNormProtos() {
if (NormProtos != NULL) {
for (int i = 0; i < NormProtos->NumProtos; i++)
FreeProtoList(&NormProtos->Protos[i]);
@ -174,28 +146,7 @@ void FreeNormProtos() {
NormProtos = NULL;
}
}
/*---------------------------------------------------------------------------*/
void InitNormProtoVars() {
/*
** Parameters: none
** Globals:
** NormProtoFile filename for normalization protos
** Operation: Initialize the control variables for the normalization
** matcher.
** Return: none
** Exceptions: none
** History: Mon Nov 5 17:22:10 1990, DSJ, Created.
*/
VALUE dummy;
string_variable (NormProtoFile, "NormProtoFile", NORM_PROTO_FILE);
MakeNormAdjMidpoint();
MakeNormAdjCurl();
} /* InitNormProtoVars */
} // namespace tesseract
/**----------------------------------------------------------------------------
Private Code
@ -208,14 +159,14 @@ void InitNormProtoVars() {
* 1 / (1 + (NormAdj / midpoint) ^ curl)
**********************************************************************/
FLOAT32 NormEvidenceOf(register FLOAT32 NormAdj) {
NormAdj /= NormAdjMidpoint;
NormAdj /= classify_norm_adj_midpoint;
if (NormAdjCurl == 3)
if (classify_norm_adj_curl == 3)
NormAdj = NormAdj * NormAdj * NormAdj;
else if (NormAdjCurl == 2)
else if (classify_norm_adj_curl == 2)
NormAdj = NormAdj * NormAdj;
else
NormAdj = pow (NormAdj, NormAdjCurl);
NormAdj = pow(static_cast<double>(NormAdj), classify_norm_adj_curl);
return (1.0 / (1.0 + NormAdj));
}
@ -242,8 +193,8 @@ void PrintNormMatch(FILE *File,
FLOAT32 TotalMatch;
for (i = 0, TotalMatch = 0.0; i < NumParams; i++) {
ParamMatch = (Feature->Params[i] - Mean (Proto, i)) /
StandardDeviation (Proto, i);
ParamMatch = (Feature->Params[i] - Mean(Proto, i)) /
StandardDeviation(Proto, i);
fprintf (File, " %6.1f", ParamMatch);
@ -257,7 +208,8 @@ void PrintNormMatch(FILE *File,
/*---------------------------------------------------------------------------*/
NORM_PROTOS *ReadNormProtos(FILE *File) {
namespace tesseract {
NORM_PROTOS *Classify::ReadNormProtos(FILE *File, inT64 end_offset) {
/*
** Parameters:
** File open text file to read normalization protos from
@ -288,7 +240,8 @@ NORM_PROTOS *ReadNormProtos(FILE *File) {
NormProtos->ParamDesc = ReadParamDesc (File, NormProtos->NumParams);
/* read protos for each class into a separate list */
while (fscanf (File, "%s %d", unichar, &NumProtos) == 2) {
while ((end_offset < 0 || ftell(File) < end_offset) &&
fscanf(File, "%s %d", unichar, &NumProtos) == 2) {
if (unicharset.contains_unichar(unichar)) {
unichar_id = unicharset.unichar_to_id(unichar);
Protos = NormProtos->Protos[unichar_id];
@ -298,8 +251,8 @@ NORM_PROTOS *ReadNormProtos(FILE *File) {
NormProtos->Protos[unichar_id] = Protos;
} else
cprintf("Error: unichar %s in normproto file is not in unichar set.\n");
SkipNewline(File);
}
return (NormProtos);
} /* ReadNormProtos */
} // namespace tesseract

View File

@ -22,17 +22,16 @@
Include Files and Type Defines
----------------------------------------------------------------------------**/
#include "matchdefs.h"
//#include "cluster.h"
#include "ocrfeatures.h"
#include "varable.h"
/**----------------------------------------------------------------------------
Public Function Prototypes
Variables
----------------------------------------------------------------------------**/
FLOAT32 ComputeNormMatch(CLASS_ID ClassId, FEATURE Feature, BOOL8 DebugMatch);
void GetNormProtos();
void FreeNormProtos();
void InitNormProtoVars();
/* control knobs used to control the normalization adjustment process */
extern double_VAR_H(classify_norm_adj_midpoint, 32.0,
"Norm adjust midpoint ...");
extern double_VAR_H(classify_norm_adj_curl, 2.0, "Norm adjust curl ...");
#endif

View File

@ -25,6 +25,9 @@
#include "freelist.h"
#include "scanutils.h"
#include <assert.h>
#include <math.h>
/**----------------------------------------------------------------------------
Public Code
----------------------------------------------------------------------------**/
@ -45,31 +48,13 @@ BOOL8 AddFeature(FEATURE_SET FeatureSet, FEATURE Feature) {
*/
if (FeatureSet->NumFeatures >= FeatureSet->MaxNumFeatures) {
FreeFeature(Feature);
return (FALSE);
return FALSE;
}
FeatureSet->Features[FeatureSet->NumFeatures] = Feature;
FeatureSet->NumFeatures++;
return (TRUE);
FeatureSet->Features[FeatureSet->NumFeatures++] = Feature;
return TRUE;
} /* AddFeature */
/*---------------------------------------------------------------------------*/
void DefaultInitFXVars() {
/*
** Parameters: none
** Globals: none
** Operation: This routine can be used by any feature extractor which
** does not use adjustable controls.
** It does nothing.
** Return: none
** Exceptions: none
** History: Wed May 23 16:37:45 1990, DSJ, Created.
*/
} /* DefaultInitFXVars */
/*---------------------------------------------------------------------------*/
void FreeFeature(FEATURE Feature) {
/*
@ -82,7 +67,7 @@ void FreeFeature(FEATURE Feature) {
** History: Mon May 21 13:33:27 1990, DSJ, Created.
*/
if (Feature) {
c_free_struct (Feature, sizeof (FEATURE_STRUCT)
free_struct (Feature, sizeof (FEATURE_STRUCT)
+ sizeof (FLOAT32) * (Feature->Type->NumParams - 1),
"sizeof(FEATURE_STRUCT)+sizeof(FLOAT32)*(NumParamsIn(Feature)-1)");
}
@ -107,7 +92,7 @@ void FreeFeatureSet(FEATURE_SET FeatureSet) {
if (FeatureSet) {
for (i = 0; i < FeatureSet->NumFeatures; i++)
FreeFeature (FeatureSet->Features[i]);
FreeFeature(FeatureSet->Features[i]);
memfree(FeatureSet);
}
} /* FreeFeatureSet */
@ -184,6 +169,9 @@ FEATURE ReadFeature(FILE *File, FEATURE_DESC FeatureDesc) {
for (i = 0; i < Feature->Type->NumParams; i++) {
if (fscanf (File, "%f", &(Feature->Params[i])) != 1)
DoError (ILLEGAL_FEATURE_PARAM, "Illegal feature parameter spec");
#ifndef __MSW32__
assert (!isnan(Feature->Params[i]));
#endif
}
return (Feature);
@ -241,8 +229,12 @@ void WriteFeature(FILE *File, FEATURE Feature) {
*/
int i;
for (i = 0; i < Feature->Type->NumParams; i++)
fprintf (File, " %12g", Feature->Params[i]);
for (i = 0; i < Feature->Type->NumParams; i++) {
#ifndef __MSW32__
assert (!isnan(Feature->Params[i]));
#endif
fprintf (File, " %12g", Feature->Params[i]);
}
fprintf (File, "\n");
} /* WriteFeature */

View File

@ -90,7 +90,6 @@ typedef FEATURE_DESC_STRUCT *FEATURE_DESC;
typedef struct fxs
{
FX_FUNC Extractor; /* func to extract features */
VOID_FUNC InitExtractorVars; /* func to init fx controls */
} FEATURE_EXT_STRUCT;
/*----------------------------------------------------------------------
@ -111,23 +110,19 @@ are as follows:
DefineFeature (Name, NumLinear, NumCircular,
MinFeatPerChar, MaxFeatPerChar,
LongName, ShortName, ParamName,
Extractor, Displayer,
ComputeExtraPenalty,
InitExtractor, InitExtractorVars, TweekExtractorVars)
LongName, ShortName, ParamName)
----------------------------------------------------------------------*/
#define DefineFeature(Name, NL, NC, Min, Max, LN, SN, PN) \
FEATURE_DESC_STRUCT Name = { \
((NL) + (NC)), NL, NC, Min, Max, LN, SN, PN};
#define DefineFeatureExt(Name, E, IEV) FEATURE_EXT_STRUCT Name = {E, IEV};
#define DefineFeatureExt(Name, E) FEATURE_EXT_STRUCT Name = {E};
/*----------------------------------------------------------------------
Generic routines that work for all feature types
----------------------------------------------------------------------*/
BOOL8 AddFeature(FEATURE_SET FeatureSet, FEATURE Feature);
void DefaultInitFXVars();
void FreeFeature(FEATURE Feature);
void FreeFeatureSet(FEATURE_SET FeatureSet);

View File

@ -20,42 +20,11 @@
----------------------------------------------------------------------------**/
#include "outfeat.h"
#include "mfoutline.h"
#include "variables.h"
#include "sigmenu.h"
#include "ocrfeatures.h" //Debug
#include <stdio.h> //Debug
#include "efio.h" //Debug
//#include "christydbg.h"
/**----------------------------------------------------------------------------
Private Function Prototypes
----------------------------------------------------------------------------**/
/*
#if defined(__STDC__) || defined(__cplusplus)
# define _ARGS(s) s
#else
# define _ARGS(s) ()
#endif*/
/* /users/danj/wiseowl/src/danj/microfeatures/outfeat.c
void AddOutlineFeatureToSet
_ARGS((FPOINT *Start,
FPOINT *End,
FEATURE_SET FeatureSet));
void ConvertToOutlineFeatures
_ARGS((MFOUTLINE Outline,
FEATURE_SET FeatureSet));
void NormalizeOutlineX
_ARGS((FEATURE_SET FeatureSet));
#undef _ARGS
*/
/**----------------------------------------------------------------------------
Global Data Definitions and Declarations
----------------------------------------------------------------------------**/
/**----------------------------------------------------------------------------
Public Code
----------------------------------------------------------------------------**/
@ -89,60 +58,14 @@ FEATURE_SET ExtractOutlineFeatures(TBLOB *Blob, LINE_STATS *LineStats) {
RemainingOutlines = Outlines;
iterate(RemainingOutlines) {
Outline = (MFOUTLINE) first_node (RemainingOutlines);
/*---------Debug--------------------------------------------------*
OFile = fopen ("f:/ims/debug/ofOutline.logCPP", "r");
if (OFile == NULL)
{
OFile = Efopen ("f:/ims/debug/ofOutline.logCPP", "w");
WriteOutline(OFile, Outline);
}
else
{
fclose (OFile);
OFile = Efopen ("f:/ims/debug/ofOutline.logCPP", "a");
}
WriteOutline(OFile, Outline);
fclose (OFile);
*--------------------------------------------------------------------*/
ConvertToOutlineFeatures(Outline, FeatureSet);
}
if (NormMethod == baseline)
if (classify_norm_method == baseline)
NormalizeOutlineX(FeatureSet);
/*---------Debug--------------------------------------------------*
File = fopen ("f:/ims/debug/ofFeatSet.logCPP", "r");
if (File == NULL)
{
File = Efopen ("f:/ims/debug/ofFeatSet.logCPP", "w");
WriteFeatureSet(File, FeatureSet);
}
else
{
fclose (File);
File = Efopen ("f:/ims/debug/ofFeatSet.logCPP", "a");
}
WriteFeatureSet(File, FeatureSet);
fclose (File);
*--------------------------------------------------------------------*/
FreeOutlines(Outlines);
return (FeatureSet);
} /* ExtractOutlineFeatures */
/*---------------------------------------------------------------------------*/
void InitOutlineFXVars() {
//once contained a dummy
/*
** Parameters: none
** Globals: none
** Operation: Initialize the outline-feature extractor variables that can
** be tuned without recompiling.
** Return: none
** Exceptions: none
** History: 11/13/90, DSJ, Created.
*/
} /* InitOutlineFXVars */
/**----------------------------------------------------------------------------
Private Code
----------------------------------------------------------------------------**/
@ -169,11 +92,11 @@ void AddOutlineFeatureToSet(FPOINT *Start,
*/
FEATURE Feature;
Feature = NewFeature (&OutlineFeatDesc);
Feature->Params[OutlineFeatDir] = NormalizedAngleFrom (Start, End, 1.0);
Feature->Params[OutlineFeatX] = AverageOf (Start->x, End->x);
Feature->Params[OutlineFeatY] = AverageOf (Start->y, End->y);
Feature->Params[OutlineFeatLength] = DistanceBetween (*Start, *End);
Feature = NewFeature(&OutlineFeatDesc);
Feature->Params[OutlineFeatDir] = NormalizedAngleFrom(Start, End, 1.0);
Feature->Params[OutlineFeatX] = AverageOf(Start->x, End->x);
Feature->Params[OutlineFeatY] = AverageOf(Start->y, End->y);
Feature->Params[OutlineFeatLength] = DistanceBetween(*Start, *End);
AddFeature(FeatureSet, Feature);
} /* AddOutlineFeatureToSet */
@ -206,16 +129,16 @@ void ConvertToOutlineFeatures(MFOUTLINE Outline, FEATURE_SET FeatureSet) {
First = Outline;
Next = First;
do {
CopyPoint (PointAt (Next)->Point, FeatureStart);
Next = NextPointAfter (Next);
FeatureStart = PointAt(Next)->Point;
Next = NextPointAfter(Next);
/* note that an edge is hidden if the ending point of the edge is
marked as hidden. This situation happens because the order of
the outlines is reversed when they are converted from the old
format. In the old format, a hidden edge is marked by the
starting point for that edge. */
if (! (PointAt (Next)->Hidden)) {
CopyPoint (PointAt (Next)->Point, FeatureEnd);
if (!PointAt(Next)->Hidden) {
FeatureEnd = PointAt(Next)->Point;
AddOutlineFeatureToSet(&FeatureStart, &FeatureEnd, FeatureSet);
}
}

View File

@ -36,9 +36,7 @@ typedef enum {
/**----------------------------------------------------------------------------
Public Function Prototypes
----------------------------------------------------------------------------**/
FEATURE_SET ExtractOutlineFeatures(TBLOB *Blob, LINE_STATS *LineStats);
void InitOutlineFXVars();
FEATURE_SET ExtractOutlineFeatures(TBLOB *Blob, LINE_STATS *LineStats);
/*---------------------------------------------------------------------------
Privat Function Prototypes
@ -47,27 +45,9 @@ void AddOutlineFeatureToSet(FPOINT *Start,
FPOINT *End,
FEATURE_SET FeatureSet);
void ConvertToOutlineFeatures(MFOUTLINE Outline, FEATURE_SET FeatureSet);
void ConvertToOutlineFeatures(MFOUTLINE Outline, FEATURE_SET FeatureSet);
void NormalizeOutlineX(FEATURE_SET FeatureSet);
/*
#if defined(__STDC__) || defined(__cplusplus)
# define _ARGS(s) s
#else
# define _ARGS(s) ()
#endif*/
/* outfeat.c *
FEATURE_SET ExtractOutlineFeatures
_ARGS((BLOB *Blob,
LINE_STATS *LineStats));
void InitOutlineFXVars
_ARGS((void));
#undef _ARGS
*/
void NormalizeOutlineX(FEATURE_SET FeatureSet);
/**----------------------------------------------------------------------------
Global Data Definitions and Declarations

View File

@ -20,19 +20,21 @@
----------------------------------------------------------------------------**/
#include "picofeat.h"
#include "mfoutline.h"
#include "variables.h"
#include "sigmenu.h"
#include "hideedge.h"
#include "fpoint.h"
#include "varable.h"
#include <math.h>
#include "ocrfeatures.h" //Debug
#include <stdio.h> //Debug
#include "efio.h" //Debug
//#include "christydbg.h"
#define PICO_FEATURE_LENGTH 0.05
/*---------------------------------------------------------------------------
Variables
----------------------------------------------------------------------------*/
double_VAR(classify_pico_feature_length, 0.05, "Pico Feature Length");
/*---------------------------------------------------------------------------
Private Function Prototypes
@ -45,33 +47,6 @@ void ConvertToPicoFeatures2(MFOUTLINE Outline, FEATURE_SET FeatureSet);
void NormalizePicoX(FEATURE_SET FeatureSet);
/*
#if defined(__STDC__) || defined(__cplusplus)
# define _ARGS(s) s
#else
# define _ARGS(s) ()
#endif*/
/* /users/danj/wiseowl/src/danj/microfeatures/picofeat.c
void ConvertSegmentToPicoFeat
_ARGS((FPOINT *Start,
FPOINT *End,
FEATURE_SET FeatureSet));
void ConvertToPicoFeatures2
_ARGS((MFOUTLINE Outline,
FEATURE_SET FeatureSet));
void NormalizePicoX
_ARGS((FEATURE_SET FeatureSet));
#undef _ARGS
*/
/**----------------------------------------------------------------------------
Global Data Definitions and Declarations
----------------------------------------------------------------------------**/
/**----------------------------------------------------------------------------
Public Code
----------------------------------------------------------------------------**/
@ -82,7 +57,7 @@ FEATURE_SET ExtractPicoFeatures(TBLOB *Blob, LINE_STATS *LineStats) {
** Blob blob to extract pico-features from
** LineStats statistics on text row blob is in
** Globals:
** NormMethod normalization method currently specified
** classify_norm_method normalization method currently specified
** Operation: Dummy for now.
** Return: Pico-features for Blob.
** Exceptions: none
@ -119,7 +94,7 @@ FEATURE_SET ExtractPicoFeatures(TBLOB *Blob, LINE_STATS *LineStats) {
*--------------------------------------------------------------------*/
ConvertToPicoFeatures2(Outline, FeatureSet);
}
if (NormMethod == baseline)
if (classify_norm_method == baseline)
NormalizePicoX(FeatureSet);
/*---------Debug--------------------------------------------------*
File = fopen ("f:/ims/debug/pfFeatSet.logCPP", "r");
@ -141,27 +116,6 @@ FEATURE_SET ExtractPicoFeatures(TBLOB *Blob, LINE_STATS *LineStats) {
} /* ExtractPicoFeatures */
/*---------------------------------------------------------------------------*/
void InitPicoFXVars() {
/*
** Parameters: none
** Globals:
** PicoFeatureLength controls length of pico-features
** Operation: Initialize the pico-feature extractor variables that can
** be tuned without recompiling.
** Return: none
** Exceptions: none
** History: 9/4/90, DSJ, Created.
*/
VALUE dummy;
float_variable (PicoFeatureLength, "PicoFeatureLength",
PICO_FEATURE_LENGTH);
} /* InitPicoFXVars */
/**----------------------------------------------------------------------------
Private Code
----------------------------------------------------------------------------**/
@ -175,7 +129,7 @@ void ConvertSegmentToPicoFeat(FPOINT *Start,
** End ending point of pico-feature
** FeatureSet set to add pico-feature to
** Globals:
** PicoFeatureLength length of a single pico-feature
** classify_pico_feature_length length of a single pico-feature
** Operation: This routine converts an entire segment of an outline
** into a set of pico features which are added to
** FeatureSet. The length of the segment is rounded to the
@ -195,7 +149,7 @@ void ConvertSegmentToPicoFeat(FPOINT *Start,
Angle = NormalizedAngleFrom (Start, End, 1.0);
Length = DistanceBetween (*Start, *End);
NumFeatures = (int) floor (Length / PicoFeatureLength + 0.5);
NumFeatures = (int) floor (Length / classify_pico_feature_length + 0.5);
if (NumFeatures < 1)
NumFeatures = 1;
@ -228,7 +182,8 @@ void ConvertToPicoFeatures2(MFOUTLINE Outline, FEATURE_SET FeatureSet) {
** Outline outline to extract micro-features from
** FeatureSet set of features to add pico-features to
** Globals:
** PicoFeatureLength length of features to be extracted
** classify_pico_feature_length
** length of features to be extracted
** Operation:
** This routine steps thru the specified outline and cuts it
** up into pieces of equal length. These pieces become the
@ -242,24 +197,24 @@ void ConvertToPicoFeatures2(MFOUTLINE Outline, FEATURE_SET FeatureSet) {
MFOUTLINE First;
MFOUTLINE Current;
if (DegenerateOutline (Outline))
if (DegenerateOutline(Outline))
return;
First = Outline;
Current = First;
Next = NextPointAfter (Current);
Next = NextPointAfter(Current);
do {
/* note that an edge is hidden if the ending point of the edge is
marked as hidden. This situation happens because the order of
the outlines is reversed when they are converted from the old
format. In the old format, a hidden edge is marked by the
starting point for that edge. */
if (!(PointAt (Next)->Hidden))
ConvertSegmentToPicoFeat (&(PointAt (Current)->Point),
&(PointAt (Next)->Point), FeatureSet);
if (!(PointAt(Next)->Hidden))
ConvertSegmentToPicoFeat (&(PointAt(Current)->Point),
&(PointAt(Next)->Point), FeatureSet);
Current = Next;
Next = NextPointAfter (Current);
Next = NextPointAfter(Current);
}
while (Current != First);

View File

@ -24,6 +24,7 @@
#include "ocrfeatures.h"
#include "tessclas.h"
#include "fxdefs.h"
#include "varable.h"
typedef enum
{ PicoFeatY, PicoFeatDir, PicoFeatX }
@ -31,6 +32,13 @@ PICO_FEAT_PARAM_NAME;
#define MAX_PICO_FEATURES (1000)
/*---------------------------------------------------------------------------
Variables
----------------------------------------------------------------------------*/
extern double_VAR_H(classify_pico_feature_length, 0.05, "Pico Feature Length");
/**----------------------------------------------------------------------------
Public Function Prototypes
----------------------------------------------------------------------------**/
@ -38,25 +46,6 @@ PICO_FEAT_PARAM_NAME;
FEATURE_SET ExtractPicoFeatures(TBLOB *Blob, LINE_STATS *LineStats);
void InitPicoFXVars();
/*
#if defined(__STDC__) || defined(__cplusplus)
# define _ARGS(s) s
#else
# define _ARGS(s) ()
#endif*/
/* picofeat.c
FEATURE_SET ExtractPicoFeatures
_ARGS((BLOB *Blob,
LINE_STATS *LineStats));
void InitPicoFXVars
_ARGS((void));
#undef _ARGS
*/
/**----------------------------------------------------------------------------
Global Data Definitions and Declarations
----------------------------------------------------------------------------**/

View File

@ -26,7 +26,6 @@
I n c l u d e s
----------------------------------------------------------------------*/
#include "protos.h"
#include "debug.h"
#include "const.h"
#include "emalloc.h"
#include "freelist.h"
@ -35,6 +34,8 @@
#include "adaptmatch.h"
#include "scanutils.h"
#include "globals.h"
#include "classify.h"
#include "varable.h"
#include <stdio.h>
#include <math.h>
@ -47,9 +48,7 @@
----------------------------------------------------------------------*/
CLASS_STRUCT TrainingData[NUMBER_OF_CLASSES];
char *TrainingFile;
//extern int LearningDebugLevel;
STRING_VAR(classify_training_file, "MicroFeatures", "Training file");
/*----------------------------------------------------------------------
F u n c t i o n s
@ -79,8 +78,7 @@ int AddConfigToClass(CLASS_TYPE Class) {
Class->MaxNumConfigs = NewNumConfigs;
}
NewConfig = Class->NumConfigs;
Class->NumConfigs++;
NewConfig = Class->NumConfigs++;
Config = NewBitVector (MaxNumProtos);
Class->Configurations[NewConfig] = Config;
zero_all_bits (Config, WordsInVectorOfSize (MaxNumProtos));
@ -206,7 +204,7 @@ void FillABC(PROTO Proto) {
void FreeClass(CLASS_TYPE Class) {
if (Class) {
FreeClassFields(Class);
memfree(Class);
delete Class;
}
}
@ -230,18 +228,6 @@ void FreeClassFields(CLASS_TYPE Class) {
}
}
/**********************************************************************
* InitPrototypes
*
* Initialize anything that needs to be initialized to work with the
* functions in this file.
**********************************************************************/
void InitPrototypes() {
string_variable (TrainingFile, "TrainingFile", "MicroFeatures");
}
/**********************************************************************
* NewClass
*
@ -251,7 +237,7 @@ void InitPrototypes() {
CLASS_TYPE NewClass(int NumProtos, int NumConfigs) {
CLASS_TYPE Class;
Class = (CLASS_TYPE) Emalloc (sizeof (CLASS_STRUCT));
Class = new CLASS_STRUCT;
if (NumProtos > 0)
Class->Prototypes = (PROTO) Emalloc (NumProtos * sizeof (PROTO_STRUCT));
@ -292,15 +278,17 @@ void PrintProtos(CLASS_TYPE Class) {
* Read in the training data from a file. All of the classes are read
* in. The results are stored in the global variable, 'TrainingData'.
**********************************************************************/
void ReadClassFile() {
namespace tesseract {
void Classify::ReadClassFile() {
FILE *File;
char TextLine[CHARS_PER_LINE];
char unichar[CHARS_PER_LINE];
cprintf ("Reading training data from '%s' ...", TrainingFile);
cprintf ("Reading training data from '%s' ...",
static_cast<STRING>(classify_training_file).string());
fflush(stdout);
File = open_file (TrainingFile, "r");
File = open_file(static_cast<STRING>(classify_training_file).string(), "r");
while (fgets (TextLine, CHARS_PER_LINE, File) != NULL) {
sscanf(TextLine, "%s", unichar);
@ -311,6 +299,7 @@ void ReadClassFile() {
fclose(File);
new_line();
}
} // namespace tesseract
/**********************************************************************
* ReadClassFromFile

View File

@ -31,6 +31,8 @@
#include "bitvec.h"
#include "cutil.h"
#include "unichar.h"
#include "unicity_table.h"
#include "varable.h"
/*----------------------------------------------------------------------
T y p e s
@ -57,6 +59,7 @@ typedef struct
inT16 NumConfigs;
inT16 MaxNumConfigs;
CONFIGS Configurations;
UnicityTableEqEq<int> font_set;
} CLASS_STRUCT;
typedef CLASS_STRUCT *CLASS_TYPE;
typedef CLASS_STRUCT *CLASSES;
@ -73,6 +76,8 @@ typedef CLASS_STRUCT *CLASSES;
----------------------------------------------------------------------*/
extern CLASS_STRUCT TrainingData[];
extern STRING_VAR_H(classify_training_file, "MicroFeatures", "Training file");
/*----------------------------------------------------------------------
M a c r o s
----------------------------------------------------------------------*/
@ -124,10 +129,10 @@ extern CLASS_STRUCT TrainingData[];
#define PrintProto(Proto) \
(cprintf ("X=%4.2f, Y=%4.2f, Angle=%4.2f", \
Proto->X, \
Proto->Y, \
Proto->Length, \
Proto->Angle)) \
Proto->X, \
Proto->Y, \
Proto->Length, \
Proto->Angle)) \
/**********************************************************************
@ -168,8 +173,6 @@ CLASS_TYPE NewClass(int NumProtos, int NumConfigs);
void PrintProtos(CLASS_TYPE Class);
void ReadClassFile();
void ReadClassFromFile(FILE *File, UNICHAR_ID unichar_id);
void ReadConfigs(register FILE *File, CLASS_TYPE Class);
@ -182,77 +185,4 @@ void WriteOldConfigFile(FILE *File, CLASS_TYPE Class);
void WriteOldProtoFile(FILE *File, CLASS_TYPE Class);
/*
#if defined(__STDC__) || defined(__cplusplus)
# define _ARGS(s) s
#else
# define _ARGS(s) ()
#endif*/
/* protos.c *
int AddConfigToClass
_ARGS((CLASS_TYPE Class));
int AddProtoToClass
_ARGS((CLASS_TYPE Class));
FLOAT32 ClassConfigLength
_ARGS((CLASS_TYPE Class,
BIT_VECTOR Config));
FLOAT32 ClassProtoLength
_ARGS((CLASS_TYPE Class));
void CopyProto
_ARGS((PROTO Src,
PROTO Dest));
void FillABC
_ARGS((PROTO Proto));
void FreeClass
_ARGS((CLASS_TYPE Class));
void FreeClassFields
_ARGS((CLASS_TYPE Class));
void InitPrototypes
_ARGS((void));
CLASS_TYPE NewClass
_ARGS((int NumProtos,
int NumConfigs));
void PrintProtos
_ARGS((CLASS_TYPE Class));
void ReadClassFile
_ARGS((void));
void ReadClassFromFile
_ARGS((FILE *File,
int ClassChar));
void ReadConfigs
_ARGS((FILE *File,
CLASS_TYPE Class));
void ReadProtos
_ARGS((FILE *File,
CLASS_TYPE Class));
int SplitProto
_ARGS((CLASS_TYPE Class,
int OldPid));
void WriteOldConfigFile
_ARGS((FILE *File,
CLASS_TYPE Class));
void WriteOldProtoFile
_ARGS((FILE *File,
CLASS_TYPE Class));
#undef _ARGS
*/
#endif

View File

@ -1,225 +0,0 @@
/******************************************************************************
** Filename: sigmenu.c
** Purpose: General purpose, menu-oriented signal handling routines
** Author: Dan Johnson
** History: Mon Oct 2 07:25:50 1989, DSJ, Created.
**
** (c) Copyright Hewlett-Packard Company, 1988.
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
** http://www.apache.org/licenses/LICENSE-2.0
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
******************************************************************************/
/**----------------------------------------------------------------------------
Include Files and Type Defines
----------------------------------------------------------------------------**/
#include "sigmenu.h"
#include "oldlist.h"
#include "emalloc.h"
#include "secname.h"
#include <signal.h>
#include <stdio.h>
#include <string.h>
#define MAX_COMMAND_LENGTH 128
typedef struct
{
int ItemNum;
char *ItemLabel;
int_void ItemFunc;
} SIG_MENU_ITEM;
/**----------------------------------------------------------------------------
Global Data Definitions and Declarations
----------------------------------------------------------------------------**/
static LIST SignalMenus[NSIG]; /* must be initialized to NIL */
/**----------------------------------------------------------------------------
Private Function Prototypes
----------------------------------------------------------------------------**/
void MainSignalHandler(int Signal);
SIG_MENU_ITEM *NewSignalMenuItem (int ItemNum,
const char ItemLabel[], int_void ItemFunc);
int ItemCompare(void *arg1, //SIG_MENU_ITEM *Item1,
void *arg2); //SIG_MENU_ITEM *Item2);
/**----------------------------------------------------------------------------
Public Code
----------------------------------------------------------------------------**/
/*---------------------------------------------------------------------------*/
void
AddSignalMenuItem (int Signal,
int ItemNum, const char ItemLabel[], int_void ItemFunc) {
/*
** Parameters:
** Signal signal to be trapped for this menu
** ItemNum menu number for this item
** ItemLabel menu label for this item
** ItemFunc function to be called when item is selected
** Globals:
** SignalMenus list of menu items for each possible signal
** Operation:
** Add a new menu item to the list of menu items for Signal.
** Whenever Signal is encountered, the user will be given
** a list of options to choose from. This list is the list
** of all of the menu items that have been specified for that
** Signal.
** Return: none
** Exceptions: none
** History: Mon Oct 2 07:42:19 1989, DSJ, Created.
*/
#if 0
#ifndef SECURE_NAMES
SIG_MENU_ITEM *NewItem;
/* check for a valid Signal */
if (Signal >= NSIG || Signal <= 0) {
cprintf ("Illegal signal (%d) specified for menu item!\n", Signal);
return;
}
/* if this is the first item for this signal, indicate that the
appropriate signal handler has been enabled */
if (SignalMenus[Signal] == NIL)
cprintf ("Signal handler enabled for signal %d.\n", Signal);
/* add the new menu item to the appropriate list of menu items */
NewItem = NewSignalMenuItem (ItemNum, ItemLabel, ItemFunc);
SignalMenus[Signal] = s_adjoin (SignalMenus[Signal], NewItem, ItemCompare);
/* set up the trap for the appropriate signal */
signal(Signal, MainSignalHandler);
#endif
#endif
} /* AddSignalMenuItem */
/**----------------------------------------------------------------------------
Private Code
----------------------------------------------------------------------------**/
/*---------------------------------------------------------------------------*/
void MainSignalHandler(int Signal) {
/*
** Parameters:
** Signal signal that caused this function to be called
** Globals:
** SignalMenus list of menu items for each possible signal
** Operation: Provide the user with a menu of actions for the trapped
** signal. Execute the appropriate function. If the function
** returns SIG_RESUME, then terminate the signal handler and
** resume normal processing. If the function does not return
** SIG_RESUME, remain in the main signal handler menu.
** Return: none
** Exceptions: none
** History: Mon Oct 2 08:18:52 1989, DSJ, Created.
*/
#ifndef SECURE_NAMES
int Command;
char CommandLine[MAX_COMMAND_LENGTH];
char *Params;
LIST Items;
SIG_MENU_ITEM *MenuItem;
while (TRUE) {
Command = -1;
cprintf ("\nMAIN SIGNAL HANDLER FOR SIGNAL %d\n", Signal);
cprintf ("0. Resume normal operation\n");
Items = SignalMenus[Signal];
iterate(Items) {
MenuItem = (SIG_MENU_ITEM *) first_node (Items);
cprintf ("%d. %s\n", MenuItem->ItemNum, MenuItem->ItemLabel);
}
cprintf ("\nEnter Selection: ");
while (fgets (CommandLine, MAX_COMMAND_LENGTH, stdin) == NULL
|| strlen (CommandLine) <= 0);
Command = strtol (CommandLine, &Params, 10);
if (CommandLine == Params) {
cprintf ("\nIllegal command! - Try again.\n");
continue;
}
if (Command == 0)
signal(Signal, MainSignalHandler);
Items = SignalMenus[Signal];
iterate(Items) {
MenuItem = (SIG_MENU_ITEM *) first_node (Items);
if (Command == MenuItem->ItemNum) {
if ((*MenuItem->ItemFunc) ( /*Params */ ) == SIG_RESUME)
signal(Signal, MainSignalHandler);
break;
}
}
if (Items == NIL)
cprintf ("\nIllegal command! - Try again.\n");
}
#endif
} /* MainSignalHandler */
/*---------------------------------------------------------------------------*/
SIG_MENU_ITEM *
NewSignalMenuItem (int ItemNum, const char ItemLabel[], int_void ItemFunc) {
/*
** Parameters:
** ItemNum menu number for this item
** ItemLabel menu label for this item
** ItemFunc function to be called when item is selected
** Globals: none
** Operation: Allocate, initialize, and return a new signal menu item.
** Return: Ptr to new signal menu item data structure.
** Exceptions: none
** History: Mon Oct 2 08:04:20 1989, DSJ, Created.
*/
SIG_MENU_ITEM *NewItem;
NewItem = (SIG_MENU_ITEM *) Emalloc (sizeof (SIG_MENU_ITEM));
NewItem->ItemNum = ItemNum;
NewItem->ItemFunc = ItemFunc;
NewItem->ItemLabel = (char *) Emalloc (strlen (ItemLabel) + 1);
strcpy (NewItem->ItemLabel, ItemLabel);
return (NewItem);
} /* NewSignalMenuItem */
/*---------------------------------------------------------------------------*/
int ItemCompare(void *arg1, //SIG_MENU_ITEM *Item1,
void *arg2) { //SIG_MENU_ITEM *Item2)
/*
** Parameters:
** Item1, Item2 two menu items to be compared
** Globals: none
** Operation: Return -1 if the ItemNum of Item1 is less than the
** ItemNum of Item2. Return 0 if they are equal. Return +1
** if the ItemNum of Item1 is greater than the ItemNum of
** Item2. This routine is used by the list sorter to sort
** lists of menu items according to their item number.
** Return: -1, 0, or 1
** Exceptions: none
** History: Mon Oct 2 08:11:59 1989, DSJ, Created.
*/
SIG_MENU_ITEM *Item1 = (SIG_MENU_ITEM *) arg1;
SIG_MENU_ITEM *Item2 = (SIG_MENU_ITEM *) arg2;
if (Item1->ItemNum < Item2->ItemNum)
return (-1);
else if (Item1->ItemNum == Item2->ItemNum)
return (0);
else if (Item1->ItemNum > Item2->ItemNum)
return (1);
else
return 0;
} /* ItemCompare */

View File

@ -1,39 +0,0 @@
/******************************************************************************
** Filename: sigmenu.h
** Purpose: Definition of signal handler routines
** Author: Dan Johnson
** History: 10/2/89, DSJ, Created.
**
** (c) Copyright Hewlett-Packard Company, 1988.
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
** http://www.apache.org/licenses/LICENSE-2.0
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
******************************************************************************/
#ifndef SIGMENU_H
#define SIGMENU_H
/**----------------------------------------------------------------------------
Include Files and Type Defines
----------------------------------------------------------------------------**/
#include "cutil.h"
#include <signal.h>
/* functions to be placed in the signal menu look like: */
//typedef int (*SIG_MENU_FUNC)(...);
/* the value returned from a SIG_MENU_FUNC must be one of the following */
#define SIG_RESUME 1
#define SIG_MENU 0
/**----------------------------------------------------------------------------
Public Function Prototypes
----------------------------------------------------------------------------**/
void AddSignalMenuItem (int Signal,
int ItemNum,
const char ItemLabel[], int_void ItemFunc);
#endif

View File

@ -19,38 +19,35 @@
Include Files and Type Defines
----------------------------------------------------------------------------**/
#include "speckle.h"
#include "debug.h"
#include "blobs.h"
#include "ratngs.h"
#include "varable.h"
/**----------------------------------------------------------------------------
Global Data Definitions and Declarations
----------------------------------------------------------------------------**/
/* define control knobs for adjusting definition of speckle*/
make_float_var (MaxLargeSpeckleSize, 0.30, MakeMaxLargeSpeckleSize,
16, 2, SetMaxLargeSpeckleSize, "Max Large Speckle Size ...");
double_VAR(speckle_large_max_size, 0.30, "Max large speckle size");
make_float_var (SmallSpecklePenalty, 10.0, MakeSmallSpecklePenalty,
16, 3, SetSmallSpecklePenalty, "Small Speckle Penalty ...");
double_VAR(speckle_small_penalty, 10.0, "Small speckle penalty");
make_float_var (LargeSpecklePenalty, 10.0, MakeLargeSpecklePenalty,
16, 4, SetLargeSpecklePenalty, "Large Speckle Penalty ...");
double_VAR(speckle_large_penalty, 10.0, "Large speckle penalty");
make_float_var (SmallSpeckleCertainty, -1.0, MakeSmallSpeckleCertainty,
16, 5, SetSmallSpeckleCertainty,
"Small Speckle Certainty ...");
double_VAR(speckle_small_certainty, -1.0, "Small speckle certainty");
/**----------------------------------------------------------------------------
Public Code
----------------------------------------------------------------------------**/
/*---------------------------------------------------------------------------*/
LIST AddLargeSpeckleTo(LIST Choices) {
void AddLargeSpeckleTo(BLOB_CHOICE_LIST *Choices) {
/*
** Parameters:
** Choices choices to add a speckle choice to
** Globals:
** SmallSpecklePenalty rating for a small speckle
** LargeSpecklePenalty rating penalty for a large speckle
** SmallSpeckleCertainty certainty for a small speckle
** speckle_small_penalty rating for a small speckle
** speckle_large_penalty rating penalty for a large speckle
** speckle_small_certainty certainty for a small speckle
** Operation: This routine adds a null choice to Choices with a
** rating equal to the worst rating in Choices plus a pad.
** The certainty of the new choice is the same as the
@ -60,43 +57,31 @@ LIST AddLargeSpeckleTo(LIST Choices) {
** Exceptions: none
** History: Mon Mar 11 11:08:11 1991, DSJ, Created.
*/
LIST WorstChoice;
char empty_lengths[] = {0};
assert(Choices != NULL);
BLOB_CHOICE *blob_choice;
BLOB_CHOICE_IT temp_it;
temp_it.set_to_list(Choices);
/* if there are no other choices, use the small speckle penalty plus
the large speckle penalty */
if (Choices == NIL)
return (append_choice (NIL, "", empty_lengths, SmallSpecklePenalty + LargeSpecklePenalty,
SmallSpeckleCertainty, -1));
/* if there are other choices, add a null choice that is slightly worse
than the worst choice so far */
WorstChoice = last (Choices);
return (append_choice (Choices, "", empty_lengths,
best_probability (WorstChoice) + LargeSpecklePenalty,
best_certainty (WorstChoice), -1));
// If there are no other choices, use the small speckle penalty plus
// the large speckle penalty.
if (Choices->length() == 0) {
blob_choice =
new BLOB_CHOICE(0, speckle_small_certainty + speckle_large_penalty,
speckle_small_certainty, -1, NULL);
temp_it.add_to_end(blob_choice);
return;
}
// If there are other choices, add a null choice that is slightly worse
// than the worst choice so far.
temp_it.move_to_last();
blob_choice = temp_it.data(); // pick the worst choice
temp_it.add_to_end(
new BLOB_CHOICE(0, blob_choice->rating() + speckle_large_penalty,
blob_choice->certainty(), -1, NULL));
} /* AddLargeSpeckleTo */
/*---------------------------------------------------------------------------*/
void InitSpeckleVars() {
/*
** Parameters: none
** Globals: none
** Operation: Install the control variables needed for the speckle
** filters.
** Return: none
** Exceptions: none
** History: Mon Mar 11 12:04:59 1991, DSJ, Created.
*/
MakeMaxLargeSpeckleSize();
MakeSmallSpecklePenalty();
MakeLargeSpecklePenalty();
MakeSmallSpeckleCertainty();
} /* InitSpeckleVars */
/*---------------------------------------------------------------------------*/
BOOL8 LargeSpeckle(TBLOB *Blob, TEXTROW *Row) {
/*
@ -111,15 +96,15 @@ BOOL8 LargeSpeckle(TBLOB *Blob, TEXTROW *Row) {
** Exceptions: none
** History: Mon Mar 11 10:06:49 1991, DSJ, Created.
*/
FLOAT32 SpeckleSize;
double speckle_size;
TPOINT TopLeft;
TPOINT BottomRight;
SpeckleSize = RowHeight (Row) * MaxLargeSpeckleSize;
speckle_size = RowHeight (Row) * speckle_large_max_size;
blob_bounding_box(Blob, &TopLeft, &BottomRight);
if (TopLeft.y - BottomRight.y < SpeckleSize &&
BottomRight.x - TopLeft.x < SpeckleSize)
if (TopLeft.y - BottomRight.y < speckle_size &&
BottomRight.x - TopLeft.x < speckle_size)
return (TRUE);
else
return (FALSE);

View File

@ -21,49 +21,23 @@
/**----------------------------------------------------------------------------
Include Files and Type Defines
----------------------------------------------------------------------------**/
#include "baseline.h"
#include "choices.h"
#include "ratngs.h"
/**----------------------------------------------------------------------------
Macros
----------------------------------------------------------------------------**/
/* macro for getting the height of a row of text */
#define RowHeight(R) ((is_baseline_normalized ())? \
#define RowHeight(R) ((classify_baseline_normalized)? \
(BASELINE_SCALE): \
((R)->lineheight))
/**----------------------------------------------------------------------------
Public Function Prototypes
----------------------------------------------------------------------------**/
LIST AddLargeSpeckleTo(LIST Choices);
void AddLargeSpeckleTo(BLOB_CHOICE_LIST *Choices);
void InitSpeckleVars();
BOOL8 LargeSpeckle(TBLOB *Blob, TEXTROW *Row);
BOOL8 LargeSpeckle(TBLOB *Blob, TEXTROW *Row);
/*
#if defined(__STDC__) || defined(__cplusplus)
# define _ARGS(s) s
#else
# define _ARGS(s) ()
#endif*/
/* speckle.c
LIST AddLargeSpeckleTo
_ARGS((LIST Choices));
void InitSpeckleVars
_ARGS((void));
BOOL8 LargeSpeckle
_ARGS((BLOB *Blob,
TEXTROW *Row));
#undef _ARGS
*/
/**----------------------------------------------------------------------------
Global Data Definitions and Declarations
----------------------------------------------------------------------------**/
extern float SmallSpecklePenalty;
extern float SmallSpeckleCertainty;
#endif

View File

@ -1,10 +1,10 @@
/******************************************************************************
** Filename: xform2d.c
** Purpose: Library routines for performing 2D point transformations
** Author: Dan Johnson
** History: Fri Sep 22 09:54:17 1989, DSJ, Created.
** Filename: xform2d.c
** Purpose: Library routines for performing 2D point transformations
** Author: Dan Johnson
** History: Fri Sep 22 09:54:17 1989, DSJ, Created.
**
** (c) Copyright Hewlett-Packard Company, 1988.
** (c) Copyright Hewlett-Packard Company, 1988.
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
@ -26,33 +26,33 @@
----------------------------------------------------------------------------**/
void InitMatrix(MATRIX_2D *M) {
M->a = 1;
M->b = 0;
M->c = 0;
M->d = 1;
M->tx = 0;
M->ty = 0;
M->a = 1;
M->b = 0;
M->c = 0;
M->d = 1;
M->tx = 0;
M->ty = 0;
}
void CopyMatrix(MATRIX_2D *A, MATRIX_2D *B) {
B->a = A->a;
B->b = A->b;
B->c = A->c;
B->d = A->d;
B->tx = A->tx;
B->ty = A->ty;
B->a = A->a;
B->b = A->b;
B->c = A->c;
B->d = A->d;
B->tx = A->tx;
B->ty = A->ty;
}
void TranslateMatrix(MATRIX_2D *M, FLOAT32 X, FLOAT32 Y) {
M->tx += M->a * X + M->c * Y;
M->ty += M->b * X + M->d * Y;
M->tx += M->a * X + M->c * Y;
M->ty += M->b * X + M->d * Y;
}
void ScaleMatrix(MATRIX_2D *M, FLOAT32 X, FLOAT32 Y) {
M->a *= X;
M->b *= X;
M->c *= Y;
M->d *= Y;
M->a *= X;
M->b *= X;
M->c *= Y;
M->d *= Y;
}
void MirrorMatrixInX(MATRIX_2D *M) {ScaleMatrix(M, -1, 1);}
@ -60,49 +60,49 @@ void MirrorMatrixInY(MATRIX_2D *M) {ScaleMatrix(M, 1, -1);}
void MirrorMatrixInXY(MATRIX_2D *M) {ScaleMatrix(M, -1, -1);}
FLOAT32 MapX(MATRIX_2D *M, FLOAT32 X, FLOAT32 Y) {
return M->a * (X) + (M)->c * (Y) + (M)->tx;
return M->a * (X) + (M)->c * (Y) + (M)->tx;
}
FLOAT32 MapY(MATRIX_2D *M, FLOAT32 X, FLOAT32 Y) {
return M->b * X + M->d * Y + M->ty;
return M->b * X + M->d * Y + M->ty;
}
void MapPoint(MATRIX_2D *M, FPOINT &A, FPOINT &B) {
B.x = MapX (M, A.x, A.y);
B.y = MapY (M, A.x, A.y);
void MapPoint(MATRIX_2D *M, const FPOINT &A, FPOINT* B) {
B->x = MapX(M, A.x, A.y);
B->y = MapY(M, A.x, A.y);
}
FLOAT32 MapDx(MATRIX_2D *M, FLOAT32 DX, FLOAT32 DY) {
return M->a * DX + M->c * DY;
return M->a * DX + M->c * DY;
}
FLOAT32 MapDy(MATRIX_2D *M, FLOAT32 DX, FLOAT32 DY) {
return M->b * DX + M->d * DY;
return M->b * DX + M->d * DY;
}
/*---------------------------------------------------------------------------*/
void RotateMatrix(MATRIX_2D_PTR Matrix, FLOAT32 Angle) {
/*
** Parameters:
** Matrix transformation matrix to rotate
** Angle angle to rotate matrix
** Globals: none
** Operation:
** Rotate the coordinate system (as specified by Matrix) about
** its origin by Angle radians. In matrix notation the
** effect is as follows:
** Parameters:
** Matrix transformation matrix to rotate
** Angle angle to rotate matrix
** Globals: none
** Operation:
** Rotate the coordinate system (as specified by Matrix) about
** its origin by Angle radians. In matrix notation the
** effect is as follows:
**
** Matrix = R X Matrix
** Matrix = R X Matrix
**
** where R is the following matrix
** where R is the following matrix
**
** cos Angle sin Angle 0
** -sin Angle cos Angle 0
** 0 0 1
** Return: none
** Exceptions: none
** History: 7/27/89, DSJ, Create.
** cos Angle sin Angle 0
** -sin Angle cos Angle 0
** 0 0 1
** Return: none
** Exceptions: none
** History: 7/27/89, DSJ, Create.
*/
FLOAT32 Cos, Sin;
FLOAT32 NewA, NewB;

View File

@ -1,10 +1,10 @@
/******************************************************************************
** Filename: xform2d.h
** Purpose: Definitions for using 2D point transformation library
** Author: Dan Johnson
** History: Fri Sep 22 09:57:08 1989, DSJ, Created.
** Filename: xform2d.h
** Purpose: Definitions for using 2D point transformation library
** Author: Dan Johnson
** History: Fri Sep 22 09:57:08 1989, DSJ, Created.
**
** (c) Copyright Hewlett-Packard Company, 1988.
** (c) Copyright Hewlett-Packard Company, 1988.
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
@ -51,10 +51,10 @@ FLOAT32 MapX(MATRIX_2D *M, FLOAT32 X, FLOAT32 Y);
FLOAT32 MapY(MATRIX_2D *M, FLOAT32 X, FLOAT32 Y);
void MapPoint(MATRIX_2D *M, FPOINT &A, FPOINT &B);
void MapPoint(MATRIX_2D *M, const FPOINT &A, FPOINT* B);
FLOAT32 MapDx(MATRIX_2D *M, FLOAT32 DX, FLOAT32 DY);
FLOAT32 MapDy(MATRIX_2D M, FLOAT32 DX, FLOAT32 DY);
void RotateMatrix(MATRIX_2D_PTR Matrix, FLOAT32 Angle);
void RotateMatrix(MATRIX_2D_PTR Matrix, FLOAT32 Angle);
#endif