tesseract  4.1.0
chop.cpp
Go to the documentation of this file.
1 /* -*-C-*-
2  ******************************************************************************
3  *
4  * File: chop.cpp (Formerly chop.c)
5  * Author: Mark Seaman, OCR Technology
6  *
7  * (c) Copyright 1987, Hewlett-Packard Company.
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 /*----------------------------------------------------------------------
21  I n c l u d e s
22 ----------------------------------------------------------------------*/
23 
24 #define _USE_MATH_DEFINES // for M_PI
25 #include <cmath> // for M_PI
26 #include "chop.h"
27 #include "outlines.h"
28 #include "callcpp.h"
29 #include "plotedges.h"
30 #include "wordrec.h"
31 
32 // Include automatically generated configuration file if running autoconf.
33 #ifdef HAVE_CONFIG_H
34 #include "config_auto.h"
35 #endif
36 
37 namespace tesseract {
38 /*----------------------------------------------------------------------
39  F u n c t i o n s
40 ----------------------------------------------------------------------*/
48  return static_cast<PRIORITY>(angle_change(point->prev, point, point->next));
49 }
50 
51 
57 void Wordrec::add_point_to_list(PointHeap* point_heap, EDGEPT *point) {
58  if (point_heap->size() < MAX_NUM_POINTS - 2) {
59  PointPair pair(point_priority(point), point);
60  point_heap->Push(&pair);
61  }
62 
63 #ifndef GRAPHICS_DISABLED
64  if (chop_debug > 2)
65  mark_outline(point);
66 #endif
67 }
68 
69 // Returns true if the edgept supplied as input is an inside angle. This
70 // is determined by the angular change of the vectors from point to point.
72  return angle_change(pt->prev, pt, pt->next) < chop_inside_angle;
73 }
74 
81 int Wordrec::angle_change(EDGEPT *point1, EDGEPT *point2, EDGEPT *point3) {
82  VECTOR vector1;
83  VECTOR vector2;
84 
85  int angle;
86 
87  /* Compute angle */
88  vector1.x = point2->pos.x - point1->pos.x;
89  vector1.y = point2->pos.y - point1->pos.y;
90  vector2.x = point3->pos.x - point2->pos.x;
91  vector2.y = point3->pos.y - point2->pos.y;
92  /* Use cross product */
93  float length = std::sqrt(static_cast<float>(LENGTH(vector1)) * LENGTH(vector2));
94  if (static_cast<int>(length) == 0)
95  return (0);
96  angle = static_cast<int>(floor(asin(CROSS (vector1, vector2) /
97  length) / M_PI * 180.0 + 0.5));
98 
99  /* Use dot product */
100  if (SCALAR (vector1, vector2) < 0)
101  angle = 180 - angle;
102  /* Adjust angle */
103  if (angle > 180)
104  angle -= 360;
105  if (angle <= -180)
106  angle += 360;
107  return (angle);
108 }
109 
117  EDGEPT *vertical_point,
118  int *best_dist) {
119  EDGEPT *best_point = nullptr;
120  int this_distance;
121  int found_better;
122 
123  do {
124  found_better = false;
125 
126  this_distance = edgept_dist (critical_point, vertical_point);
127  if (this_distance <= *best_dist) {
128 
129  if (!(same_point (critical_point->pos, vertical_point->pos) ||
130  same_point (critical_point->pos, vertical_point->next->pos) ||
131  (best_point && same_point (best_point->pos, vertical_point->pos)) ||
132  is_exterior_point (critical_point, vertical_point))) {
133  *best_dist = this_distance;
134  best_point = vertical_point;
136  found_better = true;
137  }
138  }
139  vertical_point = vertical_point->next;
140  }
141  while (found_better == true);
142 
143  return (best_point);
144 }
145 
146 
155  EDGEPT *this_point;
156  EDGEPT *local_min = nullptr;
157  EDGEPT *local_max = nullptr;
158 
159  this_point = outline->loop;
160  local_min = this_point;
161  local_max = this_point;
162  do {
163  if (this_point->vec.y < 0) {
164  /* Look for minima */
165  if (local_max != nullptr)
166  new_max_point(local_max, points);
167  else if (is_inside_angle (this_point))
168  add_point_to_list(points, this_point);
169  local_max = nullptr;
170  local_min = this_point->next;
171  }
172  else if (this_point->vec.y > 0) {
173  /* Look for maxima */
174  if (local_min != nullptr)
175  new_min_point(local_min, points);
176  else if (is_inside_angle (this_point))
177  add_point_to_list(points, this_point);
178  local_min = nullptr;
179  local_max = this_point->next;
180  }
181  else {
182  /* Flat area */
183  if (local_max != nullptr) {
184  if (local_max->prev->vec.y != 0) {
185  new_max_point(local_max, points);
186  }
187  local_max = this_point->next;
188  local_min = nullptr;
189  }
190  else {
191  if (local_min->prev->vec.y != 0) {
192  new_min_point(local_min, points);
193  }
194  local_min = this_point->next;
195  local_max = nullptr;
196  }
197  }
198 
199  /* Next point */
200  this_point = this_point->next;
201  }
202  while (this_point != outline->loop);
203 }
204 
205 
213 void Wordrec::new_min_point(EDGEPT *local_min, PointHeap* points) {
214  int16_t dir;
215 
216  dir = direction (local_min);
217 
218  if (dir < 0) {
219  add_point_to_list(points, local_min);
220  return;
221  }
222 
223  if (dir == 0 && point_priority (local_min) < 0) {
224  add_point_to_list(points, local_min);
225  return;
226  }
227 }
228 
229 
237 void Wordrec::new_max_point(EDGEPT *local_max, PointHeap* points) {
238  int16_t dir;
239 
240  dir = direction (local_max);
241 
242  if (dir > 0) {
243  add_point_to_list(points, local_max);
244  return;
245  }
246 
247  if (dir == 0 && point_priority (local_max) < 0) {
248  add_point_to_list(points, local_max);
249  return;
250  }
251 }
252 
253 
266 void Wordrec::vertical_projection_point(EDGEPT *split_point, EDGEPT *target_point,
267  EDGEPT** best_point,
268  EDGEPT_CLIST *new_points) {
269  EDGEPT *p; /* Iterator */
270  EDGEPT *this_edgept; /* Iterator */
271  EDGEPT_C_IT new_point_it(new_points);
272  int x = split_point->pos.x; /* X value of vertical */
273  int best_dist = LARGE_DISTANCE;/* Best point found */
274 
275  if (*best_point != nullptr)
276  best_dist = edgept_dist(split_point, *best_point);
277 
278  p = target_point;
279  /* Look at each edge point */
280  do {
281  if (((p->pos.x <= x && x <= p->next->pos.x) ||
282  (p->next->pos.x <= x && x <= p->pos.x)) &&
283  !same_point(split_point->pos, p->pos) &&
284  !same_point(split_point->pos, p->next->pos) &&
285  !p->IsChopPt() &&
286  (*best_point == nullptr || !same_point((*best_point)->pos, p->pos))) {
287 
288  if (near_point(split_point, p, p->next, &this_edgept)) {
289  new_point_it.add_before_then_move(this_edgept);
290  }
291 
292  if (*best_point == nullptr)
293  best_dist = edgept_dist (split_point, this_edgept);
294 
295  this_edgept =
296  pick_close_point(split_point, this_edgept, &best_dist);
297  if (this_edgept)
298  *best_point = this_edgept;
299  }
300 
301  p = p->next;
302  }
303  while (p != target_point);
304 }
305 
306 } // namespace tesseract
PRIORITY point_priority(EDGEPT *point)
Definition: chop.cpp:47
int angle_change(EDGEPT *point1, EDGEPT *point2, EDGEPT *point3)
Definition: chop.cpp:81
void Push(Pair *entry)
Definition: genericheap.h:95
int16_t x
Definition: blobs.h:73
void vertical_projection_point(EDGEPT *split_point, EDGEPT *target_point, EDGEPT **best_point, EDGEPT_CLIST *new_points)
Definition: chop.cpp:266
EDGEPT * next
Definition: blobs.h:171
float PRIORITY
Definition: seam.h:36
#define LENGTH(a)
Definition: vecfuncs.h:65
void prioritize_points(TESSLINE *outline, PointHeap *points)
Definition: chop.cpp:154
EDGEPT * loop
Definition: blobs.h:259
TPOINT pos
Definition: blobs.h:165
#define MAX_NUM_POINTS
Definition: chop.h:33
void add_point_to_list(PointHeap *point_heap, EDGEPT *point)
Definition: chop.cpp:57
#define same_point(p1, p2)
Definition: outlines.h:45
#define is_exterior_point(edge, point)
Definition: outlines.h:93
#define LARGE_DISTANCE
Definition: outlines.h:32
bool near_point(EDGEPT *point, EDGEPT *line_pt_0, EDGEPT *line_pt_1, EDGEPT **near_pt)
Definition: outlines.cpp:40
int16_t y
Definition: blobs.h:74
Definition: blobs.h:52
Definition: blobs.h:78
EDGEPT * pick_close_point(EDGEPT *critical_point, EDGEPT *vertical_point, int *best_dist)
Definition: chop.cpp:116
int direction(EDGEPT *point)
Definition: vecfuncs.cpp:38
void new_min_point(EDGEPT *local_min, PointHeap *points)
Definition: chop.cpp:213
bool is_inside_angle(EDGEPT *pt)
Definition: chop.cpp:71
bool chop_vertical_creep
Definition: wordrec.h:210
#define SCALAR(a, b)
Definition: vecfuncs.h:56
void new_max_point(EDGEPT *local_max, PointHeap *points)
Definition: chop.cpp:237
#define edgept_dist(p1, p2)
Definition: outlines.h:83
void mark_outline(EDGEPT *edgept)
Definition: plotedges.cpp:87
#define CROSS(a, b)
Definition: vecfuncs.h:47
VECTOR vec
Definition: blobs.h:166
bool IsChopPt() const
Definition: blobs.h:161
EDGEPT * prev
Definition: blobs.h:172