All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
mergenf.cpp
Go to the documentation of this file.
1 /******************************************************************************
2 ** Filename: MergeNF.c
3 ** Purpose: Program for merging similar nano-feature protos
4 ** Author: Dan Johnson
5 ** History: Wed Nov 21 09:55:23 1990, DSJ, Created.
6 **
7  ** (c) Copyright Hewlett-Packard Company, 1988.
8  ** Licensed under the Apache License, Version 2.0 (the "License");
9  ** you may not use this file except in compliance with the License.
10  ** You may obtain a copy of the License at
11  ** http://www.apache.org/licenses/LICENSE-2.0
12  ** Unless required by applicable law or agreed to in writing, software
13  ** distributed under the License is distributed on an "AS IS" BASIS,
14  ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  ** See the License for the specific language governing permissions and
16  ** limitations under the License.
17 ******************************************************************************/
18 #include "mergenf.h"
19 #include "host.h"
20 #include "efio.h"
21 #include "clusttool.h"
22 #include "cluster.h"
23 #include "oldlist.h"
24 #include "protos.h"
25 #include "ndminx.h"
26 #include "ocrfeatures.h"
27 #include "const.h"
28 #include "featdefs.h"
29 #include "intproto.h"
30 #include "params.h"
31 
32 #include <stdio.h>
33 #include <string.h>
34 #include <math.h>
35 
36 
37 /*-------------------once in subfeat---------------------------------*/
38 double_VAR(training_angle_match_scale, 1.0, "Angle Match Scale ...");
39 
40 double_VAR(training_similarity_midpoint, 0.0075, "Similarity Midpoint ...");
41 
42 double_VAR(training_similarity_curl, 2.0, "Similarity Curl ...");
43 
44 /*-----------------------------once in fasttrain----------------------------------*/
45 double_VAR(training_tangent_bbox_pad, 0.5, "Tangent bounding box pad ...");
46 
47 double_VAR(training_orthogonal_bbox_pad, 2.5, "Orthogonal bounding box pad ...");
48 
49 double_VAR(training_angle_pad, 45.0, "Angle pad ...");
50 
68  FEATURE Feature;
69  FLOAT32 WorstEvidence = WORST_EVIDENCE;
70  FLOAT32 Evidence;
71  FLOAT32 Angle, Length;
72 
73  /* if p1 and p2 are not close in length, don't let them match */
74  Length = fabs (p1->Length - p2->Length);
75  if (Length > MAX_LENGTH_MISMATCH)
76  return (0.0);
77 
78  /* create a dummy pico-feature to be used for comparisons */
79  Feature = NewFeature (&PicoFeatDesc);
80  Feature->Params[PicoFeatDir] = p1->Angle;
81 
82  /* convert angle to radians */
83  Angle = p1->Angle * 2.0 * PI;
84 
85  /* find distance from center of p1 to 1/2 picofeat from end */
86  Length = p1->Length / 2.0 - GetPicoFeatureLength () / 2.0;
87  if (Length < 0) Length = 0;
88 
89  /* set the dummy pico-feature at one end of p1 and match it to p2 */
90  Feature->Params[PicoFeatX] = p1->X + cos (Angle) * Length;
91  Feature->Params[PicoFeatY] = p1->Y + sin (Angle) * Length;
92  if (DummyFastMatch (Feature, p2)) {
93  Evidence = SubfeatureEvidence (Feature, p2);
94  if (Evidence < WorstEvidence)
95  WorstEvidence = Evidence;
96  } else {
97  FreeFeature(Feature);
98  return 0.0;
99  }
100 
101  /* set the dummy pico-feature at the other end of p1 and match it to p2 */
102  Feature->Params[PicoFeatX] = p1->X - cos (Angle) * Length;
103  Feature->Params[PicoFeatY] = p1->Y - sin (Angle) * Length;
104  if (DummyFastMatch (Feature, p2)) {
105  Evidence = SubfeatureEvidence (Feature, p2);
106  if (Evidence < WorstEvidence)
107  WorstEvidence = Evidence;
108  } else {
109  FreeFeature(Feature);
110  return 0.0;
111  }
112 
113  FreeFeature (Feature);
114  return (WorstEvidence);
115 
116 } /* CompareProtos */
117 
134  PROTO p2,
135  FLOAT32 w1,
136  FLOAT32 w2,
137  PROTO MergedProto) {
138  FLOAT32 TotalWeight;
139 
140  TotalWeight = w1 + w2;
141  w1 /= TotalWeight;
142  w2 /= TotalWeight;
143 
144  MergedProto->X = p1->X * w1 + p2->X * w2;
145  MergedProto->Y = p1->Y * w1 + p2->Y * w2;
146  MergedProto->Length = p1->Length * w1 + p2->Length * w2;
147  MergedProto->Angle = p1->Angle * w1 + p2->Angle * w2;
148  FillABC(MergedProto);
149 } /* ComputeMergedProto */
150 
167 int FindClosestExistingProto(CLASS_TYPE Class, int NumMerged[],
168  PROTOTYPE *Prototype) {
169  PROTO_STRUCT NewProto;
170  PROTO_STRUCT MergedProto;
171  int Pid;
172  PROTO Proto;
173  int BestProto;
174  FLOAT32 BestMatch;
175  FLOAT32 Match, OldMatch, NewMatch;
176 
177  MakeNewFromOld (&NewProto, Prototype);
178 
179  BestProto = NO_PROTO;
180  BestMatch = WORST_MATCH_ALLOWED;
181  for (Pid = 0; Pid < Class->NumProtos; Pid++) {
182  Proto = ProtoIn(Class, Pid);
183  ComputeMergedProto(Proto, &NewProto,
184  (FLOAT32) NumMerged[Pid], 1.0, &MergedProto);
185  OldMatch = CompareProtos(Proto, &MergedProto);
186  NewMatch = CompareProtos(&NewProto, &MergedProto);
187  Match = MIN(OldMatch, NewMatch);
188  if (Match > BestMatch) {
189  BestProto = Pid;
190  BestMatch = Match;
191  }
192  }
193  return BestProto;
194 } /* FindClosestExistingProto */
195 
208 void MakeNewFromOld(PROTO New, PROTOTYPE *Old) {
209  New->X = CenterX(Old->Mean);
210  New->Y = CenterY(Old->Mean);
211  New->Length = LengthOf(Old->Mean);
212  New->Angle = OrientationOf(Old->Mean);
213  FillABC(New);
214 } /* MakeNewFromOld */
215 
216 /*-------------------once in subfeat---------------------------------*/
217 
224  float Distance;
225  float Dangle;
226 
227  Dangle = Proto->Angle - Feature->Params[PicoFeatDir];
228  if (Dangle < -0.5) Dangle += 1.0;
229  if (Dangle > 0.5) Dangle -= 1.0;
230  Dangle *= training_angle_match_scale;
231 
232  Distance = Proto->A * Feature->Params[PicoFeatX] +
233  Proto->B * Feature->Params[PicoFeatY] +
234  Proto->C;
235 
236  return (EvidenceOf (Distance * Distance + Dangle * Dangle));
237 }
238 
247 double EvidenceOf (double Similarity) {
248 
249  Similarity /= training_similarity_midpoint;
250 
251  if (training_similarity_curl == 3)
252  Similarity = Similarity * Similarity * Similarity;
253  else if (training_similarity_curl == 2)
254  Similarity = Similarity * Similarity;
255  else
256  Similarity = pow (Similarity, training_similarity_curl);
257 
258  return (1.0 / (1.0 + Similarity));
259 }
260 
277  FEATURE Feature,
278  PROTO Proto)
279 {
280  FRECT BoundingBox;
281  FLOAT32 MaxAngleError;
282  FLOAT32 AngleError;
283 
284  MaxAngleError = training_angle_pad / 360.0;
285  AngleError = fabs (Proto->Angle - Feature->Params[PicoFeatDir]);
286  if (AngleError > 0.5)
287  AngleError = 1.0 - AngleError;
288 
289  if (AngleError > MaxAngleError)
290  return (FALSE);
291 
295  &BoundingBox);
296 
297  return PointInside(&BoundingBox, Feature->Params[PicoFeatX],
298  Feature->Params[PicoFeatY]);
299 } /* DummyFastMatch */
300 
318 void ComputePaddedBoundingBox (PROTO Proto, FLOAT32 TangentPad,
319  FLOAT32 OrthogonalPad, FRECT *BoundingBox) {
320  FLOAT32 Pad, Length, Angle;
321  FLOAT32 CosOfAngle, SinOfAngle;
322 
323  Length = Proto->Length / 2.0 + TangentPad;
324  Angle = Proto->Angle * 2.0 * PI;
325  CosOfAngle = fabs(cos(Angle));
326  SinOfAngle = fabs(sin(Angle));
327 
328  Pad = MAX (CosOfAngle * Length, SinOfAngle * OrthogonalPad);
329  BoundingBox->MinX = Proto->X - Pad;
330  BoundingBox->MaxX = Proto->X + Pad;
331 
332  Pad = MAX(SinOfAngle * Length, CosOfAngle * OrthogonalPad);
333  BoundingBox->MinY = Proto->Y - Pad;
334  BoundingBox->MaxY = Proto->Y + Pad;
335 
336 } /* ComputePaddedBoundingBox */
337 
347 BOOL8 PointInside(FRECT *Rectangle, FLOAT32 X, FLOAT32 Y) {
348  if (X < Rectangle->MinX) return (FALSE);
349  if (X > Rectangle->MaxX) return (FALSE);
350  if (Y < Rectangle->MinY) return (FALSE);
351  if (Y > Rectangle->MaxY) return (FALSE);
352  return (TRUE);
353 
354 } /* PointInside */
#define MAX_LENGTH_MISMATCH
Definition: mergenf.h:30
void ComputeMergedProto(PROTO p1, PROTO p2, FLOAT32 w1, FLOAT32 w2, PROTO MergedProto)
Definition: mergenf.cpp:133
#define WORST_MATCH_ALLOWED
Definition: mergenf.h:28
FLOAT32 MaxY
Definition: mergenf.h:43
float FLOAT32
Definition: host.h:111
#define MAX(x, y)
Definition: ndminx.h:24
#define double_VAR(name, val, comment)
Definition: params.h:286
#define ProtoIn(Class, Pid)
Definition: protos.h:123
#define MIN(x, y)
Definition: ndminx.h:28
FLOAT32 SubfeatureEvidence(FEATURE Feature, PROTO Proto)
Definition: mergenf.cpp:223
FEATURE NewFeature(const FEATURE_DESC_STRUCT *FeatureDesc)
Definition: ocrfeatures.cpp:96
#define CenterY(M)
Definition: mergenf.h:50
double training_angle_pad
Definition: mergenf.cpp:49
double training_tangent_bbox_pad
Definition: mergenf.cpp:45
unsigned char BOOL8
Definition: host.h:113
const FEATURE_DESC_STRUCT PicoFeatDesc
FLOAT32 * Mean
Definition: cluster.h:78
inT16 NumProtos
Definition: protos.h:59
FLOAT32 MinY
Definition: mergenf.h:43
#define LengthOf(M)
Definition: mergenf.h:51
FLOAT32 X
Definition: protos.h:47
#define CenterX(M)
Definition: mergenf.h:49
Definition: mergenf.h:41
int FindClosestExistingProto(CLASS_TYPE Class, int NumMerged[], PROTOTYPE *Prototype)
Definition: mergenf.cpp:167
FLOAT32 Angle
Definition: protos.h:49
#define NO_PROTO
Definition: matchdefs.h:42
#define GetPicoFeatureLength()
Definition: picofeat.h:59
BOOL8 PointInside(FRECT *Rectangle, FLOAT32 X, FLOAT32 Y)
Definition: mergenf.cpp:347
FLOAT32 MaxX
Definition: mergenf.h:43
FLOAT32 B
Definition: protos.h:45
FLOAT32 MinX
Definition: mergenf.h:43
double training_angle_match_scale
Definition: mergenf.cpp:38
double EvidenceOf(double Similarity)
Definition: mergenf.cpp:247
double training_orthogonal_bbox_pad
Definition: mergenf.cpp:47
FLOAT32 Params[1]
Definition: ocrfeatures.h:65
void FillABC(PROTO Proto)
Definition: protos.cpp:198
FLOAT32 Length
Definition: protos.h:50
#define FALSE
Definition: capi.h:29
void FreeFeature(FEATURE Feature)
Definition: ocrfeatures.cpp:60
#define PI
Definition: const.h:19
FLOAT32 CompareProtos(PROTO p1, PROTO p2)
Definition: mergenf.cpp:67
#define TRUE
Definition: capi.h:28
double training_similarity_midpoint
Definition: mergenf.cpp:40
FLOAT32 C
Definition: protos.h:46
#define WORST_EVIDENCE
Definition: mergenf.h:29
FLOAT32 A
Definition: protos.h:44
double training_similarity_curl
Definition: mergenf.cpp:42
void ComputePaddedBoundingBox(PROTO Proto, FLOAT32 TangentPad, FLOAT32 OrthogonalPad, FRECT *BoundingBox)
Definition: mergenf.cpp:318
#define OrientationOf(M)
Definition: mergenf.h:52
BOOL8 DummyFastMatch(FEATURE Feature, PROTO Proto)
Definition: mergenf.cpp:276
FLOAT32 Y
Definition: protos.h:48
void MakeNewFromOld(PROTO New, PROTOTYPE *Old)
Definition: mergenf.cpp:208