tesseract  5.0.0-alpha-619-ge9db
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 "scanedg.h"
20 #include "edgloop.h"
21 
22 // Include automatically generated configuration file if running autoconf.
23 #ifdef HAVE_CONFIG_H
24 #include "config_auto.h"
25 #endif
26 
27 #define MINEDGELENGTH 8 // min decent length
28 
29 /**********************************************************************
30  * complete_edge
31  *
32  * Complete the edge by cleaning it up.
33  **********************************************************************/
34 
35 void complete_edge(CRACKEDGE *start, //start of loop
36  C_OUTLINE_IT* outline_it) {
37  ScrollView::Color colour; //colour to draw in
38  int16_t looplength; //steps in loop
39  ICOORD botleft; //bounding box
40  ICOORD topright;
41  C_OUTLINE *outline; //new outline
42 
43  //check length etc.
44  colour = check_path_legal (start);
45 
46  if (colour == ScrollView::RED || colour == ScrollView::BLUE) {
47  looplength = loop_bounding_box (start, botleft, topright);
48  outline = new C_OUTLINE (start, botleft, topright, looplength);
49  //add to list
50  outline_it->add_after_then_move (outline);
51  }
52 }
53 
54 
55 /**********************************************************************
56  * check_path_legal
57  *
58  * Check that the outline is legal for length and for chaincode sum.
59  * The return value is RED for a normal black-inside outline,
60  * BLUE for a white-inside outline, MAGENTA if it is too short,
61  * YELLOW if it is too long, and GREEN if it is illegal.
62  * These colours are used to draw the raw outline.
63  **********************************************************************/
64 
65 ScrollView::Color check_path_legal( //certify outline
66  CRACKEDGE *start //start of loop
67  ) {
68  int lastchain; //last chain code
69  int chaindiff; //chain code diff
70  int32_t length; //length of loop
71  int32_t chainsum; //sum of chain diffs
72  CRACKEDGE *edgept; //current point
73  constexpr ERRCODE ED_ILLEGAL_SUM("Illegal sum of chain codes");
74 
75  length = 0;
76  chainsum = 0; //sum of chain codes
77  edgept = start;
78  lastchain = edgept->prev->stepdir; //previous chain code
79  do {
80  length++;
81  if (edgept->stepdir != lastchain) {
82  //chain code difference
83  chaindiff = edgept->stepdir - lastchain;
84  if (chaindiff > 2)
85  chaindiff -= 4;
86  else if (chaindiff < -2)
87  chaindiff += 4;
88  chainsum += chaindiff; //sum differences
89  lastchain = edgept->stepdir;
90  }
91  edgept = edgept->next;
92  }
93  while (edgept != start && length < C_OUTLINE::kMaxOutlineLength);
94 
95  if ((chainsum != 4 && chainsum != -4)
96  || edgept != start || length < MINEDGELENGTH) {
97  if (edgept != start) {
98  return ScrollView::YELLOW;
99  } else if (length < MINEDGELENGTH) {
100  return ScrollView::MAGENTA;
101  } else {
102  ED_ILLEGAL_SUM.error ("check_path_legal", TESSLOG, "chainsum=%d",
103  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  if (edgept->pos.y () < botleft.y ())
139  //get bounding box
140  botleft.set_y (edgept->pos.y ());
141  else if (edgept->pos.y () > topright.y ()) {
142  realstart = edgept;
143  leftmost = edgept->pos.x ();
144  topright.set_y (edgept->pos.y ());
145  }
146  else if (edgept->pos.y () == topright.y ()
147  && edgept->pos.x () < leftmost) {
148  //leftmost on line
149  leftmost = edgept->pos.x ();
150  realstart = edgept;
151  }
152  length++; //count elements
153  }
154  while (edgept != start);
155  start = realstart; //shift it to topleft
156  return length;
157 }
ICOORD::set_x
void set_x(int16_t xin)
rewrite function
Definition: points.h:60
CRACKEDGE::next
CRACKEDGE * next
Definition: crakedge.h:50
ERRCODE
Definition: errcode.h:67
ICOORD
integer coordinate
Definition: points.h:30
loop_bounding_box
int16_t loop_bounding_box(CRACKEDGE *&start, ICOORD &botleft, ICOORD &topright)
Definition: edgloop.cpp:113
complete_edge
void complete_edge(CRACKEDGE *start, C_OUTLINE_IT *outline_it)
Definition: edgloop.cpp:33
ICOORD::x
int16_t x() const
access function
Definition: points.h:51
C_OUTLINE
class DLLSYM C_OUTLINE
Definition: coutln.h:67
check_path_legal
ScrollView::Color check_path_legal(CRACKEDGE *start)
Definition: edgloop.cpp:62
ScrollView::BLUE
Definition: scrollview.h:108
ICOORD::set_y
void set_y(int16_t yin)
rewrite function
Definition: points.h:64
C_OUTLINE
Definition: coutln.h:71
scanedg.h
TESSLOG
Definition: errcode.h:41
ScrollView::MAGENTA
Definition: scrollview.h:109
ScrollView::YELLOW
Definition: scrollview.h:105
CRACKEDGE::pos
ICOORD pos
Definition: crakedge.h:45
ScrollView::RED
Definition: scrollview.h:104
CRACKEDGE::stepdir
int8_t stepdir
Definition: crakedge.h:48
CRACKEDGE
Definition: crakedge.h:25
ScrollView::GREEN
Definition: scrollview.h:106
CRACKEDGE::prev
CRACKEDGE * prev
Definition: crakedge.h:49
C_OUTLINE::kMaxOutlineLength
static const int kMaxOutlineLength
Definition: coutln.h:272
ScrollView::Color
Color
Definition: scrollview.h:100
edgloop.h
ICOORD::y
int16_t y() const
access_function
Definition: points.h:55
MINEDGELENGTH
#define MINEDGELENGTH
Definition: edgloop.cpp:26