tesseract  5.0.0-alpha-619-ge9db
mergenf.cpp File Reference
#include <algorithm>
#include <cfloat>
#include <cmath>
#include <cstdio>
#include <cstring>
#include "mergenf.h"
#include "clusttool.h"
#include "cluster.h"
#include "oldlist.h"
#include "protos.h"
#include "ocrfeatures.h"
#include "featdefs.h"
#include "intproto.h"
#include "params.h"

Go to the source code of this file.

Macros

#define _USE_MATH_DEFINES
 

Functions

float CompareProtos (PROTO p1, PROTO p2)
 
void ComputeMergedProto (PROTO p1, PROTO p2, float w1, float w2, PROTO MergedProto)
 
int FindClosestExistingProto (CLASS_TYPE Class, int NumMerged[], PROTOTYPE *Prototype)
 
void MakeNewFromOld (PROTO New, PROTOTYPE *Old)
 
SubfeatureEvidence

Compare a feature to a prototype. Print the result.

float SubfeatureEvidence (FEATURE Feature, PROTO Proto)
 
EvidenceOf

Return the new type of evidence number corresponding to this distance value. This number is no longer based on the chi squared approximation. The equation that represents the transform is: 1 / (1 + (sim / midpoint) ^ curl)

double EvidenceOf (double Similarity)
 
bool DummyFastMatch (FEATURE Feature, PROTO Proto)
 
void ComputePaddedBoundingBox (PROTO Proto, float TangentPad, float OrthogonalPad, FRECT *BoundingBox)
 
bool PointInside (FRECT *Rectangle, float X, float Y)
 

Macro Definition Documentation

◆ _USE_MATH_DEFINES

#define _USE_MATH_DEFINES

Definition at line 17 of file mergenf.cpp.

Function Documentation

◆ CompareProtos()

float CompareProtos ( PROTO  p1,
PROTO  p2 
)

Compare protos p1 and p2 and return an estimate of the worst evidence rating that will result for any part of p1 that is compared to p2. In other words, if p1 were broken into pico-features and each pico-feature was matched to p2, what is the worst evidence rating that will be achieved for any pico-feature.

Parameters
p1,p2protos to be compared

Globals: none

Returns
Worst possible result when matching p1 to p2.

Definition at line 63 of file mergenf.cpp.

63  {
64  FEATURE Feature;
65  float WorstEvidence = WORST_EVIDENCE;
66  float Evidence;
67  float Angle, Length;
68 
69  /* if p1 and p2 are not close in length, don't let them match */
70  Length = fabs (p1->Length - p2->Length);
71  if (Length > MAX_LENGTH_MISMATCH)
72  return (0.0);
73 
74  /* create a dummy pico-feature to be used for comparisons */
75  Feature = NewFeature (&PicoFeatDesc);
76  Feature->Params[PicoFeatDir] = p1->Angle;
77 
78  /* convert angle to radians */
79  Angle = p1->Angle * 2.0 * M_PI;
80 
81  /* find distance from center of p1 to 1/2 picofeat from end */
82  Length = p1->Length / 2.0 - GetPicoFeatureLength () / 2.0;
83  if (Length < 0) Length = 0;
84 
85  /* set the dummy pico-feature at one end of p1 and match it to p2 */
86  Feature->Params[PicoFeatX] = p1->X + cos (Angle) * Length;
87  Feature->Params[PicoFeatY] = p1->Y + sin (Angle) * Length;
88  if (DummyFastMatch (Feature, p2)) {
89  Evidence = SubfeatureEvidence (Feature, p2);
90  if (Evidence < WorstEvidence)
91  WorstEvidence = Evidence;
92  } else {
93  FreeFeature(Feature);
94  return 0.0;
95  }
96 
97  /* set the dummy pico-feature at the other end of p1 and match it to p2 */
98  Feature->Params[PicoFeatX] = p1->X - cos (Angle) * Length;
99  Feature->Params[PicoFeatY] = p1->Y - sin (Angle) * Length;
100  if (DummyFastMatch (Feature, p2)) {
101  Evidence = SubfeatureEvidence (Feature, p2);
102  if (Evidence < WorstEvidence)
103  WorstEvidence = Evidence;
104  } else {
105  FreeFeature(Feature);
106  return 0.0;
107  }
108 
109  FreeFeature (Feature);
110  return (WorstEvidence);
111 
112 } /* CompareProtos */

