00001
00019
00020
00021
00022 #include "normmatch.h"
00023 #include "clusttool.h"
00024 #include "normfeat.h"
00025 #include "debug.h"
00026 #include "const.h"
00027 #include "efio.h"
00028 #include "emalloc.h"
00029 #include "globals.h"
00030 #include "scanutils.h"
00031
00032 #include <stdio.h>
00033 #include <math.h>
00034
00035
00036 #define NORM_PROTO_FILE "tessdata/normproto"
00037
00042 typedef struct
00043 {
00044 int NumParams;
00045 PARAM_DESC *ParamDesc;
00046 LIST Protos[MAX_CLASS_ID + 1];
00047 } NORM_PROTOS;
00048
00049
00050
00051
00052 FLOAT32 NormEvidenceOf(register FLOAT32 NormAdj);
00053
00054 void PrintNormMatch(FILE *File,
00055 int NumParams,
00056 PROTOTYPE *Proto,
00057 FEATURE Feature);
00058
00059 NORM_PROTOS *ReadNormProtos(FILE *File);
00060
00061
00062
00063
00065 static NORM_PROTOS *NormProtos;
00066
00068 static const char *NormProtoFile = NORM_PROTO_FILE;
00069
00072
00073 make_float_var (NormAdjMidpoint, 32.0, MakeNormAdjMidpoint,
00074 15, 16, SetNormAdjMidpoint, "Norm adjust midpoint ...")
00075 make_float_var (NormAdjCurl, 2.0, MakeNormAdjCurl,
00076 15, 17, SetNormAdjCurl, "Norm adjust curl ...")
00078
00079
00080
00081
00082
00096 FLOAT32 ComputeNormMatch(CLASS_ID ClassId, FEATURE Feature, BOOL8 DebugMatch) {
00097 LIST Protos;
00098 FLOAT32 BestMatch;
00099 FLOAT32 Match;
00100 FLOAT32 Delta;
00101 PROTOTYPE *Proto;
00102 int ProtoId;
00103
00104
00105 if (ClassId == NO_CLASS) {
00106
00107 Match = (ParamOf (Feature, CharNormLength) *
00108 ParamOf (Feature, CharNormLength) * 500.0 +
00109 ParamOf (Feature, CharNormRx) *
00110 ParamOf (Feature, CharNormRx) * 8000.0 +
00111 ParamOf (Feature, CharNormRy) *
00112 ParamOf (Feature, CharNormRy) * 8000.0);
00113 return (1.0 - NormEvidenceOf (Match));
00114 }
00115
00116 BestMatch = MAX_FLOAT32;
00117 Protos = NormProtos->Protos[ClassId];
00118
00119 if (DebugMatch) {
00120 cprintf ("\nFeature = ");
00121 WriteFeature(stdout, Feature);
00122 }
00123
00124 ProtoId = 0;
00125 iterate(Protos) {
00126 Proto = (PROTOTYPE *) first (Protos);
00127 Delta = ParamOf (Feature, CharNormY) - Proto->Mean[CharNormY];
00128 Match = Delta * Delta * Proto->Weight.Elliptical[CharNormY];
00129 Delta = ParamOf (Feature, CharNormRx) - Proto->Mean[CharNormRx];
00130 Match += Delta * Delta * Proto->Weight.Elliptical[CharNormRx];
00131
00132 if (Match < BestMatch)
00133 BestMatch = Match;
00134
00135 if (DebugMatch) {
00136 cprintf ("Proto %1d = ", ProtoId);
00137 WriteNFloats (stdout, NormProtos->NumParams, Proto->Mean);
00138 cprintf (" var = ");
00139 WriteNFloats (stdout, NormProtos->NumParams,
00140 Proto->Variance.Elliptical);
00141 cprintf (" match = ");
00142 PrintNormMatch (stdout, NormProtos->NumParams, Proto, Feature);
00143 }
00144 ProtoId++;
00145 }
00146 return (1.0 - NormEvidenceOf (BestMatch));
00147 }
00148
00149
00150
00163 void GetNormProtos() {
00164 FILE *File;
00165 char name[1024];
00166
00167 strcpy(name, demodir);
00168 strcat(name, NormProtoFile);
00169 File = Efopen (name, "r");
00170 NormProtos = ReadNormProtos (File);
00171 fclose(File);
00172
00173 }
00174
00175 void FreeNormProtos() {
00176 if (NormProtos != NULL) {
00177 for (int i = 0; i <= MAX_CLASS_ID; i++)
00178 FreeProtoList(&NormProtos->Protos[i]);
00179 Efree(NormProtos->ParamDesc);
00180 Efree(NormProtos);
00181 NormProtos = NULL;
00182 }
00183 }
00184
00185
00195 void InitNormProtoVars() {
00196 VALUE dummy;
00197
00198 string_variable (NormProtoFile, "NormProtoFile", NORM_PROTO_FILE);
00199
00200 MakeNormAdjMidpoint();
00201 MakeNormAdjCurl();
00202
00203 }
00204
00205
00206
00207
00208
00218 FLOAT32 NormEvidenceOf(register FLOAT32 NormAdj) {
00219 NormAdj /= NormAdjMidpoint;
00220
00221 if (NormAdjCurl == 3)
00222 NormAdj = NormAdj * NormAdj * NormAdj;
00223 else if (NormAdjCurl == 2)
00224 NormAdj = NormAdj * NormAdj;
00225 else
00226 NormAdj = pow (NormAdj, NormAdjCurl);
00227 return (1.0 / (1.0 + NormAdj));
00228 }
00229
00230
00231
00243 void PrintNormMatch(FILE *File,
00244 int NumParams,
00245 PROTOTYPE *Proto,
00246 FEATURE Feature) {
00247 int i;
00248 FLOAT32 ParamMatch;
00249 FLOAT32 TotalMatch;
00250
00251 for (i = 0, TotalMatch = 0.0; i < NumParams; i++) {
00252 ParamMatch = ((ParamOf (Feature, i) - Mean (Proto, i)) /
00253 StandardDeviation (Proto, i));
00254
00255 fprintf (File, " %6.1f", ParamMatch);
00256
00257 if (i == CharNormY || i == CharNormRx)
00258 TotalMatch += ParamMatch * ParamMatch;
00259 }
00260 fprintf (File, " --> %6.1f (%4.2f)\n",
00261 TotalMatch, NormEvidenceOf (TotalMatch));
00262
00263 }
00264
00265
00266
00277 NORM_PROTOS *ReadNormProtos(FILE *File) {
00278 NORM_PROTOS *NormProtos;
00279 int i;
00280 char ClassId[2];
00281 LIST Protos;
00282 int NumProtos;
00283
00284
00285 NormProtos = (NORM_PROTOS *) Emalloc (sizeof (NORM_PROTOS));
00286 for (i = 0; i <= MAX_CLASS_ID; i++)
00287 NormProtos->Protos[i] = NIL;
00288
00289
00290 NormProtos->NumParams = ReadSampleSize (File);
00291 NormProtos->ParamDesc = ReadParamDesc (File, NormProtos->NumParams);
00292
00293
00294 while (fscanf (File, "%1s %d", ClassId, &NumProtos) == 2) {
00295 Protos = NormProtos->Protos[ClassId[0]];
00296 for (i = 0; i < NumProtos; i++)
00297 Protos =
00298 push_last (Protos, ReadPrototype (File, NormProtos->NumParams));
00299 NormProtos->Protos[ClassId[0]] = Protos;
00300 }
00301
00302 return (NormProtos);
00303
00304 }