tesseract  4.0.0-1-g2a2b
mergenf.cpp File Reference
#include "mergenf.h"
#include "host.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"
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>

Go to the source code of this file.

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)
 

Variables

double training_angle_match_scale = 1.0
 
double training_similarity_midpoint = 0.0075
 
double training_similarity_curl = 2.0
 
double training_tangent_bbox_pad = 0.5
 
double training_orthogonal_bbox_pad = 2.5
 
double training_angle_pad = 45.0
 

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

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

◆ 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

Globals: none

Returns
none (results are returned in MergedProto)

Definition at line 125 of file mergenf.cpp.

129  {
130  float TotalWeight;
131 
132  TotalWeight = w1 + w2;
133  w1 /= TotalWeight;
134  w2 /= TotalWeight;
135 
136  MergedProto->X = p1->X * w1 + p2->X * w2;
137  MergedProto->Y = p1->Y * w1 + p2->Y * w2;
138  MergedProto->Length = p1->Length * w1 + p2->Length * w2;
139  MergedProto->Angle = p1->Angle * w1 + p2->Angle * w2;
140  FillABC(MergedProto);
141 } /* ComputeMergedProto */
float X
Definition: protos.h:46
float Y
Definition: protos.h:47
float Length
Definition: protos.h:49
void FillABC(PROTO Proto)
Definition: protos.cpp:195
float Angle
Definition: protos.h:48

◆ 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

Globals: none

Returns
none (results are returned in BoundingBox)

Definition at line 299 of file mergenf.cpp.

300  {
301  float Length = Proto->Length / 2.0 + TangentPad;
302  float Angle = Proto->Angle * 2.0 * M_PI;
303  float CosOfAngle = fabs(cos(Angle));
304  float SinOfAngle = fabs(sin(Angle));
305 
306  float Pad = std::max(CosOfAngle * Length, SinOfAngle * OrthogonalPad);
307  BoundingBox->MinX = Proto->X - Pad;
308  BoundingBox->MaxX = Proto->X + Pad;
309 
310  Pad = std::max(SinOfAngle * Length, CosOfAngle * OrthogonalPad);
311  BoundingBox->MinY = Proto->Y - Pad;
312  BoundingBox->MaxY = Proto->Y + Pad;
313 
314 } /* ComputePaddedBoundingBox */
float MaxX
Definition: mergenf.h:44
float X
Definition: protos.h:46
float Y
Definition: protos.h:47
float Length
Definition: protos.h:49
float MinY
Definition: mergenf.h:44
float MaxY
Definition: mergenf.h:44
float Angle
Definition: protos.h:48
float MinX
Definition: mergenf.h:44

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

262 {
263  FRECT BoundingBox;
264  float MaxAngleError;
265  float AngleError;
266 
267  MaxAngleError = training_angle_pad / 360.0;
268  AngleError = fabs (Proto->Angle - Feature->Params[PicoFeatDir]);
269  if (AngleError > 0.5)
270  AngleError = 1.0 - AngleError;
271 
272  if (AngleError > MaxAngleError)
273  return false;
274 
278  &BoundingBox);
279 
280  return PointInside(&BoundingBox, Feature->Params[PicoFeatX],
281  Feature->Params[PicoFeatY]);
282 } /* DummyFastMatch */
double training_tangent_bbox_pad
Definition: mergenf.cpp:41
double training_angle_pad
Definition: mergenf.cpp:45
float Params[1]
Definition: ocrfeatures.h:62
#define GetPicoFeatureLength()
Definition: picofeat.h:57
Definition: mergenf.h:43
void ComputePaddedBoundingBox(PROTO Proto, float TangentPad, float OrthogonalPad, FRECT *BoundingBox)
Definition: mergenf.cpp:299
bool PointInside(FRECT *Rectangle, float X, float Y)
Definition: mergenf.cpp:323
float Angle
Definition: protos.h:48
double training_orthogonal_bbox_pad
Definition: mergenf.cpp:43

◆ EvidenceOf()

double EvidenceOf ( double  Similarity)

Definition at line 234 of file mergenf.cpp.

234  {
235 
236  Similarity /= training_similarity_midpoint;
237 
238  if (training_similarity_curl == 3)
239  Similarity = Similarity * Similarity * Similarity;
240  else if (training_similarity_curl == 2)
241  Similarity = Similarity * Similarity;
242  else
243  Similarity = pow (Similarity, training_similarity_curl);
244 
245  return (1.0 / (1.0 + Similarity));
246 }
double training_similarity_midpoint
Definition: mergenf.cpp:36
double training_similarity_curl
Definition: mergenf.cpp:38

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