◆ ComputeMergedProto()

void ComputeMergedProto ( PROTO  p1,
PROTO  p2,
float  w1,
float  w2,
PROTO  MergedProto 
)

This routine computes a proto which is the weighted average of protos p1 and p2. The new proto is returned in MergedProto.

Parameters
p1,p2protos to be merged
w1,w2weight of each proto
MergedProtoplace to put resulting merged proto

Definition at line 123 of file mergenf.cpp.

127  {
128  float TotalWeight;
129 
130  TotalWeight = w1 + w2;
131  w1 /= TotalWeight;
132  w2 /= TotalWeight;
133 
134  MergedProto->X = p1->X * w1 + p2->X * w2;
135  MergedProto->Y = p1->Y * w1 + p2->Y * w2;
136  MergedProto->Length = p1->Length * w1 + p2->Length * w2;
137  MergedProto->Angle = p1->Angle * w1 + p2->Angle * w2;
138  FillABC(MergedProto);
139 } /* ComputeMergedProto */

◆ ComputePaddedBoundingBox()

void ComputePaddedBoundingBox ( PROTO  Proto,
float  TangentPad,
float  OrthogonalPad,
FRECT BoundingBox 
)

This routine computes a bounding box that encloses the specified proto along with some padding. The amount of padding is specified as separate distances in the tangential and orthogonal directions.

Parameters
Protoproto to compute bounding box for
TangentPadamount of pad to add in direction of segment
OrthogonalPadamount of pad to add orthogonal to segment
[out]BoundingBoxplace to put results

Definition at line 293 of file mergenf.cpp.

294  {
295  float Length = Proto->Length / 2.0 + TangentPad;
296  float Angle = Proto->Angle * 2.0 * M_PI;
297  float CosOfAngle = fabs(cos(Angle));
298  float SinOfAngle = fabs(sin(Angle));
299 
300  float Pad = std::max(CosOfAngle * Length, SinOfAngle * OrthogonalPad);
301  BoundingBox->MinX = Proto->X - Pad;
302  BoundingBox->MaxX = Proto->X + Pad;
303 
304  Pad = std::max(SinOfAngle * Length, CosOfAngle * OrthogonalPad);
305  BoundingBox->MinY = Proto->Y - Pad;
306  BoundingBox->MaxY = Proto->Y + Pad;
307 
308 } /* ComputePaddedBoundingBox */

◆ DummyFastMatch()

bool DummyFastMatch ( FEATURE  Feature,
PROTO  Proto 
)

This routine returns true if Feature would be matched by a fast match table built from Proto.

Parameters
Featurefeature to be "fast matched" to proto
Protoproto being "fast matched" against

Globals:

  • training_tangent_bbox_pad bounding box pad tangent to proto
  • training_orthogonal_bbox_pad bounding box pad orthogonal to proto
Returns
true if feature could match Proto.

Definition at line 259 of file mergenf.cpp.

260 {
261  FRECT BoundingBox;
262  float MaxAngleError;
263  float AngleError;
264 
265  MaxAngleError = training_angle_pad / 360.0;
266  AngleError = fabs (Proto->Angle - Feature->Params[PicoFeatDir]);
267  if (AngleError > 0.5)
268  AngleError = 1.0 - AngleError;
269 
270  if (AngleError > MaxAngleError)
271  return false;
272 
274  training_tangent_bbox_pad * GetPicoFeatureLength (),
275  training_orthogonal_bbox_pad * GetPicoFeatureLength (),
276  &BoundingBox);
277 
278  return PointInside(&BoundingBox, Feature->Params[PicoFeatX],
279  Feature->Params[PicoFeatY]);
280 } /* DummyFastMatch */

