Tesseract 3.02

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
edgloop.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 * File: edgloop.c (Formerly edgeloop.c)
3 * Description: Functions to clean up an outline before approximation.
4 * Author: Ray Smith
5 * Created: Tue Mar 26 16:56:25 GMT 1991
6 *
7 * (C) Copyright 1991, Hewlett-Packard Ltd.
8 ** Licensed under the Apache License, Version 2.0 (the "License");
9 ** you may not use this file except in compliance with the License.
10 ** You may obtain a copy of the License at
11 ** http://www.apache.org/licenses/LICENSE-2.0
12 ** Unless required by applicable law or agreed to in writing, software
13 ** distributed under the License is distributed on an "AS IS" BASIS,
14 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 ** See the License for the specific language governing permissions and
16 ** limitations under the License.
17 *
18 **********************************************************************/
19
20 #include "mfcpch.h"
21 #include "scanedg.h"
22 #include "drawedg.h"
23 #include "edgloop.h"
24
25 // Include automatically generated configuration file if running autoconf.
26 #ifdef HAVE_CONFIG_H
27 #include "config_auto.h"
28 #endif
29
30 #define MINEDGELENGTH 8 // min decent length
31
32 INT_VAR(edges_maxedgelength, 16000, "Max steps in any outline");
33
34 /**********************************************************************
35 * complete_edge
36 *
37 * Complete the edge by cleaning it up.
38 **********************************************************************/
39
40 void complete_edge(CRACKEDGE *start, //start of loop
41 C_OUTLINE_IT* outline_it) {
42 ScrollView::Color colour; //colour to draw in
43 inT16 looplength; //steps in loop
44 ICOORD botleft; //bounding box
45 ICOORD topright;
46 C_OUTLINE *outline; //new outline
47
48 //check length etc.
49 colour = check_path_legal (start);
50
51 if (colour == ScrollView::RED || colour == ScrollView::BLUE) {
52 looplength = loop_bounding_box (start, botleft, topright);
53 outline = new C_OUTLINE (start, botleft, topright, looplength);
54 //add to list
55 outline_it->add_after_then_move (outline);
56 }
57 }
58
59
60 /**********************************************************************
61 * check_path_legal
62 *
63 * Check that the outline is legal for length and for chaincode sum.
64 * The return value is RED for a normal black-inside outline,
65 * BLUE for a white-inside outline, MAGENTA if it is too short,
66 * YELLOW if it is too long, and GREEN if it is illegal.
67 * These colours are used to draw the raw outline.
68 **********************************************************************/
69
70 ScrollView::Color check_path_legal( //certify outline
71 CRACKEDGE *start //start of loop
72 ) {
73 int lastchain; //last chain code
74 int chaindiff; //chain code diff
75 inT32 length; //length of loop
76 inT32 chainsum; //sum of chain diffs
77 CRACKEDGE *edgept; //current point
78 const ERRCODE ED_ILLEGAL_SUM = "Illegal sum of chain codes";
79
80 length = 0;
81 chainsum = 0; //sum of chain codes
82 edgept = start;
83 lastchain = edgept->prev->stepdir; //previous chain code
84 do {
85 length++;
86 if (edgept->stepdir != lastchain) {
87 //chain code difference
88 chaindiff = edgept->stepdir - lastchain;
89 if (chaindiff > 2)
90 chaindiff -= 4;
91 else if (chaindiff < -2)
92 chaindiff += 4;
93 chainsum += chaindiff; //sum differences
94 lastchain = edgept->stepdir;
95 }
96 edgept = edgept->next;
97 }
98 while (edgept != start && length < edges_maxedgelength);
99
100 if ((chainsum != 4 && chainsum != -4)
101 || edgept != start || length < MINEDGELENGTH) {
102 if (edgept != start) {
103 return ScrollView::YELLOW;
104 } else if (length < MINEDGELENGTH) {
105 return ScrollView::MAGENTA;
106 } else {
107 ED_ILLEGAL_SUM.error ("check_path_legal", TESSLOG, "chainsum=%d",
108 chainsum);
109 return ScrollView::GREEN;
110 }
111 }
112 //colour on inside
113 return chainsum < 0 ? ScrollView::BLUE : ScrollView::RED;
114 }
115
116 /**********************************************************************
117 * loop_bounding_box
118 *
119 * Find the bounding box of the edge loop.
120 **********************************************************************/
121
122 inT16 loop_bounding_box( //get bounding box
123 CRACKEDGE *&start, //edge loop
124 ICOORD &botleft, //bounding box
125 ICOORD &topright) {
126 inT16 length; //length of loop
127 inT16 leftmost; //on top row
128 CRACKEDGE *edgept; //current point
129 CRACKEDGE *realstart; //topleft start
130
131 edgept = start;
132 realstart = start;
133 botleft = topright = ICOORD (edgept->pos.x (), edgept->pos.y ());
134 leftmost = edgept->pos.x ();
135 length = 0; //coutn length
136 do {
137 edgept = edgept->next;
138 if (edgept->pos.x () < botleft.x ())
139 //get bounding box
140 botleft.set_x (edgept->pos.x ());
141 else if (edgept->pos.x () > topright.x ())
142 topright.set_x (edgept->pos.x ());
143 if (edgept->pos.y () < botleft.y ())
144 //get bounding box
145 botleft.set_y (edgept->pos.y ());
146 else if (edgept->pos.y () > topright.y ()) {
147 realstart = edgept;
148 leftmost = edgept->pos.x ();
149 topright.set_y (edgept->pos.y ());
150 }
151 else if (edgept->pos.y () == topright.y ()
152 && edgept->pos.x () < leftmost) {
153 //leftmost on line
154 leftmost = edgept->pos.x ();
155 realstart = edgept;
156 }
157 length++; //count elements
158 }
159 while (edgept != start);
160 start = realstart; //shift it to topleft
161 return length;
162 }