Mercurial > hgrepos > Python2 > PyMuPDF
comparison mupdf-source/thirdparty/tesseract/src/textord/colpartitiongrid.h @ 2:b50eed0cc0ef upstream
ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4.
The directory name has changed: no version number in the expanded directory now.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 15 Sep 2025 11:43:07 +0200 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 1:1d09e1dec1d9 | 2:b50eed0cc0ef |
|---|---|
| 1 /////////////////////////////////////////////////////////////////////// | |
| 2 // File: colpartitiongrid.h | |
| 3 // Description: Class collecting code that acts on a BBGrid of ColPartitions. | |
| 4 // Author: Ray Smith | |
| 5 // | |
| 6 // (C) Copyright 2009, Google Inc. | |
| 7 // Licensed under the Apache License, Version 2.0 (the "License"); | |
| 8 // you may not use this file except in compliance with the License. | |
| 9 // You may obtain a copy of the License at | |
| 10 // http://www.apache.org/licenses/LICENSE-2.0 | |
| 11 // Unless required by applicable law or agreed to in writing, software | |
| 12 // distributed under the License is distributed on an "AS IS" BASIS, | |
| 13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 14 // See the License for the specific language governing permissions and | |
| 15 // limitations under the License. | |
| 16 // | |
| 17 /////////////////////////////////////////////////////////////////////// | |
| 18 | |
| 19 #ifndef TESSERACT_TEXTORD_COLPARTITIONGRID_H_ | |
| 20 #define TESSERACT_TEXTORD_COLPARTITIONGRID_H_ | |
| 21 | |
| 22 #include "bbgrid.h" | |
| 23 #include "colpartition.h" | |
| 24 #include "colpartitionset.h" | |
| 25 | |
| 26 namespace tesseract { | |
| 27 | |
| 28 class TabFind; | |
| 29 | |
| 30 // ColPartitionGrid is a BBGrid of ColPartition. | |
| 31 // It collects functions that work on the grid. | |
| 32 class TESS_API ColPartitionGrid | |
| 33 : public BBGrid<ColPartition, ColPartition_CLIST, ColPartition_C_IT> { | |
| 34 public: | |
| 35 ColPartitionGrid() = default; | |
| 36 ColPartitionGrid(int gridsize, const ICOORD &bleft, const ICOORD &tright); | |
| 37 | |
| 38 ~ColPartitionGrid() override = default; | |
| 39 | |
| 40 // Handles a click event in a display window. | |
| 41 void HandleClick(int x, int y) override; | |
| 42 | |
| 43 // Merges ColPartitions in the grid that look like they belong in the same | |
| 44 // textline. | |
| 45 // For all partitions in the grid, calls the box_cb permanent callback | |
| 46 // to compute the search box, searches the box, and if a candidate is found, | |
| 47 // calls the confirm_cb to check any more rules. If the confirm_cb returns | |
| 48 // true, then the partitions are merged. | |
| 49 // Both callbacks are deleted before returning. | |
| 50 void Merges(const std::function<bool(ColPartition *, TBOX *)> &box_cb, | |
| 51 const std::function<bool(const ColPartition *, | |
| 52 const ColPartition *)> &confirm_cb); | |
| 53 | |
| 54 // For the given partition, calls the box_cb permanent callback | |
| 55 // to compute the search box, searches the box, and if a candidate is found, | |
| 56 // calls the confirm_cb to check any more rules. If the confirm_cb returns | |
| 57 // true, then the partitions are merged. | |
| 58 // Returns true if the partition is consumed by one or more merges. | |
| 59 bool MergePart(const std::function<bool(ColPartition *, TBOX *)> &box_cb, | |
| 60 const std::function<bool(const ColPartition *, | |
| 61 const ColPartition *)> &confirm_cb, | |
| 62 ColPartition *part); | |
| 63 | |
| 64 // Computes and returns the total overlap of all partitions in the grid. | |
| 65 // If overlap_grid is non-null, it is filled with a grid that holds empty | |
| 66 // partitions representing the union of all overlapped partitions. | |
| 67 int ComputeTotalOverlap(ColPartitionGrid **overlap_grid); | |
| 68 | |
| 69 // Finds all the ColPartitions in the grid that overlap with the given | |
| 70 // box and returns them SortByBoxLeft(ed) and uniqued in the given list. | |
| 71 // Any partition equal to not_this (may be nullptr) is excluded. | |
| 72 void FindOverlappingPartitions(const TBOX &box, const ColPartition *not_this, | |
| 73 ColPartition_CLIST *parts); | |
| 74 | |
| 75 // Finds and returns the best candidate ColPartition to merge with part, | |
| 76 // selected from the candidates list, based on the minimum increase in | |
| 77 // pairwise overlap among all the partitions overlapped by the combined box. | |
| 78 // If overlap_increase is not nullptr then it returns the increase in overlap | |
| 79 // that would result from the merge. | |
| 80 // See colpartitiongrid.cpp for a diagram. | |
| 81 ColPartition *BestMergeCandidate( | |
| 82 const ColPartition *part, ColPartition_CLIST *candidates, bool debug, | |
| 83 const std::function<bool(const ColPartition *, const ColPartition *)> | |
| 84 &confirm_cb, | |
| 85 int *overlap_increase); | |
| 86 | |
| 87 // Split partitions where it reduces overlap between their bounding boxes. | |
| 88 // ColPartitions are after all supposed to be a partitioning of the blobs | |
| 89 // AND of the space on the page! | |
| 90 // Blobs that cause overlaps get removed, put in individual partitions | |
| 91 // and added to the big_parts list. They are most likely characters on | |
| 92 // 2 textlines that touch, or something big like a dropcap. | |
| 93 void SplitOverlappingPartitions(ColPartition_LIST *big_parts); | |
| 94 | |
| 95 // Filters partitions of source_type by looking at local neighbours. | |
| 96 // Where a majority of neighbours have a text type, the partitions are | |
| 97 // changed to text, where the neighbours have image type, they are changed | |
| 98 // to image, and partitions that have no definite neighbourhood type are | |
| 99 // left unchanged. | |
| 100 // im_box and rerotation are used to map blob coordinates onto the | |
| 101 // nontext_map, which is used to prevent the spread of text neighbourhoods | |
| 102 // into images. | |
| 103 // Returns true if anything was changed. | |
| 104 bool GridSmoothNeighbours(BlobTextFlowType source_type, Image nontext_map, | |
| 105 const TBOX &im_box, const FCOORD &rerotation); | |
| 106 | |
| 107 // Reflects the grid and its colpartitions in the y-axis, assuming that | |
| 108 // all blob boxes have already been done. | |
| 109 void ReflectInYAxis(); | |
| 110 | |
| 111 // Rotates the grid and its colpartitions by the given angle, assuming that | |
| 112 // all blob boxes have already been done. | |
| 113 void Deskew(const FCOORD &deskew); | |
| 114 | |
| 115 // Transforms the grid of partitions to the output blocks, putting each | |
| 116 // partition into a separate block. We don't really care about the order, | |
| 117 // as we just want to get as much text as possible without trying to organize | |
| 118 // it into proper blocks or columns. | |
| 119 void ExtractPartitionsAsBlocks(BLOCK_LIST *blocks, TO_BLOCK_LIST *to_blocks); | |
| 120 | |
| 121 // Sets the left and right tabs of the partitions in the grid. | |
| 122 void SetTabStops(TabFind *tabgrid); | |
| 123 | |
| 124 // Makes the ColPartSets and puts them in the PartSetVector ready | |
| 125 // for finding column bounds. Returns false if no partitions were found. | |
| 126 // Each ColPartition in the grid is placed in a single ColPartSet based | |
| 127 // on the bottom-left of its bounding box. | |
| 128 bool MakeColPartSets(PartSetVector *part_sets); | |
| 129 | |
| 130 // Makes a single ColPartitionSet consisting of a single ColPartition that | |
| 131 // represents the total horizontal extent of the significant content on the | |
| 132 // page. Used for the single column setting in place of automatic detection. | |
| 133 // Returns nullptr if the page is empty of significant content. | |
| 134 ColPartitionSet *MakeSingleColumnSet(WidthCallback cb); | |
| 135 | |
| 136 // Mark the BLOBNBOXes in each partition as being owned by that partition. | |
| 137 void ClaimBoxes(); | |
| 138 | |
| 139 // Retypes all the blobs referenced by the partitions in the grid. | |
| 140 // Image blobs are sliced on the grid boundaries to give the tab finder | |
| 141 // a better handle on the edges of the images, and the actual blobs are | |
| 142 // returned in the im_blobs list, as they are not owned by the block. | |
| 143 void ReTypeBlobs(BLOBNBOX_LIST *im_blobs); | |
| 144 | |
| 145 // The boxes within the partitions have changed (by deskew) so recompute | |
| 146 // the bounds of all the partitions and reinsert them into the grid. | |
| 147 void RecomputeBounds(int gridsize, const ICOORD &bleft, const ICOORD &tright, | |
| 148 const ICOORD &vertical); | |
| 149 | |
| 150 // Improves the margins of the ColPartitions in the grid by calling | |
| 151 // FindPartitionMargins on each. | |
| 152 void GridFindMargins(ColPartitionSet **best_columns); | |
| 153 | |
| 154 // Improves the margins of the ColPartitions in the list by calling | |
| 155 // FindPartitionMargins on each. | |
| 156 void ListFindMargins(ColPartitionSet **best_columns, | |
| 157 ColPartition_LIST *parts); | |
| 158 | |
| 159 // Deletes all the partitions in the grid after disowning all the blobs. | |
| 160 void DeleteParts(); | |
| 161 | |
| 162 // Deletes all the partitions in the grid that are of type BRT_UNKNOWN and | |
| 163 // all the blobs in them. | |
| 164 void DeleteUnknownParts(TO_BLOCK *block); | |
| 165 | |
| 166 // Deletes all the partitions in the grid that are NOT of flow type | |
| 167 // BTFT_LEADER. | |
| 168 void DeleteNonLeaderParts(); | |
| 169 | |
| 170 // Finds and marks text partitions that represent figure captions. | |
| 171 void FindFigureCaptions(); | |
| 172 | |
| 173 //////// Functions that manipulate ColPartitions in the grid /////// | |
| 174 //////// to find chains of partner partitions of the same type. /////// | |
| 175 // For every ColPartition in the grid, finds its upper and lower neighbours. | |
| 176 void FindPartitionPartners(); | |
| 177 // Finds the best partner in the given direction for the given partition. | |
| 178 // Stores the result with AddPartner. | |
| 179 void FindPartitionPartners(bool upper, ColPartition *part); | |
| 180 // Finds the best partner in the given direction for the given partition. | |
| 181 // Stores the result with AddPartner. | |
| 182 void FindVPartitionPartners(bool to_the_left, ColPartition *part); | |
| 183 // For every ColPartition with multiple partners in the grid, reduces the | |
| 184 // number of partners to 0 or 1. If get_desperate is true, goes to more | |
| 185 // desperate merge methods to merge flowing text before breaking partnerships. | |
| 186 void RefinePartitionPartners(bool get_desperate); | |
| 187 | |
| 188 private: | |
| 189 // Finds and returns a list of candidate ColPartitions to merge with part. | |
| 190 // The candidates must overlap search_box, and when merged must not | |
| 191 // overlap any other partitions that are not overlapped by each individually. | |
| 192 void FindMergeCandidates(const ColPartition *part, const TBOX &search_box, | |
| 193 bool debug, ColPartition_CLIST *candidates); | |
| 194 | |
| 195 // Smoothes the region type/flow type of the given part by looking at local | |
| 196 // neighbours and the given image mask. Searches a padded rectangle with the | |
| 197 // padding truncated on one size of the part's box in turn for each side, | |
| 198 // using the result (if any) that has the least distance to all neighbours | |
| 199 // that contribute to the decision. This biases in favor of rectangular | |
| 200 // regions without completely enforcing them. | |
| 201 // If a good decision cannot be reached, the part is left unchanged. | |
| 202 // im_box and rerotation are used to map blob coordinates onto the | |
| 203 // nontext_map, which is used to prevent the spread of text neighbourhoods | |
| 204 // into images. | |
| 205 // Returns true if the partition was changed. | |
| 206 bool SmoothRegionType(Image nontext_map, const TBOX &im_box, | |
| 207 const FCOORD &rerotation, bool debug, | |
| 208 ColPartition *part); | |
| 209 // Executes the search for SmoothRegionType in a single direction. | |
| 210 // Creates a bounding box that is padded in all directions except direction, | |
| 211 // and searches it for other partitions. Finds the nearest collection of | |
| 212 // partitions that makes a decisive result (if any) and returns the type | |
| 213 // and the distance of the collection. If there are any pixels in the | |
| 214 // nontext_map, then the decision is biased towards image. | |
| 215 BlobRegionType SmoothInOneDirection(BlobNeighbourDir direction, | |
| 216 Image nontext_map, const TBOX &im_box, | |
| 217 const FCOORD &rerotation, bool debug, | |
| 218 const ColPartition &part, | |
| 219 int *best_distance); | |
| 220 // Counts the partitions in the given search_box by appending the gap | |
| 221 // distance (scaled by dist_scaling) of the part from the base_part to the | |
| 222 // vector of the appropriate type for the partition. Prior to return, the | |
| 223 // vectors in the dists array are sorted in increasing order. | |
| 224 // dists must be an array of vectors of size NPT_COUNT. | |
| 225 void AccumulatePartDistances(const ColPartition &base_part, | |
| 226 const ICOORD &dist_scaling, | |
| 227 const TBOX &search_box, Image nontext_map, | |
| 228 const TBOX &im_box, const FCOORD &rerotation, | |
| 229 bool debug, std::vector<int> *dists); | |
| 230 | |
| 231 // Improves the margins of the ColPartition by searching for | |
| 232 // neighbours that vertically overlap significantly. | |
| 233 void FindPartitionMargins(ColPartitionSet *columns, ColPartition *part); | |
| 234 | |
| 235 // Starting at x, and going in the specified direction, up to x_limit, finds | |
| 236 // the margin for the given y range by searching sideways, | |
| 237 // and ignoring not_this. | |
| 238 int FindMargin(int x, bool right_to_left, int x_limit, int y_bottom, | |
| 239 int y_top, const ColPartition *not_this); | |
| 240 }; | |
| 241 | |
| 242 } // namespace tesseract. | |
| 243 | |
| 244 #endif // TESSERACT_TEXTORD_COLPARTITIONGRID_H_ |