◆ EvidenceOf()

double EvidenceOf ( double  Similarity)

Definition at line 232 of file mergenf.cpp.

232  {
233 
234  Similarity /= training_similarity_midpoint;
235 
236  if (training_similarity_curl == 3)
237  Similarity = Similarity * Similarity * Similarity;
238  else if (training_similarity_curl == 2)
239  Similarity = Similarity * Similarity;
240  else
241  Similarity = pow (Similarity, training_similarity_curl);
242 
243  return (1.0 / (1.0 + Similarity));
244 }

◆ FindClosestExistingProto()

int FindClosestExistingProto ( CLASS_TYPE  Class,
int  NumMerged[],
PROTOTYPE Prototype 
)

This routine searches through all of the prototypes in Class and returns the id of the proto which would provide the best approximation of Prototype. If no close approximation can be found, NO_PROTO is returned.

Parameters
Classclass to search for matching old proto in
NumMerged# of protos merged into each proto of Class
Prototypenew proto to find match for

Globals: none

Returns
Id of closest proto in Class or NO_PROTO.

Definition at line 155 of file mergenf.cpp.

156  {
157  PROTO_STRUCT NewProto;
158  PROTO_STRUCT MergedProto;
159  int Pid;
160  PROTO Proto;
161  int BestProto;
162  float BestMatch;
163  float Match, OldMatch, NewMatch;
164 
165  MakeNewFromOld (&NewProto, Prototype);
166 
167  BestProto = NO_PROTO;
168  BestMatch = WORST_MATCH_ALLOWED;
169  for (Pid = 0; Pid < Class->NumProtos; Pid++) {
170  Proto = ProtoIn(Class, Pid);
171  ComputeMergedProto(Proto, &NewProto,
172  static_cast<float>(NumMerged[Pid]), 1.0, &MergedProto);
173  OldMatch = CompareProtos(Proto, &MergedProto);
174  NewMatch = CompareProtos(&NewProto, &MergedProto);
175  Match = std::min(OldMatch, NewMatch);
176  if (Match > BestMatch) {
177  BestProto = Pid;
178  BestMatch = Match;
179  }
180  }
181  return BestProto;
182 } /* FindClosestExistingProto */

◆ MakeNewFromOld()

void MakeNewFromOld ( PROTO  New,
PROTOTYPE Old 
)

This fills in the fields of the New proto based on the fields of the Old proto.

Parameters
Newnew proto to be filled in
Oldold proto to be converted

Globals: none

Definition at line 193 of file mergenf.cpp.

193  {
194  New->X = CenterX(Old->Mean);
195  New->Y = CenterY(Old->Mean);
196  New->Length = LengthOf(Old->Mean);
197  New->Angle = OrientationOf(Old->Mean);
198  FillABC(New);
199 } /* MakeNewFromOld */

◆ PointInside()

bool PointInside ( FRECT Rectangle,
float  X,
float  Y 
)

Return true if point (X,Y) is inside of Rectangle.

Globals: none

Returns
true if point (X,Y) is inside of Rectangle.

Definition at line 317 of file mergenf.cpp.

317  {
318  return (X >= Rectangle->MinX) &&
319  (X <= Rectangle->MaxX) &&
320  (Y >= Rectangle->MinY) &&
321  (Y <= Rectangle->MaxY);
322 } /* PointInside */

◆ SubfeatureEvidence()

float SubfeatureEvidence ( FEATURE  Feature,
PROTO  Proto 
)

Definition at line 208 of file mergenf.cpp.