158  {
159  PROTO_STRUCT NewProto;
160  PROTO_STRUCT MergedProto;
161  int Pid;
162  PROTO 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,
174  (float) NumMerged[Pid], 1.0, &MergedProto);
175  OldMatch = CompareProtos(Proto, &MergedProto);
176  NewMatch = CompareProtos(&NewProto, &MergedProto);
177  Match = std::min(OldMatch, NewMatch);
178  if (Match > BestMatch) {
179  BestProto = Pid;
180  BestMatch = Match;
181  }
182  }
183  return BestProto;
184 } /* FindClosestExistingProto */
int16_t NumProtos
Definition: protos.h:61
void ComputeMergedProto(PROTO p1, PROTO p2, float w1, float w2, PROTO MergedProto)
Definition: mergenf.cpp:125
#define WORST_MATCH_ALLOWED
Definition: mergenf.h:31
#define ProtoIn(Class, Pid)
Definition: protos.h:121
void MakeNewFromOld(PROTO New, PROTOTYPE *Old)
Definition: mergenf.cpp:195
float CompareProtos(PROTO p1, PROTO p2)
Definition: mergenf.cpp:61
#define NO_PROTO
Definition: matchdefs.h:43

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

195  {
196  New->X = CenterX(Old->Mean);
197  New->Y = CenterY(Old->Mean);
198  New->Length = LengthOf(Old->Mean);
199  New->Angle = OrientationOf(Old->Mean);
200  FillABC(New);
201 } /* MakeNewFromOld */
float * Mean
Definition: cluster.h:78
float X
Definition: protos.h:46
#define CenterX(M)
Definition: mergenf.h:50
float Y
Definition: protos.h:47
float Length
Definition: protos.h:49
#define CenterY(M)
Definition: mergenf.h:51
void FillABC(PROTO Proto)
Definition: protos.cpp:195
float Angle
Definition: protos.h:48
#define LengthOf(M)
Definition: mergenf.h:52
#define OrientationOf(M)
Definition: mergenf.h:53

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

323  {
324  return (X >= Rectangle->MinX) &&
325  (X <= Rectangle->MaxX) &&
326  (Y >= Rectangle->MinY) &&
327  (Y <= Rectangle->MaxY);
328 } /* PointInside */
float MaxX
Definition: mergenf.h:44
float MinY
Definition: mergenf.h:44
float MaxY
Definition: mergenf.h:44
float MinX
Definition: mergenf.h:44

◆ SubfeatureEvidence()

float SubfeatureEvidence ( FEATURE  Feature,
PROTO  Proto 
)

Definition at line 210 of file mergenf.cpp.

210  {
211  float Distance;
212  float Dangle;
213 
214  Dangle = Proto->Angle - Feature->Params[PicoFeatDir];
215  if (Dangle < -0.5) Dangle += 1.0;
216  if (Dangle > 0.5) Dangle -= 1.0;
217  Dangle *= training_angle_match_scale;
218 
219  Distance = Proto->A * Feature->Params[PicoFeatX] +
220  Proto->B * Feature->Params[PicoFeatY] +
221  Proto->C;
222 
223  return (EvidenceOf (Distance * Distance + Dangle * Dangle));
224 }
double training_angle_match_scale
Definition: mergenf.cpp:34
float B
Definition: protos.h:44
float Params[1]
Definition: ocrfeatures.h:62
double EvidenceOf(double Similarity)
Definition: mergenf.cpp:234
float C
Definition: protos.h:45
float Angle
Definition: protos.h:48
float A
Definition: protos.h:43

Variable Documentation

◆ training_angle_match_scale

double training_angle_match_scale = 1.0

"Angle Match Scale ..."

Definition at line 34 of file mergenf.cpp.

◆ training_angle_pad

double training_angle_pad = 45.0

"Angle pad ..."

Definition at line 45 of file mergenf.cpp.

◆ training_orthogonal_bbox_pad

double training_orthogonal_bbox_pad = 2.5

"Orthogonal bounding box pad ..."

Definition at line 43 of file mergenf.cpp.

◆ training_similarity_curl

double training_similarity_curl = 2.0

"Similarity Curl ..."

Definition at line 38 of file mergenf.cpp.

◆ training_similarity_midpoint

double training_similarity_midpoint = 0.0075

"Similarity Midpoint ..."

Definition at line 36 of file mergenf.cpp.

◆ training_tangent_bbox_pad

double training_tangent_bbox_pad = 0.5

"Tangent bounding box pad ..."

Definition at line 41 of file mergenf.cpp.