|
tesseract 3.04.01
|
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 ******************************************************************************/ 00018 /*---------------------------------------------------------------------------- 00019 Include Files and Type Defines 00020 ----------------------------------------------------------------------------*/ 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 00031 /*---------------------------------------------------------------------------- 00032 Variables 00033 ----------------------------------------------------------------------------*/ 00034 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 00041 /*---------------------------------------------------------------------------- 00042 Macros 00043 ----------------------------------------------------------------------------*/ 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 00057 /*---------------------------------------------------------------------------- 00058 Public Code 00059 ----------------------------------------------------------------------------*/ 00060 00072 MICROFEATURES BlobMicroFeatures(TBLOB* Blob, const DENORM& cn_denorm) { 00073 MICROFEATURES MicroFeatures = NIL_LIST; 00074 LIST Outlines; 00075 LIST RemainingOutlines; 00076 MFOUTLINE Outline; 00077 00078 if (Blob != NULL) { 00079 Outlines = ConvertBlob(Blob); 00080 00081 RemainingOutlines = Outlines; 00082 iterate(RemainingOutlines) { 00083 Outline = (MFOUTLINE) first_node (RemainingOutlines); 00084 CharNormalizeOutline(Outline, cn_denorm); 00085 } 00086 00087 RemainingOutlines = Outlines; 00088 iterate(RemainingOutlines) { 00089 Outline = (MFOUTLINE) first_node(RemainingOutlines); 00090 FindDirectionChanges(Outline, classify_min_slope, classify_max_slope); 00091 MarkDirectionChanges(Outline); 00092 MicroFeatures = ConvertToMicroFeatures(Outline, MicroFeatures); 00093 } 00094 FreeOutlines(Outlines); 00095 } 00096 return MicroFeatures; 00097 } /* BlobMicroFeatures */ 00098 00099 00100 /*--------------------------------------------------------------------------- 00101 Private Code 00102 ---------------------------------------------------------------------------*/ 00103 00120 FLOAT32 ComputeOrientation(MFEDGEPT *Start, MFEDGEPT *End) { 00121 FLOAT32 Orientation; 00122 00123 Orientation = NormalizeAngle (AngleFrom (Start->Point, End->Point)); 00124 00125 /* ensure that round-off errors do not put circular param out of range */ 00126 if ((Orientation < 0) || (Orientation >= 1)) 00127 Orientation = 0; 00128 return (Orientation); 00129 } /* ComputeOrientation */ 00130 00131 00141 MICROFEATURES ConvertToMicroFeatures(MFOUTLINE Outline, 00142 MICROFEATURES MicroFeatures) { 00143 MFOUTLINE Current; 00144 MFOUTLINE Last; 00145 MFOUTLINE First; 00146 MICROFEATURE NewFeature; 00147 00148 if (DegenerateOutline (Outline)) 00149 return (MicroFeatures); 00150 00151 First = NextExtremity (Outline); 00152 Last = First; 00153 do { 00154 Current = NextExtremity (Last); 00155 if (!PointAt(Current)->Hidden) { 00156 NewFeature = ExtractMicroFeature (Last, Current); 00157 if (NewFeature != NULL) 00158 MicroFeatures = push (MicroFeatures, NewFeature); 00159 } 00160 Last = Current; 00161 } 00162 while (Last != First); 00163 00164 return (MicroFeatures); 00165 } /* ConvertToMicroFeatures */ 00166 00167 00185 MICROFEATURE ExtractMicroFeature(MFOUTLINE Start, MFOUTLINE End) { 00186 MICROFEATURE NewFeature; 00187 MFEDGEPT *P1, *P2; 00188 00189 P1 = PointAt(Start); 00190 P2 = PointAt(End); 00191 00192 NewFeature = NewMicroFeature (); 00193 NewFeature[XPOSITION] = AverageOf(P1->Point.x, P2->Point.x); 00194 NewFeature[YPOSITION] = AverageOf(P1->Point.y, P2->Point.y); 00195 NewFeature[MFLENGTH] = DistanceBetween(P1->Point, P2->Point); 00196 NewFeature[ORIENTATION] = NormalizedAngleFrom(&P1->Point, &P2->Point, 1.0); 00197 NewFeature[FIRSTBULGE] = 0.0f; // deprecated 00198 NewFeature[SECONDBULGE] = 0.0f; // deprecated 00199 00200 return NewFeature; 00201 } /* ExtractMicroFeature */