|
tesseract 3.04.01
|
#include <math.h>#include <stdio.h>#include <assert.h>#include "classify.h"#include "const.h"#include "emalloc.h"#include "fontinfo.h"#include "genericvector.h"#include "globals.h"#include "helpers.h"#include "intproto.h"#include "mfoutline.h"#include "ndminx.h"#include "picofeat.h"#include "points.h"#include "shapetable.h"#include "svmnode.h"Go to the source code of this file.
Classes | |
| struct | FILL_SWITCH |
| struct | TABLE_FILLER |
| struct | FILL_SPEC |
Namespaces | |
| namespace | tesseract |
Defines | |
| #define | PROTO_PRUNER_SCALE (4.0) |
| #define | INT_DESCENDER (0.0 * INT_CHAR_NORM_RANGE) |
| #define | INT_BASELINE (0.25 * INT_CHAR_NORM_RANGE) |
| #define | INT_XHEIGHT (0.75 * INT_CHAR_NORM_RANGE) |
| #define | INT_CAPHEIGHT (1.0 * INT_CHAR_NORM_RANGE) |
| #define | INT_XCENTER (0.5 * INT_CHAR_NORM_RANGE) |
| #define | INT_YCENTER (0.5 * INT_CHAR_NORM_RANGE) |
| #define | INT_XRADIUS (0.2 * INT_CHAR_NORM_RANGE) |
| #define | INT_YRADIUS (0.2 * INT_CHAR_NORM_RANGE) |
| #define | INT_MIN_X 0 |
| #define | INT_MIN_Y 0 |
| #define | INT_MAX_X INT_CHAR_NORM_RANGE |
| #define | INT_MAX_Y INT_CHAR_NORM_RANGE |
| #define | HV_TOLERANCE (0.0025) |
| #define | MAX_NUM_SWITCHES 3 |
| #define | OLD_MAX_NUM_CONFIGS 32 |
| #define | OLD_WERDS_PER_CONFIG_VEC |
| #define | CircularIncrement(i, r) (((i) < (r) - 1)?((i)++):((i) = 0)) |
| #define | MapParam(P, O, N) (floor (((P) + (O)) * (N))) |
| #define | MAX_LEVEL 2 |
| #define | XS X_SHIFT |
| #define | YS Y_SHIFT |
| #define | AS ANGLE_SHIFT |
| #define | NB NUM_CP_BUCKETS |
Enumerations | |
| enum | SWITCH_TYPE { StartSwitch, EndSwitch, LastSwitch } |
Functions | |
| FLOAT32 | BucketStart (int Bucket, FLOAT32 Offset, int NumBuckets) |
| FLOAT32 | BucketEnd (int Bucket, FLOAT32 Offset, int NumBuckets) |
| void | DoFill (FILL_SPEC *FillSpec, CLASS_PRUNER_STRUCT *Pruner, register uinT32 ClassMask, register uinT32 ClassCount, register uinT32 WordIndex) |
| BOOL8 | FillerDone (TABLE_FILLER *Filler) |
| void | FillPPCircularBits (uinT32 ParamTable[NUM_PP_BUCKETS][WERDS_PER_PP_VECTOR], int Bit, FLOAT32 Center, FLOAT32 Spread, bool debug) |
| void | FillPPLinearBits (uinT32 ParamTable[NUM_PP_BUCKETS][WERDS_PER_PP_VECTOR], int Bit, FLOAT32 Center, FLOAT32 Spread, bool debug) |
| void | GetCPPadsForLevel (int Level, FLOAT32 *EndPad, FLOAT32 *SidePad, FLOAT32 *AnglePad) |
| ScrollView::Color | GetMatchColorFor (FLOAT32 Evidence) |
| void | GetNextFill (TABLE_FILLER *Filler, FILL_SPEC *Fill) |
| void | InitTableFiller (FLOAT32 EndPad, FLOAT32 SidePad, FLOAT32 AnglePad, PROTO Proto, TABLE_FILLER *Filler) |
| void | RenderIntFeature (ScrollView *window, const INT_FEATURE_STRUCT *Feature, ScrollView::Color color) |
| void | RenderIntProto (ScrollView *window, INT_CLASS Class, PROTO_ID ProtoId, ScrollView::Color color) |
| int | TruncateParam (FLOAT32 Param, int Min, int Max, char *Id) |
| void | AddIntClass (INT_TEMPLATES Templates, CLASS_ID ClassId, INT_CLASS Class) |
| int | AddIntConfig (INT_CLASS Class) |
| int | AddIntProto (INT_CLASS Class) |
| void | AddProtoToClassPruner (PROTO Proto, CLASS_ID ClassId, INT_TEMPLATES Templates) |
| void | AddProtoToProtoPruner (PROTO Proto, int ProtoId, INT_CLASS Class, bool debug) |
| uinT8 | Bucket8For (FLOAT32 param, FLOAT32 offset, int num_buckets) |
| uinT16 | Bucket16For (FLOAT32 param, FLOAT32 offset, int num_buckets) |
| uinT8 | CircBucketFor (FLOAT32 param, FLOAT32 offset, int num_buckets) |
| void | UpdateMatchDisplay () |
| void | ConvertConfig (BIT_VECTOR Config, int ConfigId, INT_CLASS Class) |
| void | DisplayIntFeature (const INT_FEATURE_STRUCT *Feature, FLOAT32 Evidence) |
| void | DisplayIntProto (INT_CLASS Class, PROTO_ID ProtoId, FLOAT32 Evidence) |
| 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) |
| void | tesseract::ClearFeatureSpaceWindow (NORM_METHOD norm_method, ScrollView *window) |
| void | InitIntMatchWindowIfReqd () |
| void | InitProtoDisplayWindowIfReqd () |
| void | InitFeatureDisplayWindowIfReqd () |
| ScrollView * | CreateFeatureSpaceWindow (const char *name, int xpos, int ypos) |
Variables | |
| ScrollView * | IntMatchWindow = NULL |
| ScrollView * | FeatureDisplayWindow = NULL |
| ScrollView * | ProtoDisplayWindow = NULL |
| int | classify_num_cp_levels = 3 |
| double | classify_cp_angle_pad_loose = 45.0 |
| double | classify_cp_angle_pad_medium = 20.0 |
| double | classify_cp_angle_pad_tight = 10.0 |
| double | classify_cp_end_pad_loose = 0.5 |
| double | classify_cp_end_pad_medium = 0.5 |
| double | classify_cp_end_pad_tight = 0.5 |
| double | classify_cp_side_pad_loose = 2.5 |
| double | classify_cp_side_pad_medium = 1.2 |
| double | classify_cp_side_pad_tight = 0.6 |
| double | classify_pp_angle_pad = 45.0 |
| double | classify_pp_end_pad = 0.5 |
| double | classify_pp_side_pad = 2.5 |
| #define AS ANGLE_SHIFT |
| #define CircularIncrement | ( | i, | |
| r | |||
| ) | (((i) < (r) - 1)?((i)++):((i) = 0)) |
macro for performing circular increments of bucket indices
Definition at line 122 of file intproto.cpp.
| #define HV_TOLERANCE (0.0025) |
define pad used to snap near horiz/vertical protos to horiz/vertical
Definition at line 71 of file intproto.cpp.
| #define INT_BASELINE (0.25 * INT_CHAR_NORM_RANGE) |
Definition at line 57 of file intproto.cpp.
| #define INT_CAPHEIGHT (1.0 * INT_CHAR_NORM_RANGE) |
Definition at line 59 of file intproto.cpp.
| #define INT_DESCENDER (0.0 * INT_CHAR_NORM_RANGE) |
Definition at line 56 of file intproto.cpp.
| #define INT_MAX_X INT_CHAR_NORM_RANGE |
Definition at line 67 of file intproto.cpp.
| #define INT_MAX_Y INT_CHAR_NORM_RANGE |
Definition at line 68 of file intproto.cpp.
| #define INT_MIN_X 0 |
Definition at line 65 of file intproto.cpp.
| #define INT_MIN_Y 0 |
Definition at line 66 of file intproto.cpp.
| #define INT_XCENTER (0.5 * INT_CHAR_NORM_RANGE) |
Definition at line 61 of file intproto.cpp.
| #define INT_XHEIGHT (0.75 * INT_CHAR_NORM_RANGE) |
Definition at line 58 of file intproto.cpp.
| #define INT_XRADIUS (0.2 * INT_CHAR_NORM_RANGE) |
Definition at line 63 of file intproto.cpp.
| #define INT_YCENTER (0.5 * INT_CHAR_NORM_RANGE) |
Definition at line 62 of file intproto.cpp.
| #define INT_YRADIUS (0.2 * INT_CHAR_NORM_RANGE) |
Definition at line 64 of file intproto.cpp.
| #define MapParam | ( | P, | |
| O, | |||
| N | |||
| ) | (floor (((P) + (O)) * (N))) |
macro for mapping floats to ints without bounds checking
Definition at line 125 of file intproto.cpp.
| #define MAX_LEVEL 2 |
| #define MAX_NUM_SWITCHES 3 |
Definition at line 76 of file intproto.cpp.
| #define NB NUM_CP_BUCKETS |
| #define OLD_MAX_NUM_CONFIGS 32 |
Definition at line 114 of file intproto.cpp.
| #define OLD_WERDS_PER_CONFIG_VEC |
((OLD_MAX_NUM_CONFIGS + BITS_PER_WERD - 1) /\ BITS_PER_WERD)
Definition at line 115 of file intproto.cpp.
| #define PROTO_PRUNER_SCALE (4.0) |
Definition at line 54 of file intproto.cpp.
| #define XS X_SHIFT |
| #define YS Y_SHIFT |
| enum SWITCH_TYPE |
Definition at line 73 of file intproto.cpp.
{ StartSwitch, EndSwitch, LastSwitch }
| void AddIntClass | ( | INT_TEMPLATES | Templates, |
| CLASS_ID | ClassId, | ||
| INT_CLASS | Class | ||
| ) |
This routine adds a new class structure to a set of templates. Classes have to be added to Templates in the order of increasing ClassIds.
| Templates | templates to add new class to |
| ClassId | class id to associate new class with |
| Class | class data structure to add to templates |
Globals: none
Definition at line 240 of file intproto.cpp.
{
int Pruner;
assert (LegalClassId (ClassId));
if (ClassId != Templates->NumClasses) {
fprintf(stderr, "Please make sure that classes are added to templates");
fprintf(stderr, " in increasing order of ClassIds\n");
exit(1);
}
ClassForClassId (Templates, ClassId) = Class;
Templates->NumClasses++;
if (Templates->NumClasses > MaxNumClassesIn (Templates)) {
Pruner = Templates->NumClassPruners++;
Templates->ClassPruners[Pruner] = new CLASS_PRUNER_STRUCT;
memset(Templates->ClassPruners[Pruner], 0, sizeof(CLASS_PRUNER_STRUCT));
}
} /* AddIntClass */
| int AddIntConfig | ( | INT_CLASS | Class | ) |
This routine returns the index of the next free config in Class.
| Class | class to add new configuration to |
Globals: none
Definition at line 272 of file intproto.cpp.
{
int Index;
assert(Class->NumConfigs < MAX_NUM_CONFIGS);
Index = Class->NumConfigs++;
Class->ConfigLengths[Index] = 0;
return Index;
} /* AddIntConfig */
| int AddIntProto | ( | INT_CLASS | Class | ) |
This routine allocates the next free proto in Class and returns its index.
| Class | class to add new proto to |
Globals: none
Definition at line 295 of file intproto.cpp.
{
int Index;
int ProtoSetId;
PROTO_SET ProtoSet;
INT_PROTO Proto;
uinT32 *Word;
if (Class->NumProtos >= MAX_NUM_PROTOS)
return (NO_PROTO);
Index = Class->NumProtos++;
if (Class->NumProtos > MaxNumIntProtosIn(Class)) {
ProtoSetId = Class->NumProtoSets++;
ProtoSet = (PROTO_SET) Emalloc(sizeof(PROTO_SET_STRUCT));
Class->ProtoSets[ProtoSetId] = ProtoSet;
memset(ProtoSet, 0, sizeof(*ProtoSet));
/* reallocate space for the proto lengths and install in class */
Class->ProtoLengths =
(uinT8 *)Erealloc(Class->ProtoLengths,
MaxNumIntProtosIn(Class) * sizeof(uinT8));
memset(&Class->ProtoLengths[Index], 0,
sizeof(*Class->ProtoLengths) * (MaxNumIntProtosIn(Class) - Index));
}
/* initialize proto so its length is zero and it isn't in any configs */
Class->ProtoLengths[Index] = 0;
Proto = ProtoForProtoId (Class, Index);
for (Word = Proto->Configs;
Word < Proto->Configs + WERDS_PER_CONFIG_VEC; *Word++ = 0);
return (Index);
}
| void AddProtoToClassPruner | ( | PROTO | Proto, |
| CLASS_ID | ClassId, | ||
| INT_TEMPLATES | Templates | ||
| ) |
This routine adds Proto to the class pruning tables for the specified class in Templates.
Globals:
| Proto | floating-pt proto to add to class pruner |
| ClassId | class id corresponding to Proto |
| Templates | set of templates containing class pruner |
Definition at line 346 of file intproto.cpp.
{
CLASS_PRUNER_STRUCT* Pruner;
uinT32 ClassMask;
uinT32 ClassCount;
uinT32 WordIndex;
int Level;
FLOAT32 EndPad, SidePad, AnglePad;
TABLE_FILLER TableFiller;
FILL_SPEC FillSpec;
Pruner = CPrunerFor (Templates, ClassId);
WordIndex = CPrunerWordIndexFor (ClassId);
ClassMask = CPrunerMaskFor (MAX_LEVEL, ClassId);
for (Level = classify_num_cp_levels - 1; Level >= 0; Level--) {
GetCPPadsForLevel(Level, &EndPad, &SidePad, &AnglePad);
ClassCount = CPrunerMaskFor (Level, ClassId);
InitTableFiller(EndPad, SidePad, AnglePad, Proto, &TableFiller);
while (!FillerDone (&TableFiller)) {
GetNextFill(&TableFiller, &FillSpec);
DoFill(&FillSpec, Pruner, ClassMask, ClassCount, WordIndex);
}
}
} /* AddProtoToClassPruner */
This routine updates the proto pruner lookup tables for Class to include a new proto identified by ProtoId and described by Proto.
| Proto | floating-pt proto to be added to proto pruner |
| ProtoId | id of proto |
| Class | integer class that contains desired proto pruner |
| debug | debug flag |
Definition at line 389 of file intproto.cpp.
{
FLOAT32 Angle, X, Y, Length;
FLOAT32 Pad;
int Index;
PROTO_SET ProtoSet;
if (ProtoId >= Class->NumProtos)
cprintf("AddProtoToProtoPruner:assert failed: %d < %d",
ProtoId, Class->NumProtos);
assert(ProtoId < Class->NumProtos);
Index = IndexForProto (ProtoId);
ProtoSet = Class->ProtoSets[SetForProto (ProtoId)];
Angle = Proto->Angle;
#ifndef _WIN32
assert(!isnan(Angle));
#endif
FillPPCircularBits (ProtoSet->ProtoPruner[PRUNER_ANGLE], Index,
Angle + ANGLE_SHIFT, classify_pp_angle_pad / 360.0,
debug);
Angle *= 2.0 * PI;
Length = Proto->Length;
X = Proto->X + X_SHIFT;
Pad = MAX (fabs (cos (Angle)) * (Length / 2.0 +
classify_pp_end_pad *
GetPicoFeatureLength ()),
fabs (sin (Angle)) * (classify_pp_side_pad *
GetPicoFeatureLength ()));
FillPPLinearBits(ProtoSet->ProtoPruner[PRUNER_X], Index, X, Pad, debug);
Y = Proto->Y + Y_SHIFT;
Pad = MAX (fabs (sin (Angle)) * (Length / 2.0 +
classify_pp_end_pad *
GetPicoFeatureLength ()),
fabs (cos (Angle)) * (classify_pp_side_pad *
GetPicoFeatureLength ()));
FillPPLinearBits(ProtoSet->ProtoPruner[PRUNER_Y], Index, Y, Pad, debug);
} /* AddProtoToProtoPruner */
Definition at line 445 of file intproto.cpp.
{
int bucket = IntCastRounded(MapParam(param, offset, num_buckets));
return static_cast<uinT16>(ClipToRange(bucket, 0, num_buckets - 1));
}
Returns a quantized bucket for the given param shifted by offset, notionally (param + offset) * num_buckets, but clipped and casted to the appropriate type.
Definition at line 441 of file intproto.cpp.
{
int bucket = IntCastRounded(MapParam(param, offset, num_buckets));
return static_cast<uinT8>(ClipToRange(bucket, 0, num_buckets - 1));
}
This routine returns the parameter value which corresponds to the end of the specified bucket. The bucket number should have been generated using the BucketFor() function with parameters Offset and NumBuckets.
| Bucket | bucket whose end is to be computed |
| Offset | offset used to map params to buckets |
| NumBuckets | total number of buckets |
Definition at line 1235 of file intproto.cpp.
This routine returns the parameter value which corresponds to the beginning of the specified bucket. The bucket number should have been generated using the BucketFor() function with parameters Offset and NumBuckets.
| Bucket | bucket whose start is to be computed |
| Offset | offset used to map params to buckets |
| NumBuckets | total number of buckets |
Definition at line 1216 of file intproto.cpp.
Returns a quantized bucket for the given circular param shifted by offset, notionally (param + offset) * num_buckets, but modded and casted to the appropriate type.
Definition at line 455 of file intproto.cpp.
{
int bucket = IntCastRounded(MapParam(param, offset, num_buckets));
return static_cast<uinT8>(Modulo(bucket, num_buckets));
} /* CircBucketFor */
| void ConvertConfig | ( | BIT_VECTOR | Config, |
| int | ConfigId, | ||
| INT_CLASS | Class | ||
| ) |
This operation updates the config vectors of all protos in Class to indicate that the protos with 1's in Config belong to a new configuration identified by ConfigId. It is assumed that the length of the Config bit vector is equal to the number of protos in Class.
| Config | config to be added to class |
| ConfigId | id to be used for new config |
| Class | class to add new config to |
Definition at line 493 of file intproto.cpp.
{
int ProtoId;
INT_PROTO Proto;
int TotalLength;
for (ProtoId = 0, TotalLength = 0;
ProtoId < Class->NumProtos; ProtoId++) {
if (test_bit(Config, ProtoId)) {
Proto = ProtoForProtoId(Class, ProtoId);
SET_BIT(Proto->Configs, ConfigId);
TotalLength += Class->ProtoLengths[ProtoId];
}
}
Class->ConfigLengths[ConfigId] = TotalLength;
} /* ConvertConfig */
| ScrollView* CreateFeatureSpaceWindow | ( | const char * | name, |
| int | xpos, | ||
| int | ypos | ||
| ) |
Creates a window of the appropriate size for displaying elements in feature space.
Definition at line 1936 of file intproto.cpp.
{
return new ScrollView(name, xpos, ypos, 520, 520, 260, 260, true);
}
| void DisplayIntFeature | ( | const INT_FEATURE_STRUCT * | Feature, |
| FLOAT32 | Evidence | ||
| ) |
This routine renders the specified feature into a global display list.
Globals:
| Feature | pico-feature to be displayed |
| Evidence | best evidence for this feature (0-1) |
Definition at line 630 of file intproto.cpp.
{
ScrollView::Color color = GetMatchColorFor(Evidence);
RenderIntFeature(IntMatchWindow, Feature, color);
if (FeatureDisplayWindow) {
RenderIntFeature(FeatureDisplayWindow, Feature, color);
}
} /* DisplayIntFeature */
This routine renders the specified proto into a global display list.
Globals:
| Class | class to take proto from |
| ProtoId | id of proto in Class to be displayed |
| Evidence | total evidence for proto (0-1) |
Definition at line 652 of file intproto.cpp.
{
ScrollView::Color color = GetMatchColorFor(Evidence);
RenderIntProto(IntMatchWindow, Class, ProtoId, color);
if (ProtoDisplayWindow) {
RenderIntProto(ProtoDisplayWindow, Class, ProtoId, color);
}
} /* DisplayIntProto */
| void DoFill | ( | FILL_SPEC * | FillSpec, |
| CLASS_PRUNER_STRUCT * | Pruner, | ||
| register uinT32 | ClassMask, | ||
| register uinT32 | ClassCount, | ||
| register uinT32 | WordIndex | ||
| ) |
This routine fills in the section of a class pruner corresponding to a single x value for a single proto of a class.
| FillSpec | specifies which bits to fill in pruner |
| Pruner | class pruner to be filled |
| ClassMask | indicates which bits to change in each word |
| ClassCount | indicates what to change bits to |
| WordIndex | indicates which word to change |
Definition at line 1254 of file intproto.cpp.
{
int X, Y, Angle;
uinT32 OldWord;
X = FillSpec->X;
if (X < 0)
X = 0;
if (X >= NUM_CP_BUCKETS)
X = NUM_CP_BUCKETS - 1;
if (FillSpec->YStart < 0)
FillSpec->YStart = 0;
if (FillSpec->YEnd >= NUM_CP_BUCKETS)
FillSpec->YEnd = NUM_CP_BUCKETS - 1;
for (Y = FillSpec->YStart; Y <= FillSpec->YEnd; Y++)
for (Angle = FillSpec->AngleStart;
TRUE; CircularIncrement (Angle, NUM_CP_BUCKETS)) {
OldWord = Pruner->p[X][Y][Angle][WordIndex];
if (ClassCount > (OldWord & ClassMask)) {
OldWord &= ~ClassMask;
OldWord |= ClassCount;
Pruner->p[X][Y][Angle][WordIndex] = OldWord;
}
if (Angle == FillSpec->AngleEnd)
break;
}
} /* DoFill */
| BOOL8 FillerDone | ( | TABLE_FILLER * | Filler | ) |
Return TRUE if the specified table filler is done, i.e. if it has no more lines to fill.
| Filler | table filler to check if done |
Definition at line 1297 of file intproto.cpp.
{
FILL_SWITCH *Next;
Next = &(Filler->Switch[Filler->NextSwitch]);
if (Filler->X > Next->X && Next->Type == LastSwitch)
return (TRUE);
else
return (FALSE);
} /* FillerDone */
| void FillPPCircularBits | ( | uinT32 | ParamTable[NUM_PP_BUCKETS][WERDS_PER_PP_VECTOR], |
| int | Bit, | ||
| FLOAT32 | Center, | ||
| FLOAT32 | Spread, | ||
| bool | debug | ||
| ) |
This routine sets Bit in each bit vector whose bucket lies within the range Center +- Spread. The fill is done for a circular dimension, i.e. bucket 0 is adjacent to the last bucket. It is assumed that Center and Spread are expressed in a circular coordinate system whose range is 0 to 1.
| ParamTable | table of bit vectors, one per param bucket |
| Bit | bit position in vectors to be filled |
| Center | center of filled area |
| Spread | spread of filled area |
| debug | debug flag |
Definition at line 1327 of file intproto.cpp.
{
int i, FirstBucket, LastBucket;
if (Spread > 0.5)
Spread = 0.5;
FirstBucket = (int) floor ((Center - Spread) * NUM_PP_BUCKETS);
if (FirstBucket < 0)
FirstBucket += NUM_PP_BUCKETS;
LastBucket = (int) floor ((Center + Spread) * NUM_PP_BUCKETS);
if (LastBucket >= NUM_PP_BUCKETS)
LastBucket -= NUM_PP_BUCKETS;
if (debug) tprintf("Circular fill from %d to %d", FirstBucket, LastBucket);
for (i = FirstBucket; TRUE; CircularIncrement (i, NUM_PP_BUCKETS)) {
SET_BIT (ParamTable[i], Bit);
/* exit loop after we have set the bit for the last bucket */
if (i == LastBucket)
break;
}
} /* FillPPCircularBits */
| void FillPPLinearBits | ( | uinT32 | ParamTable[NUM_PP_BUCKETS][WERDS_PER_PP_VECTOR], |
| int | Bit, | ||
| FLOAT32 | Center, | ||
| FLOAT32 | Spread, | ||
| bool | debug | ||
| ) |
This routine sets Bit in each bit vector whose bucket lies within the range Center +- Spread. The fill is done for a linear dimension, i.e. there is no wrap-around for this dimension. It is assumed that Center and Spread are expressed in a linear coordinate system whose range is approximately 0 to 1. Values outside this range will be clipped.
| ParamTable | table of bit vectors, one per param bucket |
| Bit | bit number being filled |
| Center | center of filled area |
| Spread | spread of filled area |
| debug | debug flag |
Definition at line 1371 of file intproto.cpp.
{
int i, FirstBucket, LastBucket;
FirstBucket = (int) floor ((Center - Spread) * NUM_PP_BUCKETS);
if (FirstBucket < 0)
FirstBucket = 0;
LastBucket = (int) floor ((Center + Spread) * NUM_PP_BUCKETS);
if (LastBucket >= NUM_PP_BUCKETS)
LastBucket = NUM_PP_BUCKETS - 1;
if (debug) tprintf("Linear fill from %d to %d", FirstBucket, LastBucket);
for (i = FirstBucket; i <= LastBucket; i++)
SET_BIT (ParamTable[i], Bit);
} /* FillPPLinearBits */
| void free_int_class | ( | INT_CLASS | int_class | ) |
Definition at line 711 of file intproto.cpp.
{
int i;
for (i = 0; i < int_class->NumProtoSets; i++) {
Efree (int_class->ProtoSets[i]);
}
if (int_class->ProtoLengths != NULL) {
Efree (int_class->ProtoLengths);
}
Efree(int_class);
}
| void free_int_templates | ( | INT_TEMPLATES | templates | ) |
Definition at line 748 of file intproto.cpp.
{
int i;
for (i = 0; i < templates->NumClasses; i++)
free_int_class(templates->Class[i]);
for (i = 0; i < templates->NumClassPruners; i++)
delete templates->ClassPruners[i];
Efree(templates);
}
This routine copies the appropriate global pad variables into EndPad, SidePad, and AnglePad. This is a kludge used to get around the fact that global control variables cannot be arrays. If the specified level is illegal, the tightest possible pads are returned.
| Level | "tightness" level to return pads for |
| EndPad | place to put end pad for Level |
| SidePad | place to put side pad for Level |
| AnglePad | place to put angle pad for Level |
Definition at line 1485 of file intproto.cpp.
{
switch (Level) {
case 0:
*EndPad = classify_cp_end_pad_loose * GetPicoFeatureLength ();
*SidePad = classify_cp_side_pad_loose * GetPicoFeatureLength ();
*AnglePad = classify_cp_angle_pad_loose / 360.0;
break;
case 1:
*EndPad = classify_cp_end_pad_medium * GetPicoFeatureLength ();
*SidePad = classify_cp_side_pad_medium * GetPicoFeatureLength ();
*AnglePad = classify_cp_angle_pad_medium / 360.0;
break;
case 2:
*EndPad = classify_cp_end_pad_tight * GetPicoFeatureLength ();
*SidePad = classify_cp_side_pad_tight * GetPicoFeatureLength ();
*AnglePad = classify_cp_angle_pad_tight / 360.0;
break;
default:
*EndPad = classify_cp_end_pad_tight * GetPicoFeatureLength ();
*SidePad = classify_cp_side_pad_tight * GetPicoFeatureLength ();
*AnglePad = classify_cp_angle_pad_tight / 360.0;
break;
}
if (*AnglePad > 0.5)
*AnglePad = 0.5;
} /* GetCPPadsForLevel */
| ScrollView::Color GetMatchColorFor | ( | FLOAT32 | Evidence | ) |
| Evidence | evidence value to return color for |
Definition at line 1527 of file intproto.cpp.
{
assert (Evidence >= 0.0);
assert (Evidence <= 1.0);
if (Evidence >= 0.90)
return ScrollView::WHITE;
else if (Evidence >= 0.75)
return ScrollView::GREEN;
else if (Evidence >= 0.50)
return ScrollView::RED;
else
return ScrollView::BLUE;
} /* GetMatchColorFor */
| void GetNextFill | ( | TABLE_FILLER * | Filler, |
| FILL_SPEC * | Fill | ||
| ) |
This routine returns (in Fill) the specification of the next line to be filled from Filler. FillerDone() should always be called before GetNextFill() to ensure that we do not run past the end of the fill table.
| Filler | filler to get next fill spec from |
| Fill | place to put spec for next fill |
Definition at line 1554 of file intproto.cpp.
{
FILL_SWITCH *Next;
/* compute the fill assuming no switches will be encountered */
Fill->AngleStart = Filler->AngleStart;
Fill->AngleEnd = Filler->AngleEnd;
Fill->X = Filler->X;
Fill->YStart = Filler->YStart >> 8;
Fill->YEnd = Filler->YEnd >> 8;
/* update the fill info and the filler for ALL switches at this X value */
Next = &(Filler->Switch[Filler->NextSwitch]);
while (Filler->X >= Next->X) {
Fill->X = Filler->X = Next->X;
if (Next->Type == StartSwitch) {
Fill->YStart = Next->Y;
Filler->StartDelta = Next->Delta;
Filler->YStart = Next->YInit;
}
else if (Next->Type == EndSwitch) {
Fill->YEnd = Next->Y;
Filler->EndDelta = Next->Delta;
Filler->YEnd = Next->YInit;
}
else { /* Type must be LastSwitch */
break;
}
Filler->NextSwitch++;
Next = &(Filler->Switch[Filler->NextSwitch]);
}
/* prepare the filler for the next call to this routine */
Filler->X++;
Filler->YStart += Filler->StartDelta;
Filler->YEnd += Filler->EndDelta;
} /* GetNextFill */
| void InitFeatureDisplayWindowIfReqd | ( | ) |
Initializes the feature display window if it is not already initialized.
Definition at line 1927 of file intproto.cpp.
{
if (FeatureDisplayWindow == NULL) {
FeatureDisplayWindow = CreateFeatureSpaceWindow("FeatureDisplayWindow",
50, 700);
}
}
| void InitIntMatchWindowIfReqd | ( | ) |
Initializes the int matcher window if it is not already initialized.
Definition at line 1895 of file intproto.cpp.
{
if (IntMatchWindow == NULL) {
IntMatchWindow = CreateFeatureSpaceWindow("IntMatchWindow", 50, 200);
SVMenuNode* popup_menu = new SVMenuNode();
popup_menu->AddChild("Debug Adapted classes", IDA_ADAPTIVE,
"x", "Class to debug");
popup_menu->AddChild("Debug Static classes", IDA_STATIC,
"x", "Class to debug");
popup_menu->AddChild("Debug Both", IDA_BOTH,
"x", "Class to debug");
popup_menu->AddChild("Debug Shape Index", IDA_SHAPE_INDEX,
"0", "Index to debug");
popup_menu->BuildMenu(IntMatchWindow, false);
}
}
| void InitProtoDisplayWindowIfReqd | ( | ) |
Initializes the proto display window if it is not already initialized.
Definition at line 1916 of file intproto.cpp.
{
if (ProtoDisplayWindow == NULL) {
ProtoDisplayWindow = CreateFeatureSpaceWindow("ProtoDisplayWindow",
550, 200);
}
}
| void InitTableFiller | ( | FLOAT32 | EndPad, |
| FLOAT32 | SidePad, | ||
| FLOAT32 | AnglePad, | ||
| PROTO | Proto, | ||
| TABLE_FILLER * | Filler | ||
| ) |
This routine computes a data structure (Filler) which can be used to fill in a rectangle surrounding the specified Proto.
| EndPad,SidePad,AnglePad | padding to add to proto |
| Proto | proto to create a filler for |
| Filler | place to put table filler |
Definition at line 1607 of file intproto.cpp.
{
FLOAT32 Angle;
FLOAT32 X, Y, HalfLength;
FLOAT32 Cos, Sin;
FLOAT32 XAdjust, YAdjust;
FPOINT Start, Switch1, Switch2, End;
int S1 = 0;
int S2 = 1;
Angle = Proto->Angle;
X = Proto->X;
Y = Proto->Y;
HalfLength = Proto->Length / 2.0;
Filler->AngleStart = CircBucketFor(Angle - AnglePad, AS, NB);
Filler->AngleEnd = CircBucketFor(Angle + AnglePad, AS, NB);
Filler->NextSwitch = 0;
if (fabs (Angle - 0.0) < HV_TOLERANCE || fabs (Angle - 0.5) < HV_TOLERANCE) {
/* horizontal proto - handle as special case */
Filler->X = Bucket8For(X - HalfLength - EndPad, XS, NB);
Filler->YStart = Bucket16For(Y - SidePad, YS, NB * 256);
Filler->YEnd = Bucket16For(Y + SidePad, YS, NB * 256);
Filler->StartDelta = 0;
Filler->EndDelta = 0;
Filler->Switch[0].Type = LastSwitch;
Filler->Switch[0].X = Bucket8For(X + HalfLength + EndPad, XS, NB);
} else if (fabs(Angle - 0.25) < HV_TOLERANCE ||
fabs(Angle - 0.75) < HV_TOLERANCE) {
/* vertical proto - handle as special case */
Filler->X = Bucket8For(X - SidePad, XS, NB);
Filler->YStart = Bucket16For(Y - HalfLength - EndPad, YS, NB * 256);
Filler->YEnd = Bucket16For(Y + HalfLength + EndPad, YS, NB * 256);
Filler->StartDelta = 0;
Filler->EndDelta = 0;
Filler->Switch[0].Type = LastSwitch;
Filler->Switch[0].X = Bucket8For(X + SidePad, XS, NB);
} else {
/* diagonal proto */
if ((Angle > 0.0 && Angle < 0.25) || (Angle > 0.5 && Angle < 0.75)) {
/* rising diagonal proto */
Angle *= 2.0 * PI;
Cos = fabs(cos(Angle));
Sin = fabs(sin(Angle));
/* compute the positions of the corners of the acceptance region */
Start.x = X - (HalfLength + EndPad) * Cos - SidePad * Sin;
Start.y = Y - (HalfLength + EndPad) * Sin + SidePad * Cos;
End.x = 2.0 * X - Start.x;
End.y = 2.0 * Y - Start.y;
Switch1.x = X - (HalfLength + EndPad) * Cos + SidePad * Sin;
Switch1.y = Y - (HalfLength + EndPad) * Sin - SidePad * Cos;
Switch2.x = 2.0 * X - Switch1.x;
Switch2.y = 2.0 * Y - Switch1.y;
if (Switch1.x > Switch2.x) {
S1 = 1;
S2 = 0;
}
/* translate into bucket positions and deltas */
Filler->X = Bucket8For(Start.x, XS, NB);
Filler->StartDelta = -(inT16) ((Cos / Sin) * 256);
Filler->EndDelta = (inT16) ((Sin / Cos) * 256);
XAdjust = BucketEnd(Filler->X, XS, NB) - Start.x;
YAdjust = XAdjust * Cos / Sin;
Filler->YStart = Bucket16For(Start.y - YAdjust, YS, NB * 256);
YAdjust = XAdjust * Sin / Cos;
Filler->YEnd = Bucket16For(Start.y + YAdjust, YS, NB * 256);
Filler->Switch[S1].Type = StartSwitch;
Filler->Switch[S1].X = Bucket8For(Switch1.x, XS, NB);
Filler->Switch[S1].Y = Bucket8For(Switch1.y, YS, NB);
XAdjust = Switch1.x - BucketStart(Filler->Switch[S1].X, XS, NB);
YAdjust = XAdjust * Sin / Cos;
Filler->Switch[S1].YInit = Bucket16For(Switch1.y - YAdjust, YS, NB * 256);
Filler->Switch[S1].Delta = Filler->EndDelta;
Filler->Switch[S2].Type = EndSwitch;
Filler->Switch[S2].X = Bucket8For(Switch2.x, XS, NB);
Filler->Switch[S2].Y = Bucket8For(Switch2.y, YS, NB);
XAdjust = Switch2.x - BucketStart(Filler->Switch[S2].X, XS, NB);
YAdjust = XAdjust * Cos / Sin;
Filler->Switch[S2].YInit = Bucket16For(Switch2.y + YAdjust, YS, NB * 256);
Filler->Switch[S2].Delta = Filler->StartDelta;
Filler->Switch[2].Type = LastSwitch;
Filler->Switch[2].X = Bucket8For(End.x, XS, NB);
} else {
/* falling diagonal proto */
Angle *= 2.0 * PI;
Cos = fabs(cos(Angle));
Sin = fabs(sin(Angle));
/* compute the positions of the corners of the acceptance region */
Start.x = X - (HalfLength + EndPad) * Cos - SidePad * Sin;
Start.y = Y + (HalfLength + EndPad) * Sin - SidePad * Cos;
End.x = 2.0 * X - Start.x;
End.y = 2.0 * Y - Start.y;
Switch1.x = X - (HalfLength + EndPad) * Cos + SidePad * Sin;
Switch1.y = Y + (HalfLength + EndPad) * Sin + SidePad * Cos;
Switch2.x = 2.0 * X - Switch1.x;
Switch2.y = 2.0 * Y - Switch1.y;
if (Switch1.x > Switch2.x) {
S1 = 1;
S2 = 0;
}
/* translate into bucket positions and deltas */
Filler->X = Bucket8For(Start.x, XS, NB);
Filler->StartDelta = -(inT16) ((Sin / Cos) * 256);
Filler->EndDelta = (inT16) ((Cos / Sin) * 256);
XAdjust = BucketEnd(Filler->X, XS, NB) - Start.x;
YAdjust = XAdjust * Sin / Cos;
Filler->YStart = Bucket16For(Start.y - YAdjust, YS, NB * 256);
YAdjust = XAdjust * Cos / Sin;
Filler->YEnd = Bucket16For(Start.y + YAdjust, YS, NB * 256);
Filler->Switch[S1].Type = EndSwitch;
Filler->Switch[S1].X = Bucket8For(Switch1.x, XS, NB);
Filler->Switch[S1].Y = Bucket8For(Switch1.y, YS, NB);
XAdjust = Switch1.x - BucketStart(Filler->Switch[S1].X, XS, NB);
YAdjust = XAdjust * Sin / Cos;
Filler->Switch[S1].YInit = Bucket16For(Switch1.y + YAdjust, YS, NB * 256);
Filler->Switch[S1].Delta = Filler->StartDelta;
Filler->Switch[S2].Type = StartSwitch;
Filler->Switch[S2].X = Bucket8For(Switch2.x, XS, NB);
Filler->Switch[S2].Y = Bucket8For(Switch2.y, YS, NB);
XAdjust = Switch2.x - BucketStart(Filler->Switch[S2].X, XS, NB);
YAdjust = XAdjust * Cos / Sin;
Filler->Switch[S2].YInit = Bucket16For(Switch2.y - YAdjust, YS, NB * 256);
Filler->Switch[S2].Delta = Filler->EndDelta;
Filler->Switch[2].Type = LastSwitch;
Filler->Switch[2].X = Bucket8For(End.x, XS, NB);
}
}
} /* InitTableFiller */
| INT_CLASS NewIntClass | ( | int | MaxNumProtos, |
| int | MaxNumConfigs | ||
| ) |
This routine creates a new integer class data structure and returns it. Sufficient space is allocated to handle the specified number of protos and configs.
| MaxNumProtos | number of protos to allocate space for |
| MaxNumConfigs | number of configs to allocate space for |
Definition at line 672 of file intproto.cpp.
{
INT_CLASS Class;
PROTO_SET ProtoSet;
int i;
assert(MaxNumConfigs <= MAX_NUM_CONFIGS);
Class = (INT_CLASS) Emalloc(sizeof(INT_CLASS_STRUCT));
Class->NumProtoSets = ((MaxNumProtos + PROTOS_PER_PROTO_SET - 1) /
PROTOS_PER_PROTO_SET);
assert(Class->NumProtoSets <= MAX_NUM_PROTO_SETS);
Class->NumProtos = 0;
Class->NumConfigs = 0;
for (i = 0; i < Class->NumProtoSets; i++) {
/* allocate space for a proto set, install in class, and initialize */
ProtoSet = (PROTO_SET) Emalloc(sizeof(PROTO_SET_STRUCT));
memset(ProtoSet, 0, sizeof(*ProtoSet));
Class->ProtoSets[i] = ProtoSet;
/* allocate space for the proto lengths and install in class */
}
if (MaxNumIntProtosIn (Class) > 0) {
Class->ProtoLengths =
(uinT8 *)Emalloc(MaxNumIntProtosIn (Class) * sizeof (uinT8));
memset(Class->ProtoLengths, 0,
MaxNumIntProtosIn(Class) * sizeof(*Class->ProtoLengths));
} else {
Class->ProtoLengths = NULL;
}
memset(Class->ConfigLengths, 0, sizeof(Class->ConfigLengths));
return (Class);
} /* NewIntClass */
| INT_TEMPLATES NewIntTemplates | ( | ) |
This routine allocates a new set of integer templates initialized to hold 0 classes.
Definition at line 732 of file intproto.cpp.
{
INT_TEMPLATES T;
int i;
T = (INT_TEMPLATES) Emalloc (sizeof (INT_TEMPLATES_STRUCT));
T->NumClasses = 0;
T->NumClassPruners = 0;
for (i = 0; i < MAX_NUM_CLASSES; i++)
ClassForClassId (T, i) = NULL;
return (T);
} /* NewIntTemplates */
| void RenderIntFeature | ( | ScrollView * | window, |
| const INT_FEATURE_STRUCT * | Feature, | ||
| ScrollView::Color | color | ||
| ) |
This routine renders the specified feature into ShapeList.
| window | to add feature rendering to |
| Feature | feature to be rendered |
| color | color to use for feature rendering |
Definition at line 1770 of file intproto.cpp.
{
FLOAT32 X, Y, Dx, Dy, Length;
window->Pen(color);
assert(Feature != NULL);
assert(color != 0);
X = Feature->X;
Y = Feature->Y;
Length = GetPicoFeatureLength() * 0.7 * INT_CHAR_NORM_RANGE;
// The -PI has no significant effect here, but the value of Theta is computed
// using BinaryAnglePlusPi in intfx.cpp.
Dx = (Length / 2.0) * cos((Feature->Theta / 256.0) * 2.0 * PI - PI);
Dy = (Length / 2.0) * sin((Feature->Theta / 256.0) * 2.0 * PI - PI);
window->SetCursor(X, Y);
window->DrawTo(X + Dx, Y + Dy);
} /* RenderIntFeature */
| void RenderIntProto | ( | ScrollView * | window, |
| INT_CLASS | Class, | ||
| PROTO_ID | ProtoId, | ||
| ScrollView::Color | color | ||
| ) |
This routine extracts the parameters of the specified proto from the class description and adds a rendering of the proto onto the ShapeList.
| window | ScrollView instance |
| Class | class that proto is contained in |
| ProtoId | id of proto to be rendered |
| color | color to render proto in |
Globals: none
Definition at line 1807 of file intproto.cpp.
{
PROTO_SET ProtoSet;
INT_PROTO Proto;
int ProtoSetIndex;
int ProtoWordIndex;
FLOAT32 Length;
int Xmin, Xmax, Ymin, Ymax;
FLOAT32 X, Y, Dx, Dy;
uinT32 ProtoMask;
int Bucket;
assert(ProtoId >= 0);
assert(Class != NULL);
assert(ProtoId < Class->NumProtos);
assert(color != 0);
window->Pen(color);
ProtoSet = Class->ProtoSets[SetForProto(ProtoId)];
ProtoSetIndex = IndexForProto(ProtoId);
Proto = &(ProtoSet->Protos[ProtoSetIndex]);
Length = (Class->ProtoLengths[ProtoId] *
GetPicoFeatureLength() * INT_CHAR_NORM_RANGE);
ProtoMask = PPrunerMaskFor(ProtoId);
ProtoWordIndex = PPrunerWordIndexFor(ProtoId);
// find the x and y extent of the proto from the proto pruning table
Xmin = Ymin = NUM_PP_BUCKETS;
Xmax = Ymax = 0;
for (Bucket = 0; Bucket < NUM_PP_BUCKETS; Bucket++) {
if (ProtoMask & ProtoSet->ProtoPruner[PRUNER_X][Bucket][ProtoWordIndex]) {
UpdateRange(Bucket, &Xmin, &Xmax);
}
if (ProtoMask & ProtoSet->ProtoPruner[PRUNER_Y][Bucket][ProtoWordIndex]) {
UpdateRange(Bucket, &Ymin, &Ymax);
}
}
X = (Xmin + Xmax + 1) / 2.0 * PROTO_PRUNER_SCALE;
Y = (Ymin + Ymax + 1) / 2.0 * PROTO_PRUNER_SCALE;
// The -PI has no significant effect here, but the value of Theta is computed
// using BinaryAnglePlusPi in intfx.cpp.
Dx = (Length / 2.0) * cos((Proto->Angle / 256.0) * 2.0 * PI - PI);
Dy = (Length / 2.0) * sin((Proto->Angle / 256.0) * 2.0 * PI - PI);
window->SetCursor(X - Dx, Y - Dy);
window->DrawTo(X + Dx, Y + Dy);
} /* RenderIntProto */
| int TruncateParam | ( | FLOAT32 | Param, |
| int | Min, | ||
| int | Max, | ||
| char * | Id | ||
| ) |
This routine truncates Param to lie within the range of Min-Max inclusive. If a truncation is performed, and Id is not null, an warning message is printed.
| Param | parameter value to be truncated |
| Min,Max | parameter limits (inclusive) |
| Id | string id of parameter for error messages |
Globals: none
Definition at line 1874 of file intproto.cpp.
| void UpdateMatchDisplay | ( | ) |
This routine clears the global feature and proto display lists.
Globals:
Definition at line 473 of file intproto.cpp.
{
if (IntMatchWindow != NULL)
IntMatchWindow->Update();
} /* ClearMatchDisplay */
| double classify_cp_angle_pad_loose = 45.0 |
"Class Pruner Angle Pad Loose"
Definition at line 192 of file intproto.cpp.
| double classify_cp_angle_pad_medium = 20.0 |
"Class Pruner Angle Pad Medium"
Definition at line 194 of file intproto.cpp.
| double classify_cp_angle_pad_tight = 10.0 |
"CLass Pruner Angle Pad Tight"
Definition at line 196 of file intproto.cpp.
| double classify_cp_end_pad_loose = 0.5 |
"Class Pruner End Pad Loose"
Definition at line 197 of file intproto.cpp.
| double classify_cp_end_pad_medium = 0.5 |
"Class Pruner End Pad Medium"
Definition at line 198 of file intproto.cpp.
| double classify_cp_end_pad_tight = 0.5 |
"Class Pruner End Pad Tight"
Definition at line 199 of file intproto.cpp.
| double classify_cp_side_pad_loose = 2.5 |
"Class Pruner Side Pad Loose"
Definition at line 200 of file intproto.cpp.
| double classify_cp_side_pad_medium = 1.2 |
"Class Pruner Side Pad Medium"
Definition at line 201 of file intproto.cpp.
| double classify_cp_side_pad_tight = 0.6 |
"Class Pruner Side Pad Tight"
Definition at line 202 of file intproto.cpp.
| int classify_num_cp_levels = 3 |
"Number of Class Pruner Levels"
Definition at line 190 of file intproto.cpp.
| double classify_pp_angle_pad = 45.0 |
"Proto Pruner Angle Pad"
Definition at line 203 of file intproto.cpp.
| double classify_pp_end_pad = 0.5 |
"Proto Prune End Pad"
Definition at line 204 of file intproto.cpp.
| double classify_pp_side_pad = 2.5 |
"Proto Pruner Side Pad"
Definition at line 205 of file intproto.cpp.
| ScrollView* FeatureDisplayWindow = NULL |
Definition at line 182 of file intproto.cpp.
| ScrollView* IntMatchWindow = NULL |
Definition at line 181 of file intproto.cpp.
| ScrollView* ProtoDisplayWindow = NULL |
Definition at line 183 of file intproto.cpp.