Tesseract 3.01
|
00001 00002 // File: strokewidth.h 00003 // Description: Subclass of BBGrid to find uniformity of strokewidth. 00004 // Author: Ray Smith 00005 // Created: Mon Mar 31 16:17:01 PST 2008 00006 // 00007 // (C) Copyright 2008, Google Inc. 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 // 00019 00020 #ifndef TESSERACT_TEXTORD_STROKEWIDTH_H__ 00021 #define TESSERACT_TEXTORD_STROKEWIDTH_H__ 00022 00023 #include "bbgrid.h" // Base class. 00024 #include "blobbox.h" // BlobNeighourDir. 00025 #include "tabvector.h" // For BLOBNBOX_CLIST. 00026 00027 class TO_BLOCK; 00028 class ScrollView; 00029 00030 namespace tesseract { 00031 00032 class ColPartition_LIST; 00033 class TabFind; 00034 00040 class StrokeWidth : public BBGrid<BLOBNBOX, BLOBNBOX_CLIST, BLOBNBOX_C_IT> { 00041 public: 00042 StrokeWidth(int gridsize, const ICOORD& bleft, const ICOORD& tright); 00043 virtual ~StrokeWidth(); 00044 00045 // To save computation, the process of generating partitions is broken 00046 // into the following 4 steps: 00047 // TestVerticalTextDirection 00048 // CorrectForRotation (used only if a rotation is to be applied) 00049 // FindLeaderPartitions 00050 // TODO(rays) Coming soon: 00051 // GradeBlobsIntoPartitions. 00052 // which will replace entirely the old call sequence of: 00053 // InsertBlobsOld 00054 // MoveGoodLargeBlobs. 00055 // These functions are all required, in sequence, except for 00056 // CorrectForRotation, which is not needed if no rotation is applied. 00057 00058 // Types all the blobs as vertical or horizontal text or unknown and 00059 // returns true if the majority are vertical. 00060 // If the blobs are rotated, it is necessary to call CorrectForRotation 00061 // after rotating everything, otherwise the work done here will be enough. 00062 // If cjk_merge is true, it will attempt to merge broken cjk characters. 00063 // If osd_blobs is not null, a list of blobs from the dominant textline 00064 // direction are returned for use in orientation and script detection. 00065 bool TestVerticalTextDirection(bool cjk_merge, 00066 TO_BLOCK* block, TabFind* line_grid, 00067 BLOBNBOX_CLIST* osd_blobs); 00068 00069 // Corrects the data structures for the given rotation. 00070 void CorrectForRotation(const FCOORD& rotation, TO_BLOCK* block); 00071 00072 // Finds leader partitions and inserts them into the give grid. 00073 void FindLeaderPartitions(TO_BLOCK* block, TabFind* line_grid); 00074 00075 // Handles a click event in a display window. 00076 virtual void HandleClick(int x, int y); 00077 00078 // Puts the block blobs (normal and large) into the grid. 00079 void InsertBlobsOld(TO_BLOCK* block, TabFind* line_grid); 00080 00081 // Moves the large blobs that have good stroke-width neighbours to the normal 00082 // blobs list. 00083 void MoveGoodLargeBlobs(int resolution, TO_BLOCK* block); 00084 00085 private: 00086 // Reorganize the blob lists with a different definition of small, medium 00087 // and large, compared to the original definition. 00088 // Height is still the primary filter key, but medium width blobs of small 00089 // height become medium, and very wide blobs of small height stay small. 00090 void ReFilterBlobs(TO_BLOCK* block); 00091 00092 // Computes the noise_density_ by summing the number of elements in a 00093 // neighbourhood of each grid cell. 00094 void ComputeNoiseDensity(TO_BLOCK* block, TabFind* line_grid); 00095 00096 // Detects and marks leader dots/dashes. 00097 // Leaders are horizontal chains of small or noise blobs that look 00098 // monospace according to ColPartition::MarkAsLeaderIfMonospaced(). 00099 // Detected leaders become the only occupants of small_blobs list. 00100 // Non-leader small blobs get moved to the blobs list. 00101 // Non-leader noise blobs remain singletons in the noise list. 00102 // All small and noise blobs in high density regions are marked BTFT_NONTEXT. 00103 void FindLeadersAndMarkNoise(bool final, TO_BLOCK* block, TabFind* line_grid, 00104 ColPartition_LIST* leader_parts); 00105 00106 // Puts the block blobs (normal and large) into the grid. 00107 void InsertBlobs(TO_BLOCK* block, TabFind* line_grid); 00108 00109 // Fix broken CJK characters, using the fake joined blobs mechanism. 00110 // Blobs are really merged, ie the master takes all the outlines and the 00111 // others are deleted. 00112 void FixBrokenCJK(BLOBNBOX_LIST* blobs, TabFind* line_grid); 00113 00114 // Collect blobs that overlap or are within max_dist of the input bbox. 00115 // Return them in the list of blobs and expand the bbox to be the union 00116 // of all the boxes. not_this is excluded from the search, as are blobs 00117 // that cause the merged box to exceed max_size in either dimension. 00118 void AccumulateOverlaps(const BLOBNBOX* not_this, bool debug, 00119 int max_size, int max_dist, 00120 TBOX* bbox, BLOBNBOX_CLIST* blobs); 00121 00122 // Finds the textline direction to be horizontal or vertical according 00123 // to distance to neighbours and 1st and 2nd order neighbours. 00124 // Non-text tends to end up without a definite direction. 00125 void FindTextlineFlowDirection(bool final); 00126 00127 // Sets the neighbours and good_stroke_neighbours members of the blob by 00128 // searching close on all 4 sides. 00129 // When finding leader dots/dashes, there is a slightly different rule for 00130 // what makes a good neighbour. 00131 void SetNeighbours(bool leaders, BLOBNBOX* blob); 00132 00133 // Sets the good_stroke_neighbours member of the blob if it has a 00134 // GoodNeighbour on the given side. 00135 // Also sets the neighbour in the blob, whether or not a good one is found. 00136 // Return value is the number of neighbours in the line trap size range. 00137 // Leaders get extra special lenient treatment. 00138 int FindGoodNeighbour(BlobNeighbourDir dir, bool leaders, BLOBNBOX* blob); 00139 00140 // Makes the blob to be only horizontal or vertical where evidence 00141 // is clear based on gaps of 2nd order neighbours. 00142 void SetNeighbourFlows(BLOBNBOX* blob); 00143 00144 // Nullify the neighbours in the wrong directions where the direction 00145 // is clear-cut based on a distance margin. Good for isolating vertical 00146 // text from neighbouring horizontal text. 00147 void SimplifyObviousNeighbours(BLOBNBOX* blob); 00148 00149 // Smoothes the vertical/horizontal type of the blob based on the 00150 // 2nd-order neighbours. If reset_all is true, then all blobs are 00151 // changed. Otherwise, only ambiguous blobs are processed. 00152 void SmoothNeighbourTypes(BLOBNBOX* blob, bool desperate); 00153 00154 // Sets the leader_on_left or leader_on_right flags for blobs 00155 // that are next to one end of the given leader partition. 00156 // If left_of_part is true, then look at the left side of the partition for 00157 // blobs on which to set the leader_on_right flag. 00158 void MarkLeaderNeighbours(const ColPartition* part, bool left_of_part); 00159 00160 // Displays the blobs colored according to the number of good neighbours 00161 // and the vertical/horizontal flow. 00162 ScrollView* DisplayGoodBlobs(const char* window_name, int x, int y); 00163 00164 private: 00165 // Returns true if there is at least one side neighbour that has a similar 00166 // stroke width. 00167 bool GoodTextBlob(BLOBNBOX* blob); 00168 // Grid to indicate the dot noise density at each grid coord. 00169 IntGrid* noise_density_; 00170 // Windows for debug display. 00171 ScrollView* leaders_win_; 00172 ScrollView* initial_widths_win_; 00173 ScrollView* widths_win_; 00174 }; 00175 00176 } // namespace tesseract. 00177 00178 #endif // TESSERACT_TEXTORD_STROKEWIDTH_H__