• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  **	Filename:    picofeat.c
3  **	Purpose:     Definition of pico-features.
4  **	Author:      Dan Johnson
5  **	History:     9/4/90, 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 /**----------------------------------------------------------------------------
19           Include Files and Type Defines
20 ----------------------------------------------------------------------------**/
21 #include "picofeat.h"
22 #include "mfoutline.h"
23 #include "hideedge.h"
24 #include "fpoint.h"
25 #include "varable.h"
26 
27 #include <math.h>
28 
29 #include "ocrfeatures.h"         //Debug
30 #include <stdio.h>               //Debug
31 #include "efio.h"                //Debug
32 
33 /*---------------------------------------------------------------------------
34           Variables
35 ----------------------------------------------------------------------------*/
36 
37 double_VAR(classify_pico_feature_length, 0.05, "Pico Feature Length");
38 
39 /*---------------------------------------------------------------------------
40           Private Function Prototypes
41 ----------------------------------------------------------------------------*/
42 void ConvertSegmentToPicoFeat(FPOINT *Start,
43                               FPOINT *End,
44                               FEATURE_SET FeatureSet);
45 
46 void ConvertToPicoFeatures2(MFOUTLINE Outline, FEATURE_SET FeatureSet);
47 
48 void NormalizePicoX(FEATURE_SET FeatureSet);
49 
50 /**----------------------------------------------------------------------------
51               Public Code
52 ----------------------------------------------------------------------------**/
53 /*---------------------------------------------------------------------------*/
ExtractPicoFeatures(TBLOB * Blob,LINE_STATS * LineStats)54 FEATURE_SET ExtractPicoFeatures(TBLOB *Blob, LINE_STATS *LineStats) {
55 /*
56  **	Parameters:
57  **		Blob		blob to extract pico-features from
58  **		LineStats	statistics on text row blob is in
59  **	Globals:
60  **		classify_norm_method	normalization method currently specified
61  **	Operation: Dummy for now.
62  **	Return: Pico-features for Blob.
63  **	Exceptions: none
64  **	History: 9/4/90, DSJ, Created.
65  */
66   LIST Outlines;
67   LIST RemainingOutlines;
68   MFOUTLINE Outline;
69   FEATURE_SET FeatureSet;
70   FLOAT32 XScale, YScale;
71 
72   FeatureSet = NewFeatureSet (MAX_PICO_FEATURES);
73 
74   Outlines = ConvertBlob (Blob);
75 
76   NormalizeOutlines(Outlines, LineStats, &XScale, &YScale);
77   RemainingOutlines = Outlines;
78   iterate(RemainingOutlines) {
79     Outline = (MFOUTLINE) first_node (RemainingOutlines);
80     /*---------Debug--------------------------------------------------*
81     OFile = fopen ("f:/ims/debug/pfOutline.logCPP", "r");
82     if (OFile == NULL)
83     {
84       OFile = Efopen ("f:/ims/debug/pfOutline.logCPP", "w");
85       WriteOutline(OFile, Outline);
86     }
87     else
88     {
89       fclose (OFile);
90       OFile = Efopen ("f:/ims/debug/pfOutline.logCPP", "a");
91     }
92     WriteOutline(OFile, Outline);
93     fclose (OFile);
94     *--------------------------------------------------------------------*/
95     ConvertToPicoFeatures2(Outline, FeatureSet);
96   }
97   if (classify_norm_method == baseline)
98     NormalizePicoX(FeatureSet);
99   /*---------Debug--------------------------------------------------*
100   File = fopen ("f:/ims/debug/pfFeatSet.logCPP", "r");
101   if (File == NULL)
102   {
103     File = Efopen ("f:/ims/debug/pfFeatSet.logCPP", "w");
104     WriteFeatureSet(File, FeatureSet);
105   }
106   else
107   {
108     fclose (File);
109     File = Efopen ("f:/ims/debug/pfFeatSet.logCPP", "a");
110   }
111   WriteFeatureSet(File, FeatureSet);
112   fclose (File);
113   *--------------------------------------------------------------------*/
114   FreeOutlines(Outlines);
115   return (FeatureSet);
116 
117 }                                /* ExtractPicoFeatures */
118 
119 /**----------------------------------------------------------------------------
120               Private Code
121 ----------------------------------------------------------------------------**/
122 /*---------------------------------------------------------------------------*/
ConvertSegmentToPicoFeat(FPOINT * Start,FPOINT * End,FEATURE_SET FeatureSet)123 void ConvertSegmentToPicoFeat(FPOINT *Start,
124                               FPOINT *End,
125                               FEATURE_SET FeatureSet) {
126 /*
127  **	Parameters:
128  **		Start		starting point of pico-feature
129  **		End		ending point of pico-feature
130  **		FeatureSet	set to add pico-feature to
131  **	Globals:
132  **		classify_pico_feature_length	length of a single pico-feature
133  **	Operation: This routine converts an entire segment of an outline
134  **		into a set of pico features which are added to
135  **		FeatureSet.  The length of the segment is rounded to the
136  **		nearest whole number of pico-features.  The pico-features
137  **		are spaced evenly over the entire segment.
138  **	Return: none (results are placed in FeatureSet)
139  **	Exceptions: none
140  **	History: Tue Apr 30 15:44:34 1991, DSJ, Created.
141  */
142   FEATURE Feature;
143   FLOAT32 Angle;
144   FLOAT32 Length;
145   int NumFeatures;
146   FPOINT Center;
147   FPOINT Delta;
148   int i;
149 
150   Angle = NormalizedAngleFrom (Start, End, 1.0);
151   Length = DistanceBetween (*Start, *End);
152   NumFeatures = (int) floor (Length / classify_pico_feature_length + 0.5);
153   if (NumFeatures < 1)
154     NumFeatures = 1;
155 
156   /* compute vector for one pico feature */
157   Delta.x = XDelta (*Start, *End) / NumFeatures;
158   Delta.y = YDelta (*Start, *End) / NumFeatures;
159 
160   /* compute position of first pico feature */
161   Center.x = Start->x + Delta.x / 2.0;
162   Center.y = Start->y + Delta.y / 2.0;
163 
164   /* compute each pico feature in segment and add to feature set */
165   for (i = 0; i < NumFeatures; i++) {
166     Feature = NewFeature (&PicoFeatDesc);
167     Feature->Params[PicoFeatDir] = Angle;
168     Feature->Params[PicoFeatX] = Center.x;
169     Feature->Params[PicoFeatY] = Center.y;
170     AddFeature(FeatureSet, Feature);
171 
172     Center.x += Delta.x;
173     Center.y += Delta.y;
174   }
175 }                                /* ConvertSegmentToPicoFeat */
176 
177 
178 /*---------------------------------------------------------------------------*/
ConvertToPicoFeatures2(MFOUTLINE Outline,FEATURE_SET FeatureSet)179 void ConvertToPicoFeatures2(MFOUTLINE Outline, FEATURE_SET FeatureSet) {
180 /*
181  **	Parameters:
182  **		Outline		outline to extract micro-features from
183  **		FeatureSet	set of features to add pico-features to
184  **	Globals:
185  **		classify_pico_feature_length
186  **                             length of features to be extracted
187  **	Operation:
188  **		This routine steps thru the specified outline and cuts it
189  **		up into pieces of equal length.  These pieces become the
190  **		desired pico-features.  Each segment in the outline
191  **		is converted into an integral number of pico-features.
192  **	Return: none (results are returned in FeatureSet)
193  **	Exceptions: none
194  **	History: 4/30/91, DSJ, Adapted from ConvertToPicoFeatures().
195  */
196   MFOUTLINE Next;
197   MFOUTLINE First;
198   MFOUTLINE Current;
199 
200   if (DegenerateOutline (Outline))
201     return;
202 
203   First = Outline;
204   Current = First;
205   Next = NextPointAfter (Current);
206   do {
207     /* note that an edge is hidden if the ending point of the edge is
208        marked as hidden.  This situation happens because the order of
209        the outlines is reversed when they are converted from the old
210        format.  In the old format, a hidden edge is marked by the
211        starting point for that edge. */
212     if (!(PointAt(Next)->Hidden))
213       ConvertSegmentToPicoFeat (&(PointAt(Current)->Point),
214         &(PointAt(Next)->Point), FeatureSet);
215 
216     Current = Next;
217     Next = NextPointAfter (Current);
218   }
219   while (Current != First);
220 
221 }                                /* ConvertToPicoFeatures2 */
222 
223 
224 /*---------------------------------------------------------------------------*/
NormalizePicoX(FEATURE_SET FeatureSet)225 void NormalizePicoX(FEATURE_SET FeatureSet) {
226 /*
227  **	Parameters:
228  **		FeatureSet	pico-features to be normalized
229  **	Globals: none
230  **	Operation: This routine computes the average x position over all
231  **		of the pico-features in FeatureSet and then renormalizes
232  **		the pico-features to force this average to be the x origin
233  **		(i.e. x=0).
234  **	Return: none (FeatureSet is changed)
235  **	Exceptions: none
236  **	History: Tue Sep  4 16:50:08 1990, DSJ, Created.
237  */
238   int i;
239   FEATURE Feature;
240   FLOAT32 Origin = 0.0;
241 
242   for (i = 0; i < FeatureSet->NumFeatures; i++) {
243     Feature = FeatureSet->Features[i];
244     Origin += Feature->Params[PicoFeatX];
245   }
246   Origin /= FeatureSet->NumFeatures;
247 
248   for (i = 0; i < FeatureSet->NumFeatures; i++) {
249     Feature = FeatureSet->Features[i];
250     Feature->Params[PicoFeatX] -= Origin;
251   }
252 }                                /* NormalizePicoX */
253