|
tesseract 3.04.01
|
00001 /* -*-C-*- 00002 ******************************************************************************** 00003 * 00004 * File: seam.h (Formerly seam.h) 00005 * Description: 00006 * Author: Mark Seaman, SW Productivity 00007 * Created: Fri Oct 16 14:37:00 1987 00008 * Modified: Thu May 16 17:05:52 1991 (Mark Seaman) marks@hpgrlt 00009 * Language: C 00010 * Package: N/A 00011 * Status: Reusable Software Component 00012 * 00013 * (c) Copyright 1987, 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 #ifndef SEAM_H 00026 #define SEAM_H 00027 00028 // Include automatically generated configuration file if running autoconf. 00029 #ifdef HAVE_CONFIG_H 00030 #include "config_auto.h" 00031 #endif 00032 00033 /*---------------------------------------------------------------------- 00034 I n c l u d e s 00035 ----------------------------------------------------------------------*/ 00036 #include "blobs.h" 00037 #include "split.h" 00038 00039 /*---------------------------------------------------------------------- 00040 T y p e s 00041 ----------------------------------------------------------------------*/ 00042 typedef float PRIORITY; /* PRIORITY */ 00043 00044 class SEAM { 00045 public: 00046 // A seam with no splits 00047 SEAM(float priority, const TPOINT& location) 00048 : priority_(priority), 00049 location_(location), 00050 widthp_(0), 00051 widthn_(0), 00052 num_splits_(0) {} 00053 // A seam with a single split point. 00054 SEAM(float priority, const TPOINT& location, const SPLIT& split) 00055 : priority_(priority), 00056 location_(location), 00057 widthp_(0), 00058 widthn_(0), 00059 num_splits_(1) { 00060 splits_[0] = split; 00061 } 00062 // Default copy constructor, operator= and destructor are OK! 00063 00064 // Accessors. 00065 float priority() const { return priority_; } 00066 void set_priority(float priority) { priority_ = priority; } 00067 bool HasAnySplits() const { return num_splits_ > 0; } 00068 00069 // Returns the bounding box of all the points in the seam. 00070 TBOX bounding_box() const; 00071 00072 // Returns true if other can be combined into *this. 00073 bool CombineableWith(const SEAM& other, int max_x_dist, 00074 float max_total_priority) const; 00075 // Combines other into *this. Only works if CombinableWith returned true. 00076 void CombineWith(const SEAM& other); 00077 00078 // Returns true if the given blob contains all splits of *this SEAM. 00079 bool ContainedByBlob(const TBLOB& blob) const { 00080 for (int s = 0; s < num_splits_; ++s) { 00081 if (!splits_[s].ContainedByBlob(blob)) return false; 00082 } 00083 return true; 00084 } 00085 00086 // Returns true if the given EDGEPT is used by this SEAM, checking only 00087 // the EDGEPT pointer, not the coordinates. 00088 bool UsesPoint(const EDGEPT* point) const { 00089 for (int s = 0; s < num_splits_; ++s) { 00090 if (splits_[s].UsesPoint(point)) return true; 00091 } 00092 return false; 00093 } 00094 // Returns true if *this and other share any common point, by coordinates. 00095 bool SharesPosition(const SEAM& other) const { 00096 for (int s = 0; s < num_splits_; ++s) { 00097 for (int t = 0; t < other.num_splits_; ++t) 00098 if (splits_[s].SharesPosition(other.splits_[t])) return true; 00099 } 00100 return false; 00101 } 00102 // Returns true if *this and other have any vertically overlapping splits. 00103 bool OverlappingSplits(const SEAM& other) const { 00104 for (int s = 0; s < num_splits_; ++s) { 00105 TBOX split1_box = splits_[s].bounding_box(); 00106 for (int t = 0; t < other.num_splits_; ++t) { 00107 TBOX split2_box = other.splits_[t].bounding_box(); 00108 if (split1_box.y_overlap(split2_box)) return true; 00109 } 00110 } 00111 return false; 00112 } 00113 00114 // Marks the edgepts used by the seam so the segments made by the cut 00115 // never get split further by another seam in the future. 00116 void Finalize() { 00117 for (int s = 0; s < num_splits_; ++s) { 00118 splits_[s].point1->MarkChop(); 00119 splits_[s].point2->MarkChop(); 00120 } 00121 } 00122 00123 // Returns true if the splits in *this SEAM appear OK in the sense that they 00124 // do not cross any outlines and do not chop off any ridiculously small 00125 // pieces. 00126 bool IsHealthy(const TBLOB& blob, int min_points, int min_area) const; 00127 00128 // Computes the widthp_/widthn_ range for all existing SEAMs and for *this 00129 // seam, which is about to be inserted at insert_index. Returns false if 00130 // any of the computations fails, as this indicates an invalid chop. 00131 // widthn_/widthp_ are only changed if modify is true. 00132 bool PrepareToInsertSeam(const GenericVector<SEAM*>& seams, 00133 const GenericVector<TBLOB*>& blobs, int insert_index, 00134 bool modify); 00135 // Computes the widthp_/widthn_ range. Returns false if not all the splits 00136 // are accounted for. widthn_/widthp_ are only changed if modify is true. 00137 bool FindBlobWidth(const GenericVector<TBLOB*>& blobs, int index, 00138 bool modify); 00139 00140 // Splits this blob into two blobs by applying the splits included in 00141 // *this SEAM 00142 void ApplySeam(bool italic_blob, TBLOB* blob, TBLOB* other_blob) const; 00143 // Undoes ApplySeam by removing the seam between these two blobs. 00144 // Produces one blob as a result, and deletes other_blob. 00145 void UndoSeam(TBLOB* blob, TBLOB* other_blob) const; 00146 00147 // Prints everything in *this SEAM. 00148 void Print(const char* label) const; 00149 // Prints a collection of SEAMs. 00150 static void PrintSeams(const char* label, const GenericVector<SEAM*>& seams); 00151 #ifndef GRAPHICS_DISABLED 00152 // Draws the seam in the given window. 00153 void Mark(ScrollView* window) const; 00154 #endif 00155 00156 // Break up the blobs in this chain so that they are all independent. 00157 // This operation should undo the affect of join_pieces. 00158 static void BreakPieces(const GenericVector<SEAM*>& seams, 00159 const GenericVector<TBLOB*>& blobs, int first, 00160 int last); 00161 // Join a group of base level pieces into a single blob that can then 00162 // be classified. 00163 static void JoinPieces(const GenericVector<SEAM*>& seams, 00164 const GenericVector<TBLOB*>& blobs, int first, 00165 int last); 00166 00167 // Hides the seam so the outlines appear not to be cut by it. 00168 void Hide() const; 00169 // Undoes hide, so the outlines are cut by the seam. 00170 void Reveal() const; 00171 00172 // Computes and returns, but does not set, the full priority of *this SEAM. 00173 // The arguments here are config parameters defined in Wordrec. Add chop_ 00174 // to the beginning of the name. 00175 float FullPriority(int xmin, int xmax, double overlap_knob, 00176 int centered_maxwidth, double center_knob, 00177 double width_change_knob) const; 00178 00179 private: 00180 // Maximum number of splits that a SEAM can hold. 00181 static const int kMaxNumSplits = 3; 00182 // Priority of this split. Lower is better. 00183 float priority_; 00184 // Position of the middle of the seam. 00185 TPOINT location_; 00186 // A range such that all splits in *this SEAM are contained within blobs in 00187 // the range [index - widthn_,index + widthp_] where index is the index of 00188 // this SEAM in the seams vector. 00189 inT8 widthp_; 00190 inT8 widthn_; 00191 // Number of splits_ that are used. 00192 inT8 num_splits_; 00193 // Set of pairs of points that are the ends of each split in the SEAM. 00194 SPLIT splits_[kMaxNumSplits]; 00195 }; 00196 00197 /*---------------------------------------------------------------------- 00198 F u n c t i o n s 00199 ----------------------------------------------------------------------*/ 00200 00201 void start_seam_list(TWERD* word, GenericVector<SEAM*>* seam_array); 00202 00203 #endif