training/mergenf.cpp

Go to the documentation of this file.
00001 
00019 /*----------------------------------------------------------------------------
00020                Include Files and Type Defines
00021 ----------------------------------------------------------------------------*/
00022 #include "mergenf.h"
00023 #include "general.h"
00024 #include "efio.h"
00025 #include "clusttool.h"
00026 #include "cluster.h"
00027 #include "oldlist.h"
00028 #include "protos.h"
00029 #include "minmax.h"
00030 #include "ocrfeatures.h"
00031 #include "debug.h"
00032 #include "const.h"
00033 #include "featdefs.h"
00034 #include "intproto.h"
00035 
00036 #include <stdio.h>
00037 #include <string.h>
00038 #include <math.h>
00039 
00040 
00041 /*----------------------------------------------------------------------------
00042                Variables
00043 -----------------------------------------------------------------------------*/
00044 
00047 /*-------------------once in subfeat---------------------------------*/
00048 make_float_var (AngleMatchScale, 1.0, MakeAngleMatchScale,
00049                 7, 2, SetAngleMatchScale,  "Angle Match Scale ...")
00050 
00051 make_float_var (SimilarityMidpoint, 0.0075, MakeSimilarityMidpoint,
00052                 7, 3, SetSimilarityMidpoint,  "Similarity Midpoint ...")
00053 
00054 make_float_var (SimilarityCurl, 2.0, MakeSimilarityCurl,
00055                 7, 4, SetSimilarityCurl,  "Similarity Curl ...")
00056 
00057 /*-----------------------------once in fasttrain----------------------------------*/
00058 make_float_var (TangentBBoxPad, 0.5, MakeTangentBBoxPad,
00059                 15, 3, SetTangentBBoxPad,  "Tangent bounding box pad ...")
00060 
00061 make_float_var (OrthogonalBBoxPad, 2.5, MakeOrthogonalBBoxPad,
00062                 15, 4, SetOrthogonalBBoxPad,  "Orthogonal bounding box pad ...")
00063 
00064 make_float_var (AnglePad, 45.0, MakeAnglePad,
00065                 15, 5, SetAnglePad,  "Angle pad ...")
00068 /*----------------------------------------------------------------------------
00069             Global Data Definitions and Declarations
00070 ----------------------------------------------------------------------------*/
00071 //int row_number;       /* kludge due to linking problems */
00072 
00073 /*----------------------------------------------------------------------------
00074                      Public Code
00075 ----------------------------------------------------------------------------*/
00076 /*---------------------------------------------------------------------------*/
00077 
00094 FLOAT32 CompareProtos (
00095      PROTO  p1,
00096     PROTO   p2)
00097 {
00098    FEATURE  Feature;
00099    FLOAT32  WorstEvidence = WORST_EVIDENCE;
00100    FLOAT32  Evidence;
00101    FLOAT32  Angle, Length;
00102 
00103    /* if p1 and p2 are not close in length, don't let them match */
00104    Length = fabs (ProtoLength (p1) - ProtoLength (p2));
00105    if (Length > MAX_LENGTH_MISMATCH)
00106       return (0.0);
00107 
00108    /* create a dummy pico-feature to be used for comparisons */
00109    Feature = NewFeature (&PicoFeatDesc);
00110    ParamOf (Feature, PicoFeatDir) = ProtoAngle (p1);
00111 
00112    /* convert angle to radians */
00113    Angle = ProtoAngle (p1) * 2.0 * PI;
00114 
00115    /* find distance from center of p1 to 1/2 picofeat from end */
00116    Length = ProtoLength (p1) / 2.0 - GetPicoFeatureLength () / 2.0;
00117    if (Length < 0) Length = 0;
00118 
00119    /* set the dummy pico-feature at one end of p1 and match it to p2 */
00120    ParamOf (Feature, PicoFeatX) = ProtoX (p1) + cos (Angle) * Length;
00121    ParamOf (Feature, PicoFeatY) = ProtoY (p1) + sin (Angle) * Length;
00122    if (DummyFastMatch (Feature, p2))
00123     {
00124       Evidence = SubfeatureEvidence (Feature, p2);
00125       if (Evidence < WorstEvidence)
00126          WorstEvidence = Evidence;
00127     }
00128    else
00129     {
00130       FreeFeature (Feature);
00131       return (0.0);
00132     }
00133 
00134    /* set the dummy pico-feature at the other end of p1 and match it to p2 */
00135    ParamOf (Feature, PicoFeatX) = ProtoX (p1) - cos (Angle) * Length;
00136    ParamOf (Feature, PicoFeatY) = ProtoY (p1) - sin (Angle) * Length;
00137    if (DummyFastMatch (Feature, p2))
00138     {
00139       Evidence = SubfeatureEvidence (Feature, p2);
00140       if (Evidence < WorstEvidence)
00141          WorstEvidence = Evidence;
00142     }
00143    else
00144     {
00145       FreeFeature (Feature);
00146       return (0.0);
00147     }
00148 
00149    FreeFeature (Feature);
00150    return (WorstEvidence);
00151 
00152 }// CompareProtos
00153 
00154 /*---------------------------------------------------------------------------*/
00155 
00167 void ComputeMergedProto (
00168      PROTO  p1,
00169     PROTO   p2,
00170      FLOAT32   w1,
00171     FLOAT32 w2,
00172      PROTO  MergedProto)
00173 {
00174    FLOAT32  TotalWeight;
00175 
00176    TotalWeight = w1 + w2;
00177    w1 /= TotalWeight;
00178    w2 /= TotalWeight;
00179 
00180    ProtoX      (MergedProto) = ProtoX      (p1) * w1 + ProtoX      (p2) * w2;
00181    ProtoY      (MergedProto) = ProtoY      (p1) * w1 + ProtoY      (p2) * w2;
00182    ProtoLength (MergedProto) = ProtoLength (p1) * w1 + ProtoLength (p2) * w2;
00183    ProtoAngle  (MergedProto) = ProtoAngle  (p1) * w1 + ProtoAngle  (p2) * w2;
00184    FillABC     (MergedProto);
00185 
00186 }// ComputeMergedProto
00187 
00188 /*---------------------------------------------------------------------------*/
00189 
00202 int FindClosestExistingProto (
00203      CLASS_TYPE   Class,
00204      int          NumMerged[],
00205      PROTOTYPE *Prototype)
00206 {
00207    PROTO_STRUCT   NewProto;
00208    PROTO_STRUCT   MergedProto;
00209    int      Pid;
00210    PROTO    Proto;
00211    int      BestProto;
00212    FLOAT32  BestMatch;
00213    FLOAT32  Match, OldMatch, NewMatch;
00214 
00215    MakeNewFromOld (&NewProto, Prototype);
00216 
00217    BestProto = NO_PROTO;
00218    BestMatch = WORST_MATCH_ALLOWED;
00219    for (Pid = 0; Pid < NumProtosIn (Class); Pid++)
00220    {
00221       Proto  = ProtoIn (Class, Pid);
00222       ComputeMergedProto (Proto, &NewProto,
00223          (FLOAT32) NumMerged[Pid], 1.0, &MergedProto);
00224       OldMatch = CompareProtos (Proto, &MergedProto);
00225       NewMatch = CompareProtos (&NewProto, &MergedProto);
00226       Match = MIN (OldMatch, NewMatch);
00227       if (Match > BestMatch)
00228       {
00229          BestProto = Pid;
00230          BestMatch = Match;
00231       }
00232    }//for
00233    return (BestProto);
00234 
00235 }// FindClosestExistingProto
00236 
00237 /*---------------------------------------------------------------------------*/
00238 
00247 void MakeNewFromOld (
00248      PROTO  New,
00249      PROTOTYPE *Old)
00250 {
00251    ProtoX      (New) = CenterX       (Old->Mean);
00252    ProtoY      (New) = CenterY       (Old->Mean);
00253    ProtoLength (New) = LengthOf      (Old->Mean);
00254    ProtoAngle  (New) = OrientationOf (Old->Mean);
00255    FillABC     (New);
00256 
00257 }// MakeNewFromOld
00258 
00259 /*-------------------once in subfeat---------------------------------*/
00265 void InitSubfeatureVars ()
00266 {
00267    MakeAngleMatchScale     ();
00268    MakeSimilarityCurl      ();
00269    MakeSimilarityMidpoint  ();
00270 }
00271 
00272 
00281 FLOAT32 SubfeatureEvidence (
00282    FEATURE     Feature,
00283    PROTO       Proto)
00284 {
00285    float       Distance;
00286    float       Dangle;
00287 
00288    Dangle   = ProtoAngle (Proto) - ParamOf(Feature, PicoFeatDir);
00289    if (Dangle < -0.5) Dangle += 1.0;
00290    if (Dangle >  0.5) Dangle -= 1.0;
00291    Dangle   *= AngleMatchScale;
00292 
00293    Distance = CoefficientA (Proto) * ParamOf(Feature, PicoFeatX) +
00294       CoefficientB (Proto) * ParamOf(Feature, PicoFeatY) +
00295       CoefficientC (Proto);
00296 
00297    return (EvidenceOf (Distance * Distance + Dangle * Dangle));
00298 }// SubfeatureEvidence
00299 
00320 FLOAT32 EvidenceOf (
00321   register FLOAT32   Similarity)
00322 {
00323 
00324    Similarity /= SimilarityMidpoint;
00325 
00326    if (SimilarityCurl == 3)
00327       Similarity = Similarity * Similarity * Similarity;
00328    else if (SimilarityCurl == 2)
00329       Similarity = Similarity * Similarity;
00330    else
00331       Similarity = pow (Similarity, SimilarityCurl);
00332 
00333    return (1.0 / (1.0 + Similarity));
00334 }// EvidenceOf
00335 
00336 /*-----------------------------once in fasttrain----------------------------------*/
00342 void InitFastTrainerVars ()
00343 {
00344    MakeTangentBBoxPad ();
00345    MakeOrthogonalBBoxPad ();
00346    MakeAnglePad ();
00347 
00348 }// InitFastTrainerVars
00349 
00350 /*---------------------------------------------------------------------------*/
00351 
00363 BOOL8 DummyFastMatch (
00364      FEATURE   Feature,
00365      PROTO  Proto)
00366 {
00367    FRECT    BoundingBox;
00368    FLOAT32  MaxAngleError;
00369    FLOAT32  AngleError;
00370 
00371    MaxAngleError = AnglePad / 360.0;
00372    AngleError = fabs (ProtoAngle (Proto) - ParamOf (Feature, PicoFeatDir));
00373    if (AngleError > 0.5)
00374       AngleError = 1.0 - AngleError;
00375 
00376    if (AngleError > MaxAngleError)
00377       return (FALSE);
00378 
00379    ComputePaddedBoundingBox (Proto,
00380       TangentBBoxPad * GetPicoFeatureLength (),
00381       OrthogonalBBoxPad * GetPicoFeatureLength (),
00382       &BoundingBox);
00383 
00384    return (PointInside (&BoundingBox,
00385       ParamOf (Feature, PicoFeatX),
00386       ParamOf (Feature, PicoFeatY)));
00387 
00388 }// DummyFastMatch
00389 
00390 /*----------------------------------------------------------------------------*/
00391 
00407 void ComputePaddedBoundingBox (
00408      PROTO  Proto,
00409      FLOAT32   TangentPad,
00410     FLOAT32 OrthogonalPad,
00411      FRECT  *BoundingBox)
00412 {
00413    FLOAT32  Pad, Length, Angle;
00414    FLOAT32  CosOfAngle, SinOfAngle;
00415 
00416    Length     = ProtoLength (Proto) / 2.0 + TangentPad;
00417    Angle      = ProtoAngle (Proto) * 2.0 * PI;
00418    CosOfAngle = fabs (cos (Angle));
00419    SinOfAngle = fabs (sin (Angle));
00420 
00421    Pad = MAX (CosOfAngle * Length, SinOfAngle * OrthogonalPad);
00422    BoundingBox->MinX = ProtoX (Proto) - Pad;
00423    BoundingBox->MaxX = ProtoX (Proto) + Pad;
00424 
00425    Pad = MAX (SinOfAngle * Length, CosOfAngle * OrthogonalPad);
00426    BoundingBox->MinY = ProtoY (Proto) - Pad;
00427    BoundingBox->MaxY = ProtoY (Proto) + Pad;
00428 
00429 }// ComputePaddedBoundingBox
00430 
00431 /*--------------------------------------------------------------------------*/
00432 
00443 BOOL8 PointInside (
00444      FRECT  *Rectangle,
00445      FLOAT32   X,
00446     FLOAT32 Y)
00447 {
00448    if (X < Rectangle->MinX) return (FALSE);
00449    if (X > Rectangle->MaxX) return (FALSE);
00450    if (Y < Rectangle->MinY) return (FALSE);
00451    if (Y > Rectangle->MaxY) return (FALSE);
00452    return (TRUE);
00453 
00454 }// PointInside

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