tesseract  4.0.0-1-g2a2b
mfoutline.cpp File Reference
#include "clusttool.h"
#include "emalloc.h"
#include "mfoutline.h"
#include "blobs.h"
#include "mfx.h"
#include "params.h"
#include "classify.h"
#include <cmath>
#include <cstdio>

Go to the source code of this file.

Namespaces

 tesseract
 

Functions

LIST ConvertBlob (TBLOB *blob)
 
MFOUTLINE ConvertOutline (TESSLINE *outline)
 
LIST ConvertOutlines (TESSLINE *outline, LIST mf_outlines, OUTLINETYPE outline_type)
 
void FindDirectionChanges (MFOUTLINE Outline, float MinSlope, float MaxSlope)
 
void FreeMFOutline (void *arg)
 
void FreeOutlines (LIST Outlines)
 
void MarkDirectionChanges (MFOUTLINE Outline)
 
MFEDGEPTNewEdgePoint ()
 
MFOUTLINE NextExtremity (MFOUTLINE EdgePoint)
 
void NormalizeOutline (MFOUTLINE Outline, float XOrigin)
 
void ChangeDirection (MFOUTLINE Start, MFOUTLINE End, DIRECTION Direction)
 
void CharNormalizeOutline (MFOUTLINE Outline, const DENORM &cn_denorm)
 
void ComputeDirection (MFEDGEPT *Start, MFEDGEPT *Finish, float MinSlope, float MaxSlope)
 
MFOUTLINE NextDirectionChange (MFOUTLINE EdgePoint)
 

Function Documentation

◆ ChangeDirection()

void ChangeDirection ( MFOUTLINE  Start,
MFOUTLINE  End,
DIRECTION  Direction 
)

Change the direction of every vector in the specified outline segment to Direction. The segment to be changed starts at Start and ends at End. Note that the previous direction of End must also be changed to reflect the change in direction of the point before it.

Parameters
Start,Enddefines segment of outline to be modified
Directionnew direction to assign to segment
Returns
none
Note
Globals: none

Definition at line 320 of file mfoutline.cpp.

320  {
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 */
#define PointAt(O)
Definition: mfoutline.h:68
#define NextPointAfter(E)
Definition: mfoutline.h:69

◆ CharNormalizeOutline()

void CharNormalizeOutline ( MFOUTLINE  Outline,
const DENORM cn_denorm 
)

This routine normalizes each point in Outline by translating it to the specified center and scaling it anisotropically according to the given scale factors.

Parameters
Outlineoutline to be character normalized
cn_denorm
Returns
none
Note
Globals: none

Definition at line 339 of file mfoutline.cpp.

339  {
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 */
#define MF_SCALE_FACTOR
Definition: mfoutline.h:64
#define PointAt(O)
Definition: mfoutline.h:68
void LocalNormTransform(const TPOINT &pt, TPOINT *transformed) const
Definition: normalis.cpp:306
float y
Definition: fpoint.h:31
#define NIL_LIST
Definition: oldlist.h:127
#define NextPointAfter(E)
Definition: mfoutline.h:69
FPOINT Point
Definition: mfoutline.h:41
Definition: points.h:189
float x
Definition: fpoint.h:31

◆ ComputeDirection()

void ComputeDirection ( MFEDGEPT Start,
MFEDGEPT Finish,
float  MinSlope,
float  MaxSlope 
)

This routine computes the slope from Start to Finish and and then computes the approximate direction of the line segment from Start to Finish. The direction is quantized into 8 buckets: N, S, E, W, NE, NW, SE, SW Both the slope and the direction are then stored into the appropriate fields of the Start edge point. The direction is also stored into the PreviousDirection field of the Finish edge point.

Parameters
Startstarting point to compute direction from
Finishfinishing point to compute direction to
MinSlopeslope below which lines are horizontal
MaxSlopeslope above which lines are vertical
Returns
none
Note
Globals: none

Definition at line 378 of file mfoutline.cpp.

381  {
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 }
Definition: fpoint.h:30
float y
Definition: fpoint.h:31
Definition: mfoutline.h:37
float Slope
Definition: mfoutline.h:42
FPOINT Point
Definition: mfoutline.h:41
Definition: mfoutline.h:37
DIRECTION PreviousDirection
Definition: mfoutline.h:47
DIRECTION Direction
Definition: mfoutline.h:46
float x
Definition: fpoint.h:31

◆ ConvertBlob()

LIST ConvertBlob ( TBLOB blob)

Convert a blob into a list of MFOUTLINEs (float-based microfeature format).

Definition at line 39 of file mfoutline.cpp.

39  {
40  LIST outlines = NIL_LIST;
41  return (blob == nullptr)
42  ? NIL_LIST
43  : ConvertOutlines(blob->outlines, outlines, outer);
44 }
LIST ConvertOutlines(TESSLINE *outline, LIST mf_outlines, OUTLINETYPE outline_type)
Definition: mfoutline.cpp:91
#define NIL_LIST
Definition: oldlist.h:127
TESSLINE * outlines
Definition: blobs.h:384

◆ ConvertOutline()

MFOUTLINE ConvertOutline ( TESSLINE outline)

Convert a TESSLINE into the float-based MFOUTLINE micro-feature format.

Definition at line 49 of file mfoutline.cpp.

49  {
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 }
TPOINT pos
Definition: blobs.h:170
LIST push(LIST list, void *element)
Definition: oldlist.cpp:283
bool IsHidden() const
Definition: blobs.h:160
EDGEPT * loop
Definition: blobs.h:264
float y
Definition: fpoint.h:31
Definition: blobs.h:83
int16_t x
Definition: blobs.h:78
#define NIL_LIST
Definition: oldlist.h:127
BOOL8 Hidden
Definition: mfoutline.h:44
FPOINT Point
Definition: mfoutline.h:41
#define MakeOutlineCircular(O)
Definition: mfoutline.h:70
MFEDGEPT * NewEdgePoint()
Definition: mfoutline.cpp:212
int16_t y
Definition: blobs.h:79
EDGEPT * next
Definition: blobs.h:176
float x
Definition: fpoint.h:31
#define ClearMark(P)
Definition: mfoutline.h:73

◆ ConvertOutlines()

LIST ConvertOutlines ( TESSLINE outline,
LIST  mf_outlines,
OUTLINETYPE  outline_type 
)

Convert a tree of outlines to a list of MFOUTLINEs (lists of MFEDGEPTs).

Parameters
outlinefirst outline to be converted
mf_outlineslist to add converted outlines to
outline_typeare the outlines outer or holes?

Definition at line 91 of file mfoutline.cpp.

93  {
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 }
TESSLINE * next
Definition: blobs.h:265
MFOUTLINE ConvertOutline(TESSLINE *outline)
Definition: mfoutline.cpp:49
LIST push(LIST list, void *element)
Definition: oldlist.cpp:283

◆ FindDirectionChanges()

void FindDirectionChanges ( MFOUTLINE  Outline,
float  MinSlope,
float  MaxSlope 
)

This routine searches through the specified outline, computes a slope for each vector in the outline, and marks each vector as having one of the following directions: N, S, E, W, NE, NW, SE, SW This information is then stored in the outline and the outline is returned.

Parameters
Outlinemicro-feature outline to analyze
MinSlopecontrols "snapping" of segments to horizontal
MaxSlopecontrols "snapping" of segments to vertical
Returns
none

Definition at line 118 of file mfoutline.cpp.

120  {
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 */
#define DegenerateOutline(O)
Definition: mfoutline.h:67
#define PointAt(O)
Definition: mfoutline.h:68
void ComputeDirection(MFEDGEPT *Start, MFEDGEPT *Finish, float MinSlope, float MaxSlope)
Definition: mfoutline.cpp:378
#define NextPointAfter(E)
Definition: mfoutline.h:69

◆ FreeMFOutline()

void FreeMFOutline ( void *  arg)

This routine deallocates all of the memory consumed by a micro-feature outline.

Parameters
argmicro-feature outline to be freed
Returns
none

Definition at line 150 of file mfoutline.cpp.

150  { //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 */
#define set_rest(l, cell)
Definition: oldlist.h:224
LIST pop(LIST list)
Definition: oldlist.cpp:266
#define list_rest(l)
Definition: oldlist.h:140
#define first_node(l)
Definition: oldlist.h:141
#define NIL_LIST
Definition: oldlist.h:127
LIST MFOUTLINE
Definition: mfoutline.h:34

◆ FreeOutlines()

void FreeOutlines ( LIST  Outlines)

Release all memory consumed by the specified list of outlines.

Parameters
Outlineslist of mf-outlines to be freed
Returns
none

Definition at line 172 of file mfoutline.cpp.

172  {
173  destroy_nodes(Outlines, FreeMFOutline);
174 } /* FreeOutlines */
void destroy_nodes(LIST list, void_dest destructor)
Definition: oldlist.cpp:186
void FreeMFOutline(void *arg)
Definition: mfoutline.cpp:150

◆ MarkDirectionChanges()

void MarkDirectionChanges ( MFOUTLINE  Outline)

This routine searches through the specified outline and finds the points at which the outline changes direction. These points are then marked as "extremities". This routine is used as an alternative to FindExtremities(). It forces the endpoints of the microfeatures to be at the direction changes rather than at the midpoint between direction changes.

Parameters
Outlinemicro-feature outline to analyze
Returns
none
Note
Globals: none

Definition at line 190 of file mfoutline.cpp.

190  {
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 */
#define DegenerateOutline(O)
Definition: mfoutline.h:67
#define MarkPoint(P)
Definition: mfoutline.h:74
#define PointAt(O)
Definition: mfoutline.h:68
MFOUTLINE NextDirectionChange(MFOUTLINE EdgePoint)
Definition: mfoutline.cpp:449

◆ NewEdgePoint()

MFEDGEPT* NewEdgePoint ( )

Return a new edge point for a micro-feature outline.

Definition at line 212 of file mfoutline.cpp.

212  {
213  return reinterpret_cast<MFEDGEPT *>(malloc(sizeof(MFEDGEPT)));
214 }

◆ NextDirectionChange()

MFOUTLINE NextDirectionChange ( MFOUTLINE  EdgePoint)

This routine returns the next point in the micro-feature outline that has a direction different than EdgePoint. The routine assumes that the outline being searched is not a degenerate outline (i.e. it must have 2 or more edge points).

Parameters
EdgePointstart search from this point
Returns
Point of next direction change in micro-feature outline.
Note
Globals: none

Definition at line 449 of file mfoutline.cpp.

449  {
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 }
#define PointAt(O)
Definition: mfoutline.h:68
#define NextPointAfter(E)
Definition: mfoutline.h:69
DIRECTION
Definition: mfoutline.h:36

◆ NextExtremity()

MFOUTLINE NextExtremity ( MFOUTLINE  EdgePoint)

This routine returns the next point in the micro-feature outline that is an extremity. The search starts after EdgePoint. The routine assumes that the outline being searched is not a degenerate outline (i.e. it must have 2 or more edge points).

Parameters
EdgePointstart search from this point
Returns
Next extremity in the outline after EdgePoint.
Note
Globals: none

Definition at line 227 of file mfoutline.cpp.

227  {
228  EdgePoint = NextPointAfter(EdgePoint);
229  while (!PointAt(EdgePoint)->ExtremityMark)
230  EdgePoint = NextPointAfter(EdgePoint);
231 
232  return (EdgePoint);
233 
234 } /* NextExtremity */
#define PointAt(O)
Definition: mfoutline.h:68
#define NextPointAfter(E)
Definition: mfoutline.h:69

◆ NormalizeOutline()

void NormalizeOutline ( MFOUTLINE  Outline,
float  XOrigin 
)

This routine normalizes the coordinates of the specified outline so that the outline is deskewed down to the baseline, translated so that x=0 is at XOrigin, and scaled so that the height of a character cell from descender to ascender is 1. Of this height, 0.25 is for the descender, 0.25 for the ascender, and 0.5 for the x-height. The y coordinate of the baseline is 0.

Parameters
Outlineoutline to be normalized
XOriginx-origin of text
Returns
none
Note
Globals: none

Definition at line 251 of file mfoutline.cpp.

252  {
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 */
#define MF_SCALE_FACTOR
Definition: mfoutline.h:64
const int kBlnBaselineOffset
Definition: normalis.h:25
#define PointAt(O)
Definition: mfoutline.h:68
float y
Definition: fpoint.h:31
#define NIL_LIST
Definition: oldlist.h:127
#define NextPointAfter(E)
Definition: mfoutline.h:69
FPOINT Point
Definition: mfoutline.h:41
float x
Definition: fpoint.h:31