classify/normmatch.cpp

Go to the documentation of this file.
00001 
00019 /* =================
00020           Include Files and Type Defines
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 /* define default filenames for training data */
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           Private Function Prototypes
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         Global Data Definitions and Declarations
00063  ==================== */
00065 static NORM_PROTOS *NormProtos;
00066 
00068 static const char *NormProtoFile = NORM_PROTO_FILE;
00069 
00072 /* control knobs used to control the normalization adjustment process */
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 //extern char *demodir;
00079 /* =================
00080               Public Code
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   /* handle requests for classification as noise */
00105   if (ClassId == NO_CLASS) {
00106     /* kludge - clean up constants and make into control knobs later */
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 }                                /* ComputeNormMatch */
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 }                                /* GetNormProtos */
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 }                                /* InitNormProtoVars */
00204 
00205 
00206 /* =================
00207     Private Code
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 }                                /* PrintNormMatch */
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   /* allocate and initialization data structure */
00285   NormProtos = (NORM_PROTOS *) Emalloc (sizeof (NORM_PROTOS));
00286   for (i = 0; i <= MAX_CLASS_ID; i++)
00287     NormProtos->Protos[i] = NIL;
00288 
00289   /* read file header and save in data structure */
00290   NormProtos->NumParams = ReadSampleSize (File);
00291   NormProtos->ParamDesc = ReadParamDesc (File, NormProtos->NumParams);
00292 
00293   /* read protos for each class into a separate list */
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 }                                /* ReadNormProtos */

Generated on Wed Feb 28 19:49:10 2007 for Tesseract by  doxygen 1.5.1