tesseract 4.1.1
Loading...
Searching...
No Matches
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 18 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 */
TESS_API const FEATURE_DESC_STRUCT PicoFeatDesc
FEATURE NewFeature(const FEATURE_DESC_STRUCT *FeatureDesc)
Definition: ocrfeatures.cpp:78
void FreeFeature(FEATURE Feature)
Definition: ocrfeatures.cpp:54
#define GetPicoFeatureLength()
Definition: picofeat.h:57
@ PicoFeatY
Definition: picofeat.h:44
@ PicoFeatDir
Definition: picofeat.h:44
@ PicoFeatX
Definition: picofeat.h:44
bool DummyFastMatch(FEATURE Feature, PROTO Proto)
Definition: mergenf.cpp:259
float SubfeatureEvidence(FEATURE Feature, PROTO Proto)
Definition: mergenf.cpp:208
#define MAX_LENGTH_MISMATCH
Definition: mergenf.h:33
#define WORST_EVIDENCE
Definition: mergenf.h:32
float Params[1]
Definition: ocrfeatures.h:61
float Angle
Definition: protos.h:42
float Length
Definition: protos.h:43
float Y
Definition: protos.h:41
float X
Definition: protos.h:40

◆ 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 */
void FillABC(PROTO Proto)
Definition: protos.cpp:108

◆ 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 */
float MaxY
Definition: mergenf.h:44
float MinX
Definition: mergenf.h:44
float MinY
Definition: mergenf.h:44
float MaxX
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 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 */
bool PointInside(FRECT *Rectangle, float X, float Y)
Definition: mergenf.cpp:317
void ComputePaddedBoundingBox(PROTO Proto, float TangentPad, float OrthogonalPad, FRECT *BoundingBox)
Definition: mergenf.cpp:293
Definition: mergenf.h:43

◆ 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 */
#define ProtoIn(Class, Pid)
Definition: protos.h:84
#define NO_PROTO
Definition: matchdefs.h:41
void ComputeMergedProto(PROTO p1, PROTO p2, float w1, float w2, PROTO MergedProto)
Definition: mergenf.cpp:123
void MakeNewFromOld(PROTO New, PROTOTYPE *Old)
Definition: mergenf.cpp:193
float CompareProtos(PROTO p1, PROTO p2)
Definition: mergenf.cpp:63
#define WORST_MATCH_ALLOWED
Definition: mergenf.h:31
int16_t NumProtos
Definition: protos.h:55

◆ 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 */
#define CenterX(M)
Definition: mergenf.h:50
#define CenterY(M)
Definition: mergenf.h:51
#define LengthOf(M)
Definition: mergenf.h:52
#define OrientationOf(M)
Definition: mergenf.h:53
float * Mean
Definition: cluster.h:74

◆ 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}
double EvidenceOf(double Similarity)
Definition: mergenf.cpp:232
float B
Definition: protos.h:38
float A
Definition: protos.h:37
float C
Definition: protos.h:39