tesseract  5.0.0
edgloop.cpp
Go to the documentation of this file.
1 /**********************************************************************
2  * File: edgloop.cpp (Formerly edgeloop.c)
3  * Description: Functions to clean up an outline before approximation.
4  * Author: Ray Smith
5  *
6  * (C) Copyright 1991, Hewlett-Packard Ltd.
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 // Include automatically generated configuration file if running autoconf.
20 #ifdef HAVE_CONFIG_H
21 # include "config_auto.h"
22 #endif
23 
24 #include "scanedg.h"
25 
26 #include "edgloop.h"
27 
28 namespace tesseract {
29 
30 #define MINEDGELENGTH 8 // min decent length
31 
32 /**********************************************************************
33  * complete_edge
34  *
35  * Complete the edge by cleaning it up.
36  **********************************************************************/
37 
38 void complete_edge(CRACKEDGE *start, // start of loop
39  C_OUTLINE_IT *outline_it) {
40  ScrollView::Color colour; // colour to draw in
41  int16_t looplength; // steps in loop
42  ICOORD botleft; // bounding box
43  ICOORD topright;
44  C_OUTLINE *outline; // new outline
45 
46  // check length etc.
47  colour = check_path_legal(start);
48 
49  if (colour == ScrollView::RED || colour == ScrollView::BLUE) {
50  looplength = loop_bounding_box(start, botleft, topright);
51  outline = new C_OUTLINE(start, botleft, topright, looplength);
52  // add to list
53  outline_it->add_after_then_move(outline);
54  }
55 }
56 
57 /**********************************************************************
58  * check_path_legal
59  *
60  * Check that the outline is legal for length and for chaincode sum.
61  * The return value is RED for a normal black-inside outline,
62  * BLUE for a white-inside outline, MAGENTA if it is too short,
63  * YELLOW if it is too long, and GREEN if it is illegal.
64  * These colours are used to draw the raw outline.
65  **********************************************************************/
66 
68  CRACKEDGE *start // start of loop
69 ) {
70  int lastchain; // last chain code
71  int chaindiff; // chain code diff
72  int32_t length; // length of loop
73  int32_t chainsum; // sum of chain diffs
74  CRACKEDGE *edgept; // current point
75  constexpr ERRCODE ED_ILLEGAL_SUM("Illegal sum of chain codes");
76 
77  length = 0;
78  chainsum = 0; // sum of chain codes
79  edgept = start;
80  lastchain = edgept->prev->stepdir; // previous chain code
81  do {
82  length++;
83  if (edgept->stepdir != lastchain) {
84  // chain code difference
85  chaindiff = edgept->stepdir - lastchain;
86  if (chaindiff > 2) {
87  chaindiff -= 4;
88  } else if (chaindiff < -2) {
89  chaindiff += 4;
90  }
91  chainsum += chaindiff; // sum differences
92  lastchain = edgept->stepdir;
93  }
94  edgept = edgept->next;
95  } while (edgept != start && length < C_OUTLINE::kMaxOutlineLength);
96 
97  if ((chainsum != 4 && chainsum != -4) || edgept != start || length < MINEDGELENGTH) {
98  if (edgept != start) {
99  return ScrollView::YELLOW;
100  } else if (length < MINEDGELENGTH) {
101  return ScrollView::MAGENTA;
102  } else {
103  ED_ILLEGAL_SUM.error("check_path_legal", TESSLOG, "chainsum=%d", chainsum);
104  return ScrollView::GREEN;
105  }
106  }
107  // colour on inside
108  return chainsum < 0 ? ScrollView::BLUE : ScrollView::RED;
109 }
110 
111 /**********************************************************************
112  * loop_bounding_box
113  *
114  * Find the bounding box of the edge loop.
115  **********************************************************************/
116 
117 int16_t loop_bounding_box( // get bounding box
118  CRACKEDGE *&start, // edge loop
119  ICOORD &botleft, // bounding box
120  ICOORD &topright) {
121  int16_t length; // length of loop
122  int16_t leftmost; // on top row
123  CRACKEDGE *edgept; // current point
124  CRACKEDGE *realstart; // topleft start
125 
126  edgept = start;
127  realstart = start;
128  botleft = topright = ICOORD(edgept->pos.x(), edgept->pos.y());
129  leftmost = edgept->pos.x();
130  length = 0; // coutn length
131  do {
132  edgept = edgept->next;
133  if (edgept->pos.x() < botleft.x()) {
134  // get bounding box
135  botleft.set_x(edgept->pos.x());
136  } else if (edgept->pos.x() > topright.x()) {
137  topright.set_x(edgept->pos.x());
138  }
139  if (edgept->pos.y() < botleft.y()) {
140  // get bounding box
141  botleft.set_y(edgept->pos.y());
142  } else if (edgept->pos.y() > topright.y()) {
143  realstart = edgept;
144  leftmost = edgept->pos.x();
145  topright.set_y(edgept->pos.y());
146  } else if (edgept->pos.y() == topright.y() && edgept->pos.x() < leftmost) {
147  // leftmost on line
148  leftmost = edgept->pos.x();
149  realstart = edgept;
150  }
151  length++; // count elements
152  } while (edgept != start);
153  start = realstart; // shift it to topleft
154  return length;
155 }
156 
157 } // namespace tesseract
#define MINEDGELENGTH
Definition: edgloop.cpp:30
void complete_edge(CRACKEDGE *start, C_OUTLINE_IT *outline_it)
Definition: edgloop.cpp:38
int16_t loop_bounding_box(CRACKEDGE *&start, ICOORD &botleft, ICOORD &topright)
Definition: edgloop.cpp:117
ScrollView::Color check_path_legal(CRACKEDGE *start)
Definition: edgloop.cpp:67
@ TESSLOG
Definition: errcode.h:29
static const int kMaxOutlineLength
Definition: coutln.h:273
CRACKEDGE * next
Definition: crakedge.h:37
CRACKEDGE * prev
Definition: crakedge.h:36
integer coordinate
Definition: points.h:36
void set_x(TDimension xin)
rewrite function
Definition: points.h:67
TDimension y() const
access_function
Definition: points.h:62
void set_y(TDimension yin)
rewrite function
Definition: points.h:71
TDimension x() const
access function
Definition: points.h:58