forked from tesseract-ocr/tesseract
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmfx.cpp
201 lines (174 loc) · 7.5 KB
/
mfx.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
/******************************************************************************
** Filename: mfx.c
** Purpose: Micro feature extraction routines
** Author: Dan Johnson
** History: 7/21/89, DSJ, Created.
**
** (c) Copyright Hewlett-Packard Company, 1988.
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
** http://www.apache.org/licenses/LICENSE-2.0
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
******************************************************************************/
/*----------------------------------------------------------------------------
Include Files and Type Defines
----------------------------------------------------------------------------*/
#include "mfdefs.h"
#include "mfoutline.h"
#include "clusttool.h" //NEEDED
#include "const.h"
#include "intfx.h"
#include "normalis.h"
#include "params.h"
#include <math.h>
/*----------------------------------------------------------------------------
Variables
----------------------------------------------------------------------------*/
/* old numbers corresponded to 10.0 degrees and 80.0 degrees */
double_VAR(classify_min_slope, 0.414213562,
"Slope below which lines are called horizontal");
double_VAR(classify_max_slope, 2.414213562,
"Slope above which lines are called vertical");
/*----------------------------------------------------------------------------
Macros
----------------------------------------------------------------------------*/
/* miscellaneous macros */
#define NormalizeAngle(A) ( (((A)<0)?((A)+2*PI):(A)) / (2*PI) )
/*----------------------------------------------------------------------------
Private Function Prototypes
-----------------------------------------------------------------------------*/
FLOAT32 ComputeOrientation(MFEDGEPT *Start, MFEDGEPT *End);
MICROFEATURES ConvertToMicroFeatures(MFOUTLINE Outline,
MICROFEATURES MicroFeatures);
MICROFEATURE ExtractMicroFeature(MFOUTLINE Start, MFOUTLINE End);
/*----------------------------------------------------------------------------
Public Code
----------------------------------------------------------------------------*/
/**
* This routine extracts micro-features from the specified
* blob and returns a list of the micro-features. All
* micro-features are normalized according to the specified
* line statistics.
* @param Blob blob to extract micro-features from
* @param cn_denorm control parameter to feature extractor
* @return List of micro-features extracted from the blob.
* @note Exceptions: none
* @note History: 7/21/89, DSJ, Created.
*/
MICROFEATURES BlobMicroFeatures(TBLOB* Blob, const DENORM& cn_denorm) {
MICROFEATURES MicroFeatures = NIL_LIST;
LIST Outlines;
LIST RemainingOutlines;
MFOUTLINE Outline;
if (Blob != NULL) {
Outlines = ConvertBlob(Blob);
RemainingOutlines = Outlines;
iterate(RemainingOutlines) {
Outline = (MFOUTLINE) first_node (RemainingOutlines);
CharNormalizeOutline(Outline, cn_denorm);
}
RemainingOutlines = Outlines;
iterate(RemainingOutlines) {
Outline = (MFOUTLINE) first_node(RemainingOutlines);
FindDirectionChanges(Outline, classify_min_slope, classify_max_slope);
MarkDirectionChanges(Outline);
MicroFeatures = ConvertToMicroFeatures(Outline, MicroFeatures);
}
FreeOutlines(Outlines);
}
return MicroFeatures;
} /* BlobMicroFeatures */
/*---------------------------------------------------------------------------
Private Code
---------------------------------------------------------------------------*/
/**
* This routine computes the orientation parameter of the
* specified micro-feature. The orientation is the angle of
* the vector from Start to End. It is normalized to a number
* between 0 and 1 where 0 corresponds to 0 degrees and 1
* corresponds to 360 degrees. The actual range is [0,1), i.e.
* 1 is excluded from the range (since it is actual the
* same orientation as 0). This routine assumes that Start
* and End are not the same point.
* @param Start starting edge point of micro-feature
* @param End ending edge point of micro-feature
* @note Globals: none
* @return Orientation parameter for the specified micro-feature.
* @note Exceptions: none
* @note History: 7/27/89, DSJ, Created.
*/
FLOAT32 ComputeOrientation(MFEDGEPT *Start, MFEDGEPT *End) {
FLOAT32 Orientation;
Orientation = NormalizeAngle (AngleFrom (Start->Point, End->Point));
/* ensure that round-off errors do not put circular param out of range */
if ((Orientation < 0) || (Orientation >= 1))
Orientation = 0;
return (Orientation);
} /* ComputeOrientation */
/**
* Convert Outline to MicroFeatures
* @param Outline outline to extract micro-features from
* @param MicroFeatures list of micro-features to add to
* @return List of micro-features with new features added to front.
* @note Globals: none
* @note Exceptions: none
* @note History: 7/26/89, DSJ, Created.
*/
MICROFEATURES ConvertToMicroFeatures(MFOUTLINE Outline,
MICROFEATURES MicroFeatures) {
MFOUTLINE Current;
MFOUTLINE Last;
MFOUTLINE First;
MICROFEATURE NewFeature;
if (DegenerateOutline (Outline))
return (MicroFeatures);
First = NextExtremity (Outline);
Last = First;
do {
Current = NextExtremity (Last);
if (!PointAt(Current)->Hidden) {
NewFeature = ExtractMicroFeature (Last, Current);
if (NewFeature != NULL)
MicroFeatures = push (MicroFeatures, NewFeature);
}
Last = Current;
}
while (Last != First);
return (MicroFeatures);
} /* ConvertToMicroFeatures */
/**
* This routine computes the feature parameters which describe
* the micro-feature that starts and Start and ends at End.
* A new micro-feature is allocated, filled with the feature
* parameters, and returned. The routine assumes that
* Start and End are not the same point. If they are the
* same point, NULL is returned, a warning message is
* printed, and the current outline is dumped to stdout.
* @param Start starting point of micro-feature
* @param End ending point of micro-feature
* @return New micro-feature or NULL if the feature was rejected.
* @note Globals: none
* @note Exceptions: none
* @note History:
* - 7/26/89, DSJ, Created.
* - 11/17/89, DSJ, Added handling for Start and End same point.
*/
MICROFEATURE ExtractMicroFeature(MFOUTLINE Start, MFOUTLINE End) {
MICROFEATURE NewFeature;
MFEDGEPT *P1, *P2;
P1 = PointAt(Start);
P2 = PointAt(End);
NewFeature = NewMicroFeature ();
NewFeature[XPOSITION] = AverageOf(P1->Point.x, P2->Point.x);
NewFeature[YPOSITION] = AverageOf(P1->Point.y, P2->Point.y);
NewFeature[MFLENGTH] = DistanceBetween(P1->Point, P2->Point);
NewFeature[ORIENTATION] = NormalizedAngleFrom(&P1->Point, &P2->Point, 1.0);
NewFeature[FIRSTBULGE] = 0.0f; // deprecated
NewFeature[SECONDBULGE] = 0.0f; // deprecated
return NewFeature;
} /* ExtractMicroFeature */