tesseract  3.03
/usr/local/google/home/jbreiden/tesseract-ocr-read-only/ccstruct/blobs.h
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines