tesseract
3.03
|
00001 /* -*-C-*- 00002 ******************************************************************************** 00003 * 00004 * File: blobs.h (Formerly blobs.h) 00005 * Description: Blob definition 00006 * Author: Mark Seaman, OCR Technology 00007 * Created: Fri Oct 27 15:39:52 1989 00008 * Modified: Thu Mar 28 15:33:38 1991 (Mark Seaman) marks@hpgrlt 00009 * Language: C 00010 * Package: N/A 00011 * Status: Experimental (Do Not Distribute) 00012 * 00013 * (c) Copyright 1989, Hewlett-Packard Company. 00014 ** Licensed under the Apache License, Version 2.0 (the "License"); 00015 ** you may not use this file except in compliance with the License. 00016 ** You may obtain a copy of the License at 00017 ** http://www.apache.org/licenses/LICENSE-2.0 00018 ** Unless required by applicable law or agreed to in writing, software 00019 ** distributed under the License is distributed on an "AS IS" BASIS, 00020 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00021 ** See the License for the specific language governing permissions and 00022 ** limitations under the License. 00023 * 00024 *********************************************************************************/ 00025 00026 #ifndef BLOBS_H 00027 #define BLOBS_H 00028 00029 /*---------------------------------------------------------------------- 00030 I n c l u d e s 00031 ----------------------------------------------------------------------*/ 00032 #include "clst.h" 00033 #include "normalis.h" 00034 #include "publictypes.h" 00035 #include "rect.h" 00036 #include "vecfuncs.h" 00037 00038 class BLOCK; 00039 class C_BLOB; 00040 class C_OUTLINE; 00041 class LLSQ; 00042 class ROW; 00043 class WERD; 00044 00045 /*---------------------------------------------------------------------- 00046 T y p e s 00047 ----------------------------------------------------------------------*/ 00048 #define EDGEPTFLAGS 4 /*concavity,length etc. */ 00049 00050 struct TPOINT { 00051 TPOINT(): x(0), y(0) {} 00052 TPOINT(inT16 vx, inT16 vy) : x(vx), y(vy) {} 00053 TPOINT(const ICOORD &ic) : x(ic.x()), y(ic.y()) {} 00054 00055 void operator+=(const TPOINT& other) { 00056 x += other.x; 00057 y += other.y; 00058 } 00059 void operator/=(int divisor) { 00060 x /= divisor; 00061 y /= divisor; 00062 } 00063 00064 inT16 x; // absolute x coord. 00065 inT16 y; // absolute y coord. 00066 }; 00067 typedef TPOINT VECTOR; // structure for coordinates. 00068 00069 struct EDGEPT { 00070 EDGEPT() 00071 : next(NULL), prev(NULL), src_outline(NULL), start_step(0), step_count(0) { 00072 memset(flags, 0, EDGEPTFLAGS * sizeof(flags[0])); 00073 } 00074 EDGEPT(const EDGEPT& src) : next(NULL), prev(NULL) { 00075 CopyFrom(src); 00076 } 00077 EDGEPT& operator=(const EDGEPT& src) { 00078 CopyFrom(src); 00079 return *this; 00080 } 00081 // Copies the data elements, but leaves the pointers untouched. 00082 void CopyFrom(const EDGEPT& src) { 00083 pos = src.pos; 00084 vec = src.vec; 00085 memcpy(flags, src.flags, EDGEPTFLAGS * sizeof(flags[0])); 00086 src_outline = src.src_outline; 00087 start_step = src.start_step; 00088 step_count = src.step_count; 00089 } 00090 // Accessors to hide or reveal a cut edge from feature extractors. 00091 void Hide() { 00092 flags[0] = true; 00093 } 00094 void Reveal() { 00095 flags[0] = false; 00096 } 00097 bool IsHidden() const { 00098 return flags[0] != 0; 00099 } 00100 void MarkChop() { 00101 flags[2] = true; 00102 } 00103 void UnmarkChop() { 00104 flags[2] = false; 00105 } 00106 bool IsChopPt() const { 00107 return flags[2] != 0; 00108 } 00109 00110 TPOINT pos; // position 00111 VECTOR vec; // vector to next point 00112 // TODO(rays) Remove flags and replace with 00113 // is_hidden, runlength, dir, and fixed. The only use 00114 // of the flags other than is_hidden is in polyaprx.cpp. 00115 char flags[EDGEPTFLAGS]; // concavity, length etc 00116 EDGEPT* next; // anticlockwise element 00117 EDGEPT* prev; // clockwise element 00118 C_OUTLINE* src_outline; // Outline it came from. 00119 // The following fields are not used if src_outline is NULL. 00120 int start_step; // Location of pos in src_outline. 00121 int step_count; // Number of steps used (may wrap around). 00122 }; 00123 00124 // For use in chop and findseam to keep a list of which EDGEPTs were inserted. 00125 CLISTIZEH(EDGEPT); 00126 00127 struct TESSLINE { 00128 TESSLINE() : is_hole(false), loop(NULL), next(NULL) {} 00129 TESSLINE(const TESSLINE& src) : loop(NULL), next(NULL) { 00130 CopyFrom(src); 00131 } 00132 ~TESSLINE() { 00133 Clear(); 00134 } 00135 TESSLINE& operator=(const TESSLINE& src) { 00136 CopyFrom(src); 00137 return *this; 00138 } 00139 // Consume the circular list of EDGEPTs to make a TESSLINE. 00140 static TESSLINE* BuildFromOutlineList(EDGEPT* outline); 00141 // Copies the data and the outline, but leaves next untouched. 00142 void CopyFrom(const TESSLINE& src); 00143 // Deletes owned data. 00144 void Clear(); 00145 // Normalize in-place using the DENORM. 00146 void Normalize(const DENORM& denorm); 00147 // Rotates by the given rotation in place. 00148 void Rotate(const FCOORD rotation); 00149 // Moves by the given vec in place. 00150 void Move(const ICOORD vec); 00151 // Scales by the given factor in place. 00152 void Scale(float factor); 00153 // Sets up the start and vec members of the loop from the pos members. 00154 void SetupFromPos(); 00155 // Recomputes the bounding box from the points in the loop. 00156 void ComputeBoundingBox(); 00157 // Computes the min and max cross product of the outline points with the 00158 // given vec and returns the results in min_xp and max_xp. Geometrically 00159 // this is the left and right edge of the outline perpendicular to the 00160 // given direction, but to get the distance units correct, you would 00161 // have to divide by the modulus of vec. 00162 void MinMaxCrossProduct(const TPOINT vec, int* min_xp, int* max_xp) const; 00163 00164 TBOX bounding_box() const; 00165 // Returns true if the point is contained within the outline box. 00166 bool Contains(const TPOINT& pt) { 00167 return topleft.x <= pt.x && pt.x <= botright.x && 00168 botright.y <= pt.y && pt.y <= topleft.y; 00169 } 00170 00171 #ifndef GRAPHICS_DISABLED 00172 void plot(ScrollView* window, ScrollView::Color color, 00173 ScrollView::Color child_color); 00174 #endif // GRAPHICS_DISABLED 00175 00176 // Returns the first outline point that has a different src_outline to its 00177 // predecessor, or, if all the same, the lowest indexed point. 00178 EDGEPT* FindBestStartPt() const; 00179 00180 00181 int BBArea() const { 00182 return (botright.x - topleft.x) * (topleft.y - botright.y); 00183 } 00184 00185 TPOINT topleft; // Top left of loop. 00186 TPOINT botright; // Bottom right of loop. 00187 TPOINT start; // Start of loop. 00188 bool is_hole; // True if this is a hole/child outline. 00189 EDGEPT *loop; // Edgeloop. 00190 TESSLINE *next; // Next outline in blob. 00191 }; // Outline structure. 00192 00193 struct TBLOB { 00194 TBLOB() : outlines(NULL) {} 00195 TBLOB(const TBLOB& src) : outlines(NULL) { 00196 CopyFrom(src); 00197 } 00198 ~TBLOB() { 00199 Clear(); 00200 } 00201 TBLOB& operator=(const TBLOB& src) { 00202 CopyFrom(src); 00203 return *this; 00204 } 00205 // Factory to build a TBLOB from a C_BLOB with polygonal approximation along 00206 // the way. If allow_detailed_fx is true, the EDGEPTs in the returned TBLOB 00207 // contain pointers to the input C_OUTLINEs that enable higher-resolution 00208 // feature extraction that does not use the polygonal approximation. 00209 static TBLOB* PolygonalCopy(bool allow_detailed_fx, C_BLOB* src); 00210 // Factory builds a blob with no outlines, but copies the other member data. 00211 static TBLOB* ShallowCopy(const TBLOB& src); 00212 // Normalizes the blob for classification only if needed. 00213 // (Normally this means a non-zero classify rotation.) 00214 // If no Normalization is needed, then NULL is returned, and the input blob 00215 // can be used directly. Otherwise a new TBLOB is returned which must be 00216 // deleted after use. 00217 TBLOB* ClassifyNormalizeIfNeeded() const; 00218 00219 // Copies the data and the outlines, but leaves next untouched. 00220 void CopyFrom(const TBLOB& src); 00221 // Deletes owned data. 00222 void Clear(); 00223 // Sets up the built-in DENORM and normalizes the blob in-place. 00224 // For parameters see DENORM::SetupNormalization, plus the inverse flag for 00225 // this blob and the Pix for the full image. 00226 void Normalize(const BLOCK* block, 00227 const FCOORD* rotation, 00228 const DENORM* predecessor, 00229 float x_origin, float y_origin, 00230 float x_scale, float y_scale, 00231 float final_xshift, float final_yshift, 00232 bool inverse, Pix* pix); 00233 // Rotates by the given rotation in place. 00234 void Rotate(const FCOORD rotation); 00235 // Moves by the given vec in place. 00236 void Move(const ICOORD vec); 00237 // Scales by the given factor in place. 00238 void Scale(float factor); 00239 // Recomputes the bounding boxes of the outlines. 00240 void ComputeBoundingBoxes(); 00241 00242 // Returns the number of outlines. 00243 int NumOutlines() const; 00244 00245 TBOX bounding_box() const; 00246 00247 const DENORM& denorm() const { 00248 return denorm_; 00249 } 00250 00251 #ifndef GRAPHICS_DISABLED 00252 void plot(ScrollView* window, ScrollView::Color color, 00253 ScrollView::Color child_color); 00254 #endif // GRAPHICS_DISABLED 00255 00256 int BBArea() const { 00257 int total_area = 0; 00258 for (TESSLINE* outline = outlines; outline != NULL; outline = outline->next) 00259 total_area += outline->BBArea(); 00260 return total_area; 00261 } 00262 00263 // Computes the center of mass and second moments for the old baseline and 00264 // 2nd moment normalizations. Returns the outline length. 00265 // The input denorm should be the normalizations that have been applied from 00266 // the image to the current state of this TBLOB. 00267 int ComputeMoments(FCOORD* center, FCOORD* second_moments) const; 00268 // Computes the precise bounding box of the coords that are generated by 00269 // GetEdgeCoords. This may be different from the bounding box of the polygon. 00270 void GetPreciseBoundingBox(TBOX* precise_box) const; 00271 // Adds edges to the given vectors. 00272 // For all the edge steps in all the outlines, or polygonal approximation 00273 // where there are no edge steps, collects the steps into x_coords/y_coords. 00274 // x_coords is a collection of the x-coords of vertical edges for each 00275 // y-coord starting at box.bottom(). 00276 // y_coords is a collection of the y-coords of horizontal edges for each 00277 // x-coord starting at box.left(). 00278 // Eg x_coords[0] is a collection of the x-coords of edges at y=bottom. 00279 // Eg x_coords[1] is a collection of the x-coords of edges at y=bottom + 1. 00280 void GetEdgeCoords(const TBOX& box, 00281 GenericVector<GenericVector<int> >* x_coords, 00282 GenericVector<GenericVector<int> >* y_coords) const; 00283 00284 TESSLINE *outlines; // List of outlines in blob. 00285 00286 private: // TODO(rays) Someday the data members will be private too. 00287 // For all the edge steps in all the outlines, or polygonal approximation 00288 // where there are no edge steps, collects the steps into the bounding_box, 00289 // llsq and/or the x_coords/y_coords. Both are used in different kinds of 00290 // normalization. 00291 // For a description of x_coords, y_coords, see GetEdgeCoords above. 00292 void CollectEdges(const TBOX& box, 00293 TBOX* bounding_box, LLSQ* llsq, 00294 GenericVector<GenericVector<int> >* x_coords, 00295 GenericVector<GenericVector<int> >* y_coords) const; 00296 00297 private: 00298 // DENORM indicating the transformations that this blob has undergone so far. 00299 DENORM denorm_; 00300 }; // Blob structure. 00301 00302 struct TWERD { 00303 TWERD() : latin_script(false) {} 00304 TWERD(const TWERD& src) { 00305 CopyFrom(src); 00306 } 00307 ~TWERD() { 00308 Clear(); 00309 } 00310 TWERD& operator=(const TWERD& src) { 00311 CopyFrom(src); 00312 return *this; 00313 } 00314 // Factory to build a TWERD from a (C_BLOB) WERD, with polygonal 00315 // approximation along the way. 00316 static TWERD* PolygonalCopy(bool allow_detailed_fx, WERD* src); 00317 // Baseline normalizes the blobs in-place, recording the normalization in the 00318 // DENORMs in the blobs. 00319 void BLNormalize(const BLOCK* block, const ROW* row, Pix* pix, bool inverse, 00320 float x_height, bool numeric_mode, 00321 tesseract::OcrEngineMode hint, 00322 const TBOX* norm_box, 00323 DENORM* word_denorm); 00324 // Copies the data and the blobs, but leaves next untouched. 00325 void CopyFrom(const TWERD& src); 00326 // Deletes owned data. 00327 void Clear(); 00328 // Recomputes the bounding boxes of the blobs. 00329 void ComputeBoundingBoxes(); 00330 00331 // Returns the number of blobs in the word. 00332 int NumBlobs() const { 00333 return blobs.size(); 00334 } 00335 TBOX bounding_box() const; 00336 00337 // Merges the blobs from start to end, not including end, and deletes 00338 // the blobs between start and end. 00339 void MergeBlobs(int start, int end); 00340 00341 void plot(ScrollView* window); 00342 00343 GenericVector<TBLOB*> blobs; // Blobs in word. 00344 bool latin_script; // This word is in a latin-based script. 00345 }; 00346 00347 /*---------------------------------------------------------------------- 00348 M a c r o s 00349 ----------------------------------------------------------------------*/ 00350 /********************************************************************** 00351 * free_widths 00352 * 00353 * Free the memory taken up by a width array. 00354 **********************************************************************/ 00355 #define free_widths(w) \ 00356 if (w) memfree (w) 00357 00358 /*---------------------------------------------------------------------- 00359 F u n c t i o n s 00360 ----------------------------------------------------------------------*/ 00361 // TODO(rays) This will become a member of TBLOB when TBLOB's definition 00362 // moves to blobs.h 00363 00364 // Returns the center of blob's bounding box in origin. 00365 void blob_origin(TBLOB *blob, TPOINT *origin); 00366 00367 bool divisible_blob(TBLOB *blob, bool italic_blob, TPOINT* location); 00368 00369 void divide_blobs(TBLOB *blob, TBLOB *other_blob, bool italic_blob, 00370 const TPOINT& location); 00371 00372 #endif