1 ///////////////////////////////////////////////////////////////////////
2 // File:        linefind.h
3 // Description: Class to find vertical lines in an image and create
4 //              a corresponding list of empty blobs.
5 // Author:      Ray Smith
6 // Created:     Thu Mar 20 09:49:01 PDT 2008
7 //
8 // (C) Copyright 2008, Google Inc.
9 // Licensed under the Apache License, Version 2.0 (the "License");
10 // you may not use this file except in compliance with the License.
11 // You may obtain a copy of the License at
12 // http://www.apache.org/licenses/LICENSE-2.0
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
18 //
19 ///////////////////////////////////////////////////////////////////////
20 
21 #ifndef TESSERACT_TEXTORD_LINEFIND_H_
22 #define TESSERACT_TEXTORD_LINEFIND_H_
23 
24 struct Boxa;
25 struct Pix;
26 struct Pixa;
27 
28 namespace tesseract {
29 
30 class TabVector_LIST;
31 class C_BLOB_LIST;
32 class BLOBNBOX_LIST;
33 class ICOORD;
34 
35 /**
36  * The LineFinder class is a simple static function wrapper class that mainly
37  * exposes the FindVerticalLines function.
38  */
39 class LineFinder {
40 public:
41   /**
42    * Finds vertical and horizontal line objects in the given pix and removes
43    * them.
44    *
45    * Uses the given resolution to determine size thresholds instead of any
46    * that may be present in the pix.
47    *
48    * The output vertical_x and vertical_y contain a sum of the output vectors,
49    * thereby giving the mean vertical direction.
50    *
51    * If pix_music_mask != nullptr, and music is detected, a mask of the staves
52    * and anything that is connected (bars, notes etc.) will be returned in
53    * pix_music_mask, the mask subtracted from pix, and the lines will not
54    * appear in v_lines or h_lines.
55    *
56    * The output vectors are owned by the list and Frozen (cannot refit) by
57    * having no boxes, as there is no need to refit or merge separator lines.
58    *
59    * The detected lines are removed from the pix.
60    */
61   static void FindAndRemoveLines(int resolution, bool debug, Image pix, int *vertical_x,
62                                  int *vertical_y, Image *pix_music_mask, TabVector_LIST *v_lines,
63                                  TabVector_LIST *h_lines);
64 
65   /**
66    * Converts the Boxa array to a list of C_BLOB, getting rid of severely
67    * overlapping outlines and those that are children of a bigger one.
68    *
69    * The output is a list of C_BLOBs that are owned by the list.
70    *
71    * The C_OUTLINEs in the C_BLOBs contain no outline data - just empty
72    * bounding boxes. The Boxa is consumed and destroyed.
73    */
74   static void ConvertBoxaToBlobs(int image_width, int image_height, Boxa **boxes,
75                                  C_BLOB_LIST *blobs);
76 
77 private:
78   // Finds vertical line objects in pix_vline and removes them from src_pix.
79   // Uses the given resolution to determine size thresholds instead of any
80   // that may be present in the pix.
81   // The output vertical_x and vertical_y contain a sum of the output vectors,
82   // thereby giving the mean vertical direction.
83   // The output vectors are owned by the list and Frozen (cannot refit) by
84   // having no boxes, as there is no need to refit or merge separator lines.
85   // If no good lines are found, pix_vline is destroyed.
86   static void FindAndRemoveVLines(int resolution, Image pix_intersections, int *vertical_x,
87                                   int *vertical_y, Image *pix_vline, Image pix_non_vline,
88                                   Image src_pix, TabVector_LIST *vectors);
89 
90   // Finds horizontal line objects in pix_vline and removes them from src_pix.
91   // Uses the given resolution to determine size thresholds instead of any
92   // that may be present in the pix.
93   // The output vertical_x and vertical_y contain a sum of the output vectors,
94   // thereby giving the mean vertical direction.
95   // The output vectors are owned by the list and Frozen (cannot refit) by
96   // having no boxes, as there is no need to refit or merge separator lines.
97   // If no good lines are found, pix_hline is destroyed.
98   static void FindAndRemoveHLines(int resolution, Image pix_intersections, int vertical_x,
99                                   int vertical_y, Image *pix_hline, Image pix_non_hline, Image src_pix,
100                                   TabVector_LIST *vectors);
101 
102   // Finds vertical lines in the given list of BLOBNBOXes. bleft and tright
103   // are the bounds of the image on which the input line_bblobs were found.
104   // The input line_bblobs list is const really.
105   // The output vertical_x and vertical_y are the total of all the vectors.
106   // The output list of TabVector makes no reference to the input BLOBNBOXes.
107   static void FindLineVectors(const ICOORD &bleft, const ICOORD &tright, BLOBNBOX_LIST *line_bblobs,
108                               int *vertical_x, int *vertical_y, TabVector_LIST *vectors);
109 
110   // Most of the heavy lifting of line finding. Given src_pix and its separate
111   // resolution, returns image masks:
112   // Returns image masks:
113   // pix_vline           candidate vertical lines.
114   // pix_non_vline       pixels that didn't look like vertical lines.
115   // pix_hline           candidate horizontal lines.
116   // pix_non_hline       pixels that didn't look like horizontal lines.
117   // pix_intersections   pixels where vertical and horizontal lines meet.
118   // pix_music_mask      candidate music staves.
119   // This function promises to initialize all the output (2nd level) pointers,
120   // but any of the returns that are empty will be nullptr on output.
121   // None of the input (1st level) pointers may be nullptr except
122   // pix_music_mask, which will disable music detection, and pixa_display, which
123   // is for debug.
124   static void GetLineMasks(int resolution, Image src_pix, Image *pix_vline, Image *pix_non_vline,
125                            Image *pix_hline, Image *pix_non_hline, Image *pix_intersections,
126                            Image *pix_music_mask, Pixa *pixa_display);
127 
128   // Returns a list of boxes corresponding to the candidate line segments. Sets
129   // the line_crossings member of the boxes so we can later determine the number
130   // of intersections touched by a full line.
131   static void GetLineBoxes(bool horizontal_lines, Image pix_lines, Image pix_intersections,
132                            C_BLOB_LIST *line_cblobs, BLOBNBOX_LIST *line_bblobs);
133 };
134 
135 } // namespace tesseract.
136 
137 #endif // TESSERACT_TEXTORD_LINEFIND_H_
138