208  {
209  float Distance;
210  float Dangle;
211 
212  Dangle = Proto->Angle - Feature->Params[PicoFeatDir];
213  if (Dangle < -0.5) Dangle += 1.0;
214  if (Dangle > 0.5) Dangle -= 1.0;
215  Dangle *= training_angle_match_scale;
216 
217  Distance = Proto->A * Feature->Params[PicoFeatX] +
218  Proto->B * Feature->Params[PicoFeatY] +
219  Proto->C;
220 
221  return (EvidenceOf (Distance * Distance + Dangle * Dangle));
222 }
DummyFastMatch
bool DummyFastMatch(FEATURE Feature, PROTO Proto)
Definition: mergenf.cpp:259
PROTO_STRUCT::Length
float Length
Definition: protos.h:41
FRECT
Definition: mergenf.h:42
FRECT::MaxX
float MaxX
Definition: mergenf.h:43
FRECT::MaxY
float MaxY
Definition: mergenf.h:43
ComputeMergedProto
void ComputeMergedProto(PROTO p1, PROTO p2, float w1, float w2, PROTO MergedProto)
Definition: mergenf.cpp:123
PROTO_STRUCT
Definition: protos.h:34
CLASS_STRUCT::NumProtos
int16_t NumProtos
Definition: protos.h:53
FEATURE_STRUCT
Definition: ocrfeatures.h:58
FRECT::MinY
float MinY
Definition: mergenf.h:43
PicoFeatY
Definition: picofeat.h:43
LengthOf
#define LengthOf(M)
Definition: mergenf.h:51
PicoFeatX
Definition: picofeat.h:43
PROTO_STRUCT::B
float B
Definition: protos.h:36
ProtoIn
#define ProtoIn(Class, Pid)
Definition: protos.h:82
PicoFeatDir
Definition: picofeat.h:43
EvidenceOf
double EvidenceOf(double Similarity)
Definition: mergenf.cpp:232
CompareProtos
float CompareProtos(PROTO p1, PROTO p2)
Definition: mergenf.cpp:63
PointInside
bool PointInside(FRECT *Rectangle, float X, float Y)
Definition: mergenf.cpp:317
NO_PROTO
#define NO_PROTO
Definition: matchdefs.h:40
PROTO_STRUCT::Y
float Y
Definition: protos.h:39
FreeFeature
void FreeFeature(FEATURE Feature)
Definition: ocrfeatures.cpp:53
PROTO_STRUCT::C
float C
Definition: protos.h:37
PROTO_STRUCT::X
float X
Definition: protos.h:38
MakeNewFromOld
void MakeNewFromOld(PROTO New, PROTOTYPE *Old)
Definition: mergenf.cpp:193
PROTO_STRUCT::Angle
float Angle
Definition: protos.h:40
CenterY
#define CenterY(M)
Definition: mergenf.h:50
FillABC
void FillABC(PROTO Proto)
Definition: protos.cpp:105
FEATURE_STRUCT::Params
float Params[1]
Definition: ocrfeatures.h:60
ComputePaddedBoundingBox
void ComputePaddedBoundingBox(PROTO Proto, float TangentPad, float OrthogonalPad, FRECT *BoundingBox)
Definition: mergenf.cpp:293
MAX_LENGTH_MISMATCH
#define MAX_LENGTH_MISMATCH
Definition: mergenf.h:32
FRECT::MinX
float MinX
Definition: mergenf.h:43
NewFeature
FEATURE NewFeature(const FEATURE_DESC_STRUCT *FeatureDesc)
Definition: ocrfeatures.cpp:77
OrientationOf
#define OrientationOf(M)
Definition: mergenf.h:52
PicoFeatDesc
const TESS_API FEATURE_DESC_STRUCT PicoFeatDesc
PROTO_STRUCT::A
float A
Definition: protos.h:35
PROTOTYPE::Mean
float * Mean
Definition: cluster.h:73
WORST_EVIDENCE
#define WORST_EVIDENCE
Definition: mergenf.h:31
CenterX
#define CenterX(M)
Definition: mergenf.h:49
SubfeatureEvidence
float SubfeatureEvidence(FEATURE Feature, PROTO Proto)
Definition: mergenf.cpp:208
WORST_MATCH_ALLOWED
#define WORST_MATCH_ALLOWED
Definition: mergenf.h:30
GetPicoFeatureLength
#define GetPicoFeatureLength()
Definition: picofeat.h:56