tesseract  5.0.0
mergenf.h File Reference
#include "cluster.h"
#include "ocrfeatures.h"
#include "picofeat.h"
#include "protos.h"

Go to the source code of this file.

Classes

struct  FRECT
 

Macros

#define WORST_MATCH_ALLOWED   (0.9)
 
#define WORST_EVIDENCE   (1.0)
 
#define MAX_LENGTH_MISMATCH   (2.0 * GetPicoFeatureLength())
 
#define PROTO_SUFFIX   ".mf.p"
 
#define CONFIG_SUFFIX   ".cl"
 
#define NO_PROTO   (-1)
 
#define XPOSITION   0
 
#define YPOSITION   1
 
#define MFLENGTH   2
 
#define ORIENTATION   3
 
#define CenterX(M)   ((M)[XPOSITION])
 
#define CenterY(M)   ((M)[YPOSITION])
 
#define LengthOf(M)   ((M)[MFLENGTH])
 
#define OrientationOf(M)   ((M)[ORIENTATION])
 

Functions

float CompareProtos (tesseract::PROTO_STRUCT *p1, tesseract::PROTO_STRUCT *p2)
 
void ComputeMergedProto (tesseract::PROTO_STRUCT *p1, tesseract::PROTO_STRUCT *p2, float w1, float w2, tesseract::PROTO_STRUCT *MergedProto)
 
int FindClosestExistingProto (tesseract::CLASS_TYPE Class, int NumMerged[], tesseract::PROTOTYPE *Prototype)
 
void MakeNewFromOld (tesseract::PROTO_STRUCT *New, tesseract::PROTOTYPE *Old)
 
float SubfeatureEvidence (tesseract::FEATURE Feature, tesseract::PROTO_STRUCT *Proto)
 
double EvidenceOf (double Similarity)
 
bool DummyFastMatch (tesseract::FEATURE Feature, tesseract::PROTO_STRUCT *Proto)
 
void ComputePaddedBoundingBox (tesseract::PROTO_STRUCT *Proto, float TangentPad, float OrthogonalPad, FRECT *BoundingBox)
 
bool PointInside (FRECT *Rectangle, float X, float Y)
 

Macro Definition Documentation

◆ CenterX

#define CenterX (   M)    ((M)[XPOSITION])

Public Macros

Definition at line 48 of file mergenf.h.

◆ CenterY

#define CenterY (   M)    ((M)[YPOSITION])

Definition at line 49 of file mergenf.h.

◆ CONFIG_SUFFIX

#define CONFIG_SUFFIX   ".cl"

Definition at line 34 of file mergenf.h.

◆ LengthOf

#define LengthOf (   M)    ((M)[MFLENGTH])

Definition at line 50 of file mergenf.h.

◆ MAX_LENGTH_MISMATCH

#define MAX_LENGTH_MISMATCH   (2.0 * GetPicoFeatureLength())

Definition at line 31 of file mergenf.h.

◆ MFLENGTH

#define MFLENGTH   2

Definition at line 38 of file mergenf.h.

◆ NO_PROTO

#define NO_PROTO   (-1)

Definition at line 35 of file mergenf.h.

◆ ORIENTATION

#define ORIENTATION   3

Definition at line 39 of file mergenf.h.

◆ OrientationOf

#define OrientationOf (   M)    ((M)[ORIENTATION])

Definition at line 51 of file mergenf.h.

◆ PROTO_SUFFIX

#define PROTO_SUFFIX   ".mf.p"

Definition at line 33 of file mergenf.h.

◆ WORST_EVIDENCE

#define WORST_EVIDENCE   (1.0)

Definition at line 30 of file mergenf.h.

◆ WORST_MATCH_ALLOWED

#define WORST_MATCH_ALLOWED   (0.9)

Include Files and Type Defines

Definition at line 29 of file mergenf.h.

◆ XPOSITION

#define XPOSITION   0

Definition at line 36 of file mergenf.h.

◆ YPOSITION

#define YPOSITION   1

Definition at line 37 of file mergenf.h.

Function Documentation

◆ CompareProtos()

float CompareProtos ( PROTO_STRUCT p1,
PROTO_STRUCT p2 
)

Public Function Prototypes

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 66 of file mergenf.cpp.

