tesseract 4.1.1
Loading...
Searching...
No Matches
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
35void 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
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
117int16_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}
@ TESSLOG
Definition: errcode.h:27
int16_t loop_bounding_box(CRACKEDGE *&start, ICOORD &botleft, ICOORD &topright)
Definition: edgloop.cpp:117
#define MINEDGELENGTH
Definition: edgloop.cpp:27
ScrollView::Color check_path_legal(CRACKEDGE *start)
Definition: edgloop.cpp:65
void complete_edge(CRACKEDGE *start, C_OUTLINE_IT *outline_it)
Definition: edgloop.cpp:35
static const int kMaxOutlineLength
Definition: coutln.h:273
CRACKEDGE * prev
Definition: crakedge.h:34
CRACKEDGE * next
Definition: crakedge.h:35
int8_t stepdir
Definition: crakedge.h:33
ICOORD pos
Definition: crakedge.h:30
integer coordinate
Definition: points.h:32
void set_x(int16_t xin)
rewrite function
Definition: points.h:61
int16_t y() const
access_function
Definition: points.h:56
void set_y(int16_t yin)
rewrite function
Definition: points.h:65
int16_t x() const
access function
Definition: points.h:52
void error(const char *caller, TessErrorLogCode action, const char *format,...) const
Definition: errcode.cpp:35