tesseract  4.0.0-1-g2a2b
mfoutline.cpp
Go to the documentation of this file.
1 /******************************************************************************
2  ** Filename: mfoutline.c
3  ** Purpose: Interface to outline struct used for extracting features
4  ** Author: Dan Johnson
5  ** History: Thu May 17 08:14:18 1990, DSJ, Created.
6  **
7  ** (c) Copyright Hewlett-Packard Company, 1988.
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  Include Files and Type Defines
20 ----------------------------------------------------------------------------*/
21 #include "clusttool.h" //If remove you get cought in a loop somewhere
22 #include "emalloc.h"
23 #include "mfoutline.h"
24 #include "blobs.h"
25 #include "mfx.h"
26 #include "params.h"
27 #include "classify.h"
28 
29 #include <cmath>
30 #include <cstdio>
31 
32 /*----------------------------------------------------------------------------
33  Public Code
34 ----------------------------------------------------------------------------*/
35 
36 /*---------------------------------------------------------------------------*/
40  LIST outlines = NIL_LIST;
41  return (blob == nullptr)
42  ? NIL_LIST
43  : ConvertOutlines(blob->outlines, outlines, outer);
44 }
45 
46 
47 /*---------------------------------------------------------------------------*/
50  MFEDGEPT *NewPoint;
51  MFOUTLINE MFOutline = NIL_LIST;
52  EDGEPT *EdgePoint;
53  EDGEPT *StartPoint;
54  EDGEPT *NextPoint;
55 
56  if (outline == nullptr || outline->loop == nullptr)
57  return MFOutline;
58 
59  StartPoint = outline->loop;
60  EdgePoint = StartPoint;
61  do {
62  NextPoint = EdgePoint->next;
63 
64  /* filter out duplicate points */
65  if (EdgePoint->pos.x != NextPoint->pos.x ||
66  EdgePoint->pos.y != NextPoint->pos.y) {
67  NewPoint = NewEdgePoint();
68  ClearMark(NewPoint);
69  NewPoint->Hidden = EdgePoint->IsHidden();
70  NewPoint->Point.x = EdgePoint->pos.x;
71  NewPoint->Point.y = EdgePoint->pos.y;
72  MFOutline = push(MFOutline, NewPoint);
73  }
74  EdgePoint = NextPoint;
75  } while (EdgePoint != StartPoint);
76 
77  if (MFOutline != nullptr)
78  MakeOutlineCircular(MFOutline);
79  return MFOutline;
80 }
81 
82 
83 /*---------------------------------------------------------------------------*/
92  LIST mf_outlines,
93  OUTLINETYPE outline_type) {
94  MFOUTLINE mf_outline;
95 
96  while (outline != nullptr) {
97  mf_outline = ConvertOutline(outline);
98  if (mf_outline != nullptr)
99  mf_outlines = push(mf_outlines, mf_outline);
100  outline = outline->next;
101  }
102  return mf_outlines;
103 }
104 
105 /*---------------------------------------------------------------------------*/
119  float MinSlope,
120  float MaxSlope) {
121  MFEDGEPT *Current;
122  MFEDGEPT *Last;
123  MFOUTLINE EdgePoint;
124 
125  if (DegenerateOutline (Outline))
126  return;
127 
128  Last = PointAt (Outline);
129  Outline = NextPointAfter (Outline);
130  EdgePoint = Outline;
131  do {
132  Current = PointAt (EdgePoint);
133  ComputeDirection(Last, Current, MinSlope, MaxSlope);
134 
135  Last = Current;
136  EdgePoint = NextPointAfter (EdgePoint);
137  }
138  while (EdgePoint != Outline);
139 
140 } /* FindDirectionChanges */
141 
142 
143 /*---------------------------------------------------------------------------*/
150 void FreeMFOutline(void *arg) { //MFOUTLINE Outline)
151  MFOUTLINE Start;
152  MFOUTLINE Outline = (MFOUTLINE) arg;
153 
154  /* break the circular outline so we can use std. techniques to deallocate */
155  Start = list_rest (Outline);
156  set_rest(Outline, NIL_LIST);
157  while (Start != nullptr) {
158  free(first_node(Start));
159  Start = pop (Start);
160  }
161 
162 } /* FreeMFOutline */
163 
164 
165 /*---------------------------------------------------------------------------*/
172 void FreeOutlines(LIST Outlines) {
173  destroy_nodes(Outlines, FreeMFOutline);
174 } /* FreeOutlines */
175 
176 
177 /*---------------------------------------------------------------------------*/
191  MFOUTLINE Current;
192  MFOUTLINE Last;
193  MFOUTLINE First;
194 
195  if (DegenerateOutline (Outline))
196  return;
197 
198  First = NextDirectionChange (Outline);
199  Last = First;
200  do {
201  Current = NextDirectionChange (Last);
202  MarkPoint (PointAt (Current));
203  Last = Current;
204  }
205  while (Last != First);
206 
207 } /* MarkDirectionChanges */
208 
209 
210 /*---------------------------------------------------------------------------*/
213  return reinterpret_cast<MFEDGEPT *>(malloc(sizeof(MFEDGEPT)));
214 }
215 
216 /*---------------------------------------------------------------------------*/
228  EdgePoint = NextPointAfter(EdgePoint);
229  while (!PointAt(EdgePoint)->ExtremityMark)
230  EdgePoint = NextPointAfter(EdgePoint);
231 
232  return (EdgePoint);
233 
234 } /* NextExtremity */
235 
236 
237 /*---------------------------------------------------------------------------*/
252  float XOrigin) {
253  if (Outline == NIL_LIST)
254  return;
255 
256  MFOUTLINE EdgePoint = Outline;
257  do {
258  MFEDGEPT *Current = PointAt(EdgePoint);
259  Current->Point.y = MF_SCALE_FACTOR *
260  (Current->Point.y - kBlnBaselineOffset);
261  Current->Point.x = MF_SCALE_FACTOR * (Current->Point.x - XOrigin);
262  EdgePoint = NextPointAfter(EdgePoint);
263  } while (EdgePoint != Outline);
264 } /* NormalizeOutline */
265 
266 
267 /*---------------------------------------------------------------------------*/
268 namespace tesseract {
286  float *XScale,
287  float *YScale) {
288  MFOUTLINE Outline;
289 
290  switch (classify_norm_method) {
291  case character:
292  ASSERT_HOST(!"How did NormalizeOutlines get called in character mode?");
293  break;
294 
295  case baseline:
296  iterate(Outlines) {
297  Outline = (MFOUTLINE) first_node(Outlines);
298  NormalizeOutline(Outline, 0.0);
299  }
300  *XScale = *YScale = MF_SCALE_FACTOR;
301  break;
302  }
303 } /* NormalizeOutlines */
304 } // namespace tesseract
305 
306 /*----------------------------------------------------------------------------
307  Private Code
308 ----------------------------------------------------------------------------*/
320 void ChangeDirection(MFOUTLINE Start, MFOUTLINE End, DIRECTION Direction) {
321  MFOUTLINE Current;
322 
323  for (Current = Start; Current != End; Current = NextPointAfter (Current))
324  PointAt (Current)->Direction = Direction;
325 
326  PointAt (End)->PreviousDirection = Direction;
327 
328 } /* ChangeDirection */
329 
339 void CharNormalizeOutline(MFOUTLINE Outline, const DENORM& cn_denorm) {
340  MFOUTLINE First, Current;
341  MFEDGEPT *CurrentPoint;
342 
343  if (Outline == NIL_LIST)
344  return;
345 
346  First = Outline;
347  Current = First;
348  do {
349  CurrentPoint = PointAt(Current);
350  FCOORD pos(CurrentPoint->Point.x, CurrentPoint->Point.y);
351  cn_denorm.LocalNormTransform(pos, &pos);
352  CurrentPoint->Point.x = (pos.x() - UINT8_MAX / 2) * MF_SCALE_FACTOR;
353  CurrentPoint->Point.y = (pos.y() - UINT8_MAX / 2) * MF_SCALE_FACTOR;
354 
355  Current = NextPointAfter(Current);
356  }
357  while (Current != First);
358 
359 } /* CharNormalizeOutline */
360 
379  MFEDGEPT *Finish,
380  float MinSlope,
381  float MaxSlope) {
382  FVECTOR Delta;
383 
384  Delta.x = Finish->Point.x - Start->Point.x;
385  Delta.y = Finish->Point.y - Start->Point.y;
386  if (Delta.x == 0) {
387  if (Delta.y < 0) {
388  Start->Slope = -FLT_MAX;
389  Start->Direction = south;
390  } else {
391  Start->Slope = FLT_MAX;
392  Start->Direction = north;
393  }
394  } else {
395  Start->Slope = Delta.y / Delta.x;
396  if (Delta.x > 0) {
397  if (Delta.y > 0) {
398  if (Start->Slope > MinSlope) {
399  if (Start->Slope < MaxSlope) {
400  Start->Direction = northeast;
401  } else {
402  Start->Direction = north;
403  }
404  } else {
405  Start->Direction = east;
406  }
407  }
408  else if (Start->Slope < -MinSlope) {
409  if (Start->Slope > -MaxSlope) {
410  Start->Direction = southeast;
411  } else {
412  Start->Direction = south;
413  }
414  } else {
415  Start->Direction = east;
416  }
417  } else if (Delta.y > 0) {
418  if (Start->Slope < -MinSlope) {
419  if (Start->Slope > -MaxSlope) {
420  Start->Direction = northwest;
421  } else {
422  Start->Direction = north;
423  }
424  } else {
425  Start->Direction = west;
426  }
427  } else if (Start->Slope > MinSlope) {
428  if (Start->Slope < MaxSlope) {
429  Start->Direction = southwest;
430  } else {
431  Start->Direction = south;
432  }
433  } else {
434  Start->Direction = west;
435  }
436  }
437  Finish->PreviousDirection = Start->Direction;
438 }
439 
450  DIRECTION InitialDirection;
451 
452  InitialDirection = PointAt (EdgePoint)->Direction;
453 
454  MFOUTLINE next_pt = nullptr;
455  do {
456  EdgePoint = NextPointAfter(EdgePoint);
457  next_pt = NextPointAfter(EdgePoint);
458  } while (PointAt(EdgePoint)->Direction == InitialDirection &&
459  !PointAt(EdgePoint)->Hidden &&
460  next_pt != nullptr && !PointAt(next_pt)->Hidden);
461 
462  return (EdgePoint);
463 }
MFOUTLINE NextExtremity(MFOUTLINE EdgePoint)
Definition: mfoutline.cpp:227
TESSLINE * next
Definition: blobs.h:265
void MarkDirectionChanges(MFOUTLINE Outline)
Definition: mfoutline.cpp:190
void ChangeDirection(MFOUTLINE Start, MFOUTLINE End, DIRECTION Direction)
Definition: mfoutline.cpp:320
void NormalizeOutline(MFOUTLINE Outline, float XOrigin)
Definition: mfoutline.cpp:251
TPOINT pos
Definition: blobs.h:170
void NormalizeOutlines(LIST Outlines, float *XScale, float *YScale)
Definition: mfoutline.cpp:285
#define MF_SCALE_FACTOR
Definition: mfoutline.h:64
void FreeOutlines(LIST Outlines)
Definition: mfoutline.cpp:172
#define DegenerateOutline(O)
Definition: mfoutline.h:67
#define set_rest(l, cell)
Definition: oldlist.h:224
void FindDirectionChanges(MFOUTLINE Outline, float MinSlope, float MaxSlope)
Definition: mfoutline.cpp:118
MFOUTLINE ConvertOutline(TESSLINE *outline)
Definition: mfoutline.cpp:49
LIST push(LIST list, void *element)
Definition: oldlist.cpp:283
LIST ConvertOutlines(TESSLINE *outline, LIST mf_outlines, OUTLINETYPE outline_type)
Definition: mfoutline.cpp:91
#define MarkPoint(P)
Definition: mfoutline.h:74
const int kBlnBaselineOffset
Definition: normalis.h:25
bool IsHidden() const
Definition: blobs.h:160
Definition: fpoint.h:30
LIST pop(LIST list)
Definition: oldlist.cpp:266
#define PointAt(O)
Definition: mfoutline.h:68
#define list_rest(l)
Definition: oldlist.h:140
MFOUTLINE NextDirectionChange(MFOUTLINE EdgePoint)
Definition: mfoutline.cpp:449
LIST ConvertBlob(TBLOB *blob)
Definition: mfoutline.cpp:39
void LocalNormTransform(const TPOINT &pt, TPOINT *transformed) const
Definition: normalis.cpp:306
void destroy_nodes(LIST list, void_dest destructor)
Definition: oldlist.cpp:186
EDGEPT * loop
Definition: blobs.h:264
float y
Definition: fpoint.h:31
void ComputeDirection(MFEDGEPT *Start, MFEDGEPT *Finish, float MinSlope, float MaxSlope)
Definition: mfoutline.cpp:378
Definition: blobs.h:83
#define first_node(l)
Definition: oldlist.h:141
int16_t x
Definition: blobs.h:78
#define NIL_LIST
Definition: oldlist.h:127
void CharNormalizeOutline(MFOUTLINE Outline, const DENORM &cn_denorm)
Definition: mfoutline.cpp:339
BOOL8 Hidden
Definition: mfoutline.h:44
Definition: mfoutline.h:37
#define NextPointAfter(E)
Definition: mfoutline.h:69
float Slope
Definition: mfoutline.h:42
FPOINT Point
Definition: mfoutline.h:41
#define iterate(l)
Definition: oldlist.h:161
Definition: points.h:189
DIRECTION
Definition: mfoutline.h:36
#define MakeOutlineCircular(O)
Definition: mfoutline.h:70
Definition: mfoutline.h:37
float x() const
Definition: points.h:208
DIRECTION PreviousDirection
Definition: mfoutline.h:47
Definition: blobs.h:268
void FreeMFOutline(void *arg)
Definition: mfoutline.cpp:150
DIRECTION Direction
Definition: mfoutline.h:46
MFEDGEPT * NewEdgePoint()
Definition: mfoutline.cpp:212
int16_t y
Definition: blobs.h:79
TESSLINE * outlines
Definition: blobs.h:384
EDGEPT * next
Definition: blobs.h:176
float x
Definition: fpoint.h:31
OUTLINETYPE
Definition: mfoutline.h:50
LIST MFOUTLINE
Definition: mfoutline.h:34
#define ClearMark(P)
Definition: mfoutline.h:73
float y() const
Definition: points.h:211
#define ASSERT_HOST(x)
Definition: errcode.h:84