66  {
67  float WorstEvidence = WORST_EVIDENCE;
68  float Evidence;
69  float Angle, Length;
70 
71  /* if p1 and p2 are not close in length, don't let them match */
72  Length = std::fabs(p1->Length - p2->Length);
73  if (Length > MAX_LENGTH_MISMATCH) {
74  return (0.0);
75  }
76 
77  /* create a dummy pico-feature to be used for comparisons */
78  auto Feature = new FEATURE_STRUCT(&PicoFeatDesc);
79  Feature->Params[PicoFeatDir] = p1->Angle;
80 
81  /* convert angle to radians */
82  Angle = p1->Angle * 2.0 * M_PI;
83 
84  /* find distance from center of p1 to 1/2 picofeat from end */
85  Length = p1->Length / 2.0 - GetPicoFeatureLength() / 2.0;
86  if (Length < 0) {
87  Length = 0;
88  }
89 
90  /* set the dummy pico-feature at one end of p1 and match it to p2 */
91  Feature->Params[PicoFeatX] = p1->X + std::cos(Angle) * Length;
92  Feature->Params[PicoFeatY] = p1->Y + std::sin(Angle) * Length;
93  if (DummyFastMatch(Feature, p2)) {
94  Evidence = SubfeatureEvidence(Feature, p2);
95  if (Evidence < WorstEvidence) {
96  WorstEvidence = Evidence;
97  }
98  } else {
99  delete Feature;
100  return 0.0;
101  }
102 
103  /* set the dummy pico-feature at the other end of p1 and match it to p2 */
104  Feature->Params[PicoFeatX] = p1->X - std::cos(Angle) * Length;
105  Feature->Params[PicoFeatY] = p1->Y - std::sin(Angle) * Length;
106  if (DummyFastMatch(Feature, p2)) {
107  Evidence = SubfeatureEvidence(Feature, p2);
108  if (Evidence < WorstEvidence) {
109  WorstEvidence = Evidence;
110  }
111  } else {
112  delete Feature;
113  return 0.0;
114  }
115 
116  delete Feature;
117  return (WorstEvidence);
118 
119 } /* CompareProtos */
#define GetPicoFeatureLength()
Definition: picofeat.h:56
bool DummyFastMatch(FEATURE Feature, PROTO_STRUCT *Proto)
Definition: mergenf.cpp:263
float SubfeatureEvidence(FEATURE Feature, PROTO_STRUCT *Proto)
Definition: mergenf.cpp:209
#define MAX_LENGTH_MISMATCH
Definition: mergenf.h:31
#define WORST_EVIDENCE
Definition: mergenf.h:30
@ PicoFeatDir
Definition: picofeat.h:43
@ PicoFeatX
Definition: picofeat.h:43
@ PicoFeatY
Definition: picofeat.h:43
TESS_API const FEATURE_DESC_STRUCT PicoFeatDesc

◆ ComputeMergedProto()

void ComputeMergedProto ( PROTO_STRUCT p1,
PROTO_STRUCT p2,
float  w1,
float  w2,
PROTO_STRUCT 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 130 of file mergenf.cpp.

130  {
131  float TotalWeight;
132 
133  TotalWeight = w1 + w2;
134  w1 /= TotalWeight;
135  w2 /= TotalWeight;
136 
137  MergedProto->X = p1->X * w1 + p2->X * w2;
138  MergedProto->Y = p1->Y * w1 + p2->Y * w2;
139  MergedProto->Length = p1->Length * w1 + p2->Length * w2;
140  MergedProto->Angle = p1->Angle * w1 + p2->Angle * w2;
141  FillABC(MergedProto);
142 } /* ComputeMergedProto */
void FillABC(PROTO_STRUCT *Proto)
Definition: protos.cpp:103

◆ ComputePaddedBoundingBox()

void ComputePaddedBoundingBox ( PROTO_STRUCT 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 295 of file mergenf.cpp.

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

◆ DummyFastMatch()

bool DummyFastMatch ( FEATURE  Feature,
PROTO_STRUCT 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 263 of file mergenf.cpp.

263  {
264  FRECT BoundingBox;
265  float MaxAngleError;
266  float AngleError;
267 
268  MaxAngleError = training_angle_pad / 360.0;
269  AngleError = std::fabs(Proto->Angle - Feature->Params[PicoFeatDir]);
270  if (AngleError > 0.5) {
271  AngleError = 1.0 - AngleError;
272  }
273 
274  if (AngleError > MaxAngleError) {
275  return false;
276  }
277 
278  ComputePaddedBoundingBox(Proto, training_tangent_bbox_pad * GetPicoFeatureLength(),
279  training_orthogonal_bbox_pad * GetPicoFeatureLength(), &BoundingBox);
280 
281  return PointInside(&BoundingBox, Feature->Params[PicoFeatX], Feature->Params[PicoFeatY]);
282 } /* DummyFastMatch */
bool PointInside(FRECT *Rectangle, float X, float Y)
Definition: mergenf.cpp:319
void ComputePaddedBoundingBox(PROTO_STRUCT *Proto, float TangentPad, float OrthogonalPad, FRECT *BoundingBox)
Definition: mergenf.cpp:295
std::vector< float > Params
Definition: ocrfeatures.h:66
Definition: mergenf.h:41

◆ EvidenceOf()

double EvidenceOf ( double  Similarity)

Definition at line 236 of file mergenf.cpp.

236  {
237  Similarity /= training_similarity_midpoint;
238 
239  if (training_similarity_curl == 3) {
240  Similarity = Similarity * Similarity * Similarity;
241  } else if (training_similarity_curl == 2) {
242  Similarity = Similarity * Similarity;
243  } else {
244  Similarity = pow(Similarity, training_similarity_curl);
245  }
246 
247  return (1.0 / (1.0 + Similarity));
248 }

◆ 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 158 of file mergenf.cpp.

158  {
159  PROTO_STRUCT NewProto;
160  PROTO_STRUCT MergedProto;
161  int Pid;
162  PROTO_STRUCT *Proto;
163  int BestProto;
164  float BestMatch;
165  float Match, OldMatch, NewMatch;
166 
167  MakeNewFromOld(&NewProto, Prototype);
168 
169  BestProto = NO_PROTO;
170  BestMatch = WORST_MATCH_ALLOWED;
171  for (Pid = 0; Pid < Class->NumProtos; Pid++) {
172  Proto = ProtoIn(Class, Pid);
173  ComputeMergedProto(Proto, &NewProto, static_cast<float>(NumMerged[Pid]), 1.0, &MergedProto);
174  OldMatch = CompareProtos(Proto, &MergedProto);
175  NewMatch = CompareProtos(&NewProto, &MergedProto);
176  Match = std::min(OldMatch, NewMatch);
177  if (Match > BestMatch) {
178  BestProto = Pid;
179  BestMatch = Match;
180  }
181  }
182  return BestProto;
183 } /* FindClosestExistingProto */
#define ProtoIn(Class, Pid)
Definition: protos.h:70
#define NO_PROTO
Definition: matchdefs.h:41
void ComputeMergedProto(PROTO_STRUCT *p1, PROTO_STRUCT *p2, float w1, float w2, PROTO_STRUCT *MergedProto)
Definition: mergenf.cpp:130
float CompareProtos(PROTO_STRUCT *p1, PROTO_STRUCT *p2)
Definition: mergenf.cpp:66
void MakeNewFromOld(PROTO_STRUCT *New, PROTOTYPE *Old)
Definition: mergenf.cpp:194
#define WORST_MATCH_ALLOWED
Definition: mergenf.h:29

◆ MakeNewFromOld()

void MakeNewFromOld ( PROTO_STRUCT 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 194 of file mergenf.cpp.

194  {
195  New->X = CenterX(Old->Mean);
196  New->Y = CenterY(Old->Mean);
197  New->Length = LengthOf(Old->Mean);
198  New->Angle = OrientationOf(Old->Mean);
199  FillABC(New);
200 } /* MakeNewFromOld */
#define CenterX(M)
Definition: mergenf.h:48
#define CenterY(M)
Definition: mergenf.h:49
#define LengthOf(M)
Definition: mergenf.h:50
#define OrientationOf(M)
Definition: mergenf.h:51
std::vector< float > Mean
Definition: cluster.h:83

◆ 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 319 of file mergenf.cpp.

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

◆ SubfeatureEvidence()

float SubfeatureEvidence ( tesseract::FEATURE  Feature,
tesseract::PROTO_STRUCT Proto 
)

Definition at line 209 of file mergenf.cpp.

209  {
210  float Distance;
211  float Dangle;
212 
213  Dangle = Proto->Angle - Feature->Params[PicoFeatDir];
214  if (Dangle < -0.5) {
215  Dangle += 1.0;
216  }
217  if (Dangle > 0.5) {
218  Dangle -= 1.0;
219  }
220  Dangle *= training_angle_match_scale;
221 
222  Distance =
223  Proto->A * Feature->Params[PicoFeatX] + Proto->B * Feature->Params[PicoFeatY] + Proto->C;
224 
225  return (EvidenceOf(Distance * Distance + Dangle * Dangle));
226 }
double EvidenceOf(double Similarity)
Definition: mergenf.cpp:236