Tesseract
3.02
|
00001 /****************************************************************************** 00002 ** Filename: mfx.c 00003 ** Purpose: Micro feature extraction routines 00004 ** Author: Dan Johnson 00005 ** History: 7/21/89, DSJ, Created. 00006 ** 00007 ** (c) Copyright Hewlett-Packard Company, 1988. 00008 ** Licensed under the Apache License, Version 2.0 (the "License"); 00009 ** you may not use this file except in compliance with the License. 00010 ** You may obtain a copy of the License at 00011 ** http://www.apache.org/licenses/LICENSE-2.0 00012 ** Unless required by applicable law or agreed to in writing, software 00013 ** distributed under the License is distributed on an "AS IS" BASIS, 00014 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00015 ** See the License for the specific language governing permissions and 00016 ** limitations under the License. 00017 ******************************************************************************/ 00021 #include "mfdefs.h" 00022 #include "mfoutline.h" 00023 #include "clusttool.h" //NEEDED 00024 #include "const.h" 00025 #include "intfx.h" 00026 #include "normalis.h" 00027 #include "params.h" 00028 00029 #include <math.h> 00030 00035 /* old numbers corresponded to 10.0 degrees and 80.0 degrees */ 00036 double_VAR(classify_min_slope, 0.414213562, 00037 "Slope below which lines are called horizontal"); 00038 double_VAR(classify_max_slope, 2.414213562, 00039 "Slope above which lines are called vertical"); 00040 00044 /* miscellaneous macros */ 00045 #define NormalizeAngle(A) ( (((A)<0)?((A)+2*PI):(A)) / (2*PI) ) 00046 00047 /*---------------------------------------------------------------------------- 00048 Private Function Prototypes 00049 -----------------------------------------------------------------------------*/ 00050 FLOAT32 ComputeOrientation(MFEDGEPT *Start, MFEDGEPT *End); 00051 00052 MICROFEATURES ConvertToMicroFeatures(MFOUTLINE Outline, 00053 MICROFEATURES MicroFeatures); 00054 00055 MICROFEATURE ExtractMicroFeature(MFOUTLINE Start, MFOUTLINE End); 00056 00061 /*---------------------------------------------------------------------------*/ 00062 CHAR_FEATURES BlobMicroFeatures(TBLOB *Blob, const DENORM& denorm) { 00063 /* 00064 ** Parameters: 00065 ** Blob blob to extract micro-features from 00066 ** denorm control parameter to feature extractor 00067 ** Operation: 00068 ** This routine extracts micro-features from the specified 00069 ** blob and returns a list of the micro-features. All 00070 ** micro-features are normalized according to the specified 00071 ** line statistics. 00072 ** Return: List of micro-features extracted from the blob. 00073 ** Exceptions: none 00074 ** History: 7/21/89, DSJ, Created. 00075 */ 00076 MICROFEATURES MicroFeatures = NIL_LIST; 00077 FLOAT32 XScale, YScale; 00078 LIST Outlines; 00079 LIST RemainingOutlines; 00080 MFOUTLINE Outline; 00081 INT_FEATURE_ARRAY blfeatures; 00082 INT_FEATURE_ARRAY cnfeatures; 00083 INT_FX_RESULT_STRUCT results; 00084 00085 if (Blob != NULL) { 00086 Outlines = ConvertBlob (Blob); 00087 if (!ExtractIntFeat(Blob, denorm, blfeatures, cnfeatures, &results)) 00088 return NULL; 00089 XScale = 0.2f / results.Ry; 00090 YScale = 0.2f / results.Rx; 00091 00092 RemainingOutlines = Outlines; 00093 iterate(RemainingOutlines) { 00094 Outline = (MFOUTLINE) first_node (RemainingOutlines); 00095 CharNormalizeOutline (Outline, 00096 results.Xmean, results.Ymean, 00097 XScale, YScale); 00098 } 00099 00100 RemainingOutlines = Outlines; 00101 iterate(RemainingOutlines) { 00102 Outline = (MFOUTLINE) first_node (RemainingOutlines); 00103 FindDirectionChanges(Outline, classify_min_slope, classify_max_slope); 00104 MarkDirectionChanges(Outline); 00105 MicroFeatures = ConvertToMicroFeatures (Outline, MicroFeatures); 00106 } 00107 FreeOutlines(Outlines); 00108 } 00109 return ((CHAR_FEATURES) MicroFeatures); 00110 } /* BlobMicroFeatures */ 00111 00112 00113 /*--------------------------------------------------------------------------- 00114 Private Code 00115 ---------------------------------------------------------------------------*/ 00116 00117 /*---------------------------------------------------------------------------*/ 00118 FLOAT32 ComputeOrientation(MFEDGEPT *Start, MFEDGEPT *End) { 00119 /* 00120 ** Parameters: 00121 ** Start starting edge point of micro-feature 00122 ** End ending edge point of micro-feature 00123 ** Globals: none 00124 ** Operation: 00125 ** This routine computes the orientation parameter of the 00126 ** specified micro-feature. The orientation is the angle of 00127 ** the vector from Start to End. It is normalized to a number 00128 ** between 0 and 1 where 0 corresponds to 0 degrees and 1 00129 ** corresponds to 360 degrees. The actual range is [0,1), i.e. 00130 ** 1 is excluded from the range (since it is actual the 00131 ** same orientation as 0). This routine assumes that Start 00132 ** and End are not the same point. 00133 ** Return: Orientation parameter for the specified micro-feature. 00134 ** Exceptions: none 00135 ** History: 7/27/89, DSJ, Created. 00136 */ 00137 FLOAT32 Orientation; 00138 00139 Orientation = NormalizeAngle (AngleFrom (Start->Point, End->Point)); 00140 00141 /* ensure that round-off errors do not put circular param out of range */ 00142 if ((Orientation < 0) || (Orientation >= 1)) 00143 Orientation = 0; 00144 return (Orientation); 00145 } /* ComputeOrientation */ 00146 00147 00148 /*---------------------------------------------------------------------------*/ 00149 MICROFEATURES ConvertToMicroFeatures(MFOUTLINE Outline, 00150 MICROFEATURES MicroFeatures) { 00151 /* 00152 ** Parameters: 00153 ** Outline outline to extract micro-features from 00154 ** MicroFeatures list of micro-features to add to 00155 ** Globals: none 00156 ** Operation: 00157 ** This routine 00158 ** Return: List of micro-features with new features added to front. 00159 ** Exceptions: none 00160 ** History: 7/26/89, DSJ, Created. 00161 */ 00162 MFOUTLINE Current; 00163 MFOUTLINE Last; 00164 MFOUTLINE First; 00165 MICROFEATURE NewFeature; 00166 00167 if (DegenerateOutline (Outline)) 00168 return (MicroFeatures); 00169 00170 First = NextExtremity (Outline); 00171 Last = First; 00172 do { 00173 Current = NextExtremity (Last); 00174 if (!PointAt(Current)->Hidden) { 00175 NewFeature = ExtractMicroFeature (Last, Current); 00176 if (NewFeature != NULL) 00177 MicroFeatures = push (MicroFeatures, NewFeature); 00178 } 00179 Last = Current; 00180 } 00181 while (Last != First); 00182 00183 return (MicroFeatures); 00184 } /* ConvertToMicroFeatures */ 00185 00186 00187 /*---------------------------------------------------------------------------*/ 00188 MICROFEATURE ExtractMicroFeature(MFOUTLINE Start, MFOUTLINE End) { 00189 /* 00190 ** Parameters: 00191 ** Start starting point of micro-feature 00192 ** End ending point of micro-feature 00193 ** Globals: none 00194 ** Operation: 00195 ** This routine computes the feature parameters which describe 00196 ** the micro-feature that starts and Start and ends at End. 00197 ** A new micro-feature is allocated, filled with the feature 00198 ** parameters, and returned. The routine assumes that 00199 ** Start and End are not the same point. If they are the 00200 ** same point, NULL is returned, a warning message is 00201 ** printed, and the current outline is dumped to stdout. 00202 ** Return: New micro-feature or NULL if the feature was rejected. 00203 ** Exceptions: none 00204 ** History: 7/26/89, DSJ, Created. 00205 ** 11/17/89, DSJ, Added handling for Start and End same point. 00206 */ 00207 MICROFEATURE NewFeature; 00208 MFEDGEPT *P1, *P2; 00209 00210 P1 = PointAt(Start); 00211 P2 = PointAt(End); 00212 00213 NewFeature = NewMicroFeature (); 00214 NewFeature[XPOSITION] = AverageOf(P1->Point.x, P2->Point.x); 00215 NewFeature[YPOSITION] = AverageOf(P1->Point.y, P2->Point.y); 00216 NewFeature[MFLENGTH] = DistanceBetween(P1->Point, P2->Point); 00217 NewFeature[ORIENTATION] = NormalizedAngleFrom(&P1->Point, &P2->Point, 1.0); 00218 NewFeature[FIRSTBULGE] = 0.0f; // deprecated 00219 NewFeature[SECONDBULGE] = 0.0f; // deprecated 00220 00221 return NewFeature; 00222 } /* ExtractMicroFeature */