tesseract 4.1.1
Loading...
Searching...
No Matches
mfoutline.cpp File Reference
#include "clusttool.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

namespace  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
Startdefines start of segment of outline to be modified
Enddefines end of segment of outline to be modified
Directionnew direction to assign to segment

Definition at line 310 of file mfoutline.cpp.

310 {
311 MFOUTLINE Current;
312
313 for (Current = Start; Current != End; Current = NextPointAfter (Current))
314 PointAt (Current)->Direction = Direction;
315
316 PointAt (End)->PreviousDirection = Direction;
317
318} /* ChangeDirection */

◆ 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

Definition at line 327 of file mfoutline.cpp.

327 {
328 MFOUTLINE First, Current;
329 MFEDGEPT *CurrentPoint;
330
331 if (Outline == NIL_LIST)
332 return;
333
334 First = Outline;
335 Current = First;
336 do {
337 CurrentPoint = PointAt(Current);
338 FCOORD pos(CurrentPoint->Point.x, CurrentPoint->Point.y);
339 cn_denorm.LocalNormTransform(pos, &pos);
340 CurrentPoint->Point.x = (pos.x() - UINT8_MAX / 2) * MF_SCALE_FACTOR;
341 CurrentPoint->Point.y = (pos.y() - UINT8_MAX / 2) * MF_SCALE_FACTOR;
342
343 Current = NextPointAfter(Current);
344 }
345 while (Current != First);
346
347} /* CharNormalizeOutline */
const float MF_SCALE_FACTOR
Definition: mfoutline.h:71
#define NIL_LIST
Definition: oldlist.h:76
void LocalNormTransform(const TPOINT &pt, TPOINT *transformed) const
Definition: normalis.cpp:306
Definition: points.h:189
float y
Definition: fpoint.h:30
float x
Definition: fpoint.h:30
FPOINT Point
Definition: mfoutline.h:53

◆ 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

Definition at line 364 of file mfoutline.cpp.

367 {
368 FVECTOR Delta;
369
370 Delta.x = Finish->Point.x - Start->Point.x;
371 Delta.y = Finish->Point.y - Start->Point.y;
372 if (Delta.x == 0) {
373 if (Delta.y < 0) {
374 Start->Slope = -FLT_MAX;
375 Start->Direction = south;
376 } else {
377 Start->Slope = FLT_MAX;
378 Start->Direction = north;
379 }
380 } else {
381 Start->Slope = Delta.y / Delta.x;
382 if (Delta.x > 0) {
383 if (Delta.y > 0) {
384 if (Start->Slope > MinSlope) {
385 if (Start->Slope < MaxSlope) {
386 Start->Direction = northeast;
387 } else {
388 Start->Direction = north;
389 }
390 } else {
391 Start->Direction = east;
392 }
393 }
394 else if (Start->Slope < -MinSlope) {
395 if (Start->Slope > -MaxSlope) {
396 Start->Direction = southeast;
397 } else {
398 Start->Direction = south;
399 }
400 } else {
401 Start->Direction = east;
402 }
403 } else if (Delta.y > 0) {
404 if (Start->Slope < -MinSlope) {
405 if (Start->Slope > -MaxSlope) {
406 Start->Direction = northwest;
407 } else {
408 Start->Direction = north;
409 }
410 } else {
411 Start->Direction = west;
412 }
413 } else if (Start->Slope > MinSlope) {
414 if (Start->Slope < MaxSlope) {
415 Start->Direction = southwest;
416 } else {
417 Start->Direction = south;
418 }
419 } else {
420 Start->Direction = west;
421 }
422 }
423 Finish->PreviousDirection = Start->Direction;
424}
@ south
Definition: mfoutline.h:33
@ southwest
Definition: mfoutline.h:39
@ east
Definition: mfoutline.h:34
@ north
Definition: mfoutline.h:32
@ northwest
Definition: mfoutline.h:37
@ west
Definition: mfoutline.h:35
@ southeast
Definition: mfoutline.h:38
@ northeast
Definition: mfoutline.h:36
Definition: fpoint.h:29
DIRECTION Direction
Definition: mfoutline.h:57
DIRECTION PreviousDirection
Definition: mfoutline.h:58
float Slope
Definition: mfoutline.h:54

◆ ConvertBlob()

LIST ConvertBlob ( TBLOB blob)

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

Definition at line 37 of file mfoutline.cpp.

37 {
38 LIST outlines = NIL_LIST;
39 return (blob == nullptr)
40 ? NIL_LIST
41 : ConvertOutlines(blob->outlines, outlines, outer);
42}
LIST ConvertOutlines(TESSLINE *outline, LIST mf_outlines, OUTLINETYPE outline_type)
Definition: mfoutline.cpp:89
@ outer
Definition: mfoutline.h:61
TESSLINE * outlines
Definition: blobs.h:400

◆ ConvertOutline()

MFOUTLINE ConvertOutline ( TESSLINE outline)

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

Definition at line 47 of file mfoutline.cpp.

47 {
48 MFEDGEPT *NewPoint;
49 MFOUTLINE MFOutline = NIL_LIST;
50 EDGEPT *EdgePoint;
51 EDGEPT *StartPoint;
52 EDGEPT *NextPoint;
53
54 if (outline == nullptr || outline->loop == nullptr)
55 return MFOutline;
56
57 StartPoint = outline->loop;
58 EdgePoint = StartPoint;
59 do {
60 NextPoint = EdgePoint->next;
61
62 /* filter out duplicate points */
63 if (EdgePoint->pos.x != NextPoint->pos.x ||
64 EdgePoint->pos.y != NextPoint->pos.y) {
65 NewPoint = NewEdgePoint();
66 NewPoint->ClearMark();
67 NewPoint->Hidden = EdgePoint->IsHidden();
68 NewPoint->Point.x = EdgePoint->pos.x;
69 NewPoint->Point.y = EdgePoint->pos.y;
70 MFOutline = push(MFOutline, NewPoint);
71 }
72 EdgePoint = NextPoint;
73 } while (EdgePoint != StartPoint);
74
75 if (MFOutline != nullptr)
76 MakeOutlineCircular(MFOutline);
77 return MFOutline;
78}
MFEDGEPT * NewEdgePoint()
Definition: mfoutline.cpp:205
LIST push(LIST list, void *element)
Definition: oldlist.cpp:213
int16_t x
Definition: blobs.h:93
int16_t y
Definition: blobs.h:94
Definition: blobs.h:99
EDGEPT * next
Definition: blobs.h:192
bool IsHidden() const
Definition: blobs.h:176
TPOINT pos
Definition: blobs.h:186
EDGEPT * loop
Definition: blobs.h:280
void ClearMark()
Definition: mfoutline.h:45
bool Hidden
Definition: mfoutline.h:55

◆ 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 89 of file mfoutline.cpp.

91 {
92 MFOUTLINE mf_outline;
93
94 while (outline != nullptr) {
95 mf_outline = ConvertOutline(outline);
96 if (mf_outline != nullptr)
97 mf_outlines = push(mf_outlines, mf_outline);
98 outline = outline->next;
99 }
100 return mf_outlines;
101}
MFOUTLINE ConvertOutline(TESSLINE *outline)
Definition: mfoutline.cpp:47
TESSLINE * next
Definition: blobs.h:281

◆ 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

Definition at line 115 of file mfoutline.cpp.

117 {
118 MFEDGEPT *Current;
119 MFEDGEPT *Last;
120 MFOUTLINE EdgePoint;
121
122 if (DegenerateOutline (Outline))
123 return;
124
125 Last = PointAt (Outline);
126 Outline = NextPointAfter (Outline);
127 EdgePoint = Outline;
128 do {
129 Current = PointAt (EdgePoint);
130 ComputeDirection(Last, Current, MinSlope, MaxSlope);
131
132 Last = Current;
133 EdgePoint = NextPointAfter (EdgePoint);
134 }
135 while (EdgePoint != Outline);
136
137} /* FindDirectionChanges */
void ComputeDirection(MFEDGEPT *Start, MFEDGEPT *Finish, float MinSlope, float MaxSlope)
Definition: mfoutline.cpp:364

◆ 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

Definition at line 146 of file mfoutline.cpp.

146 { //MFOUTLINE Outline)
147 MFOUTLINE Start;
148 auto Outline = static_cast<MFOUTLINE>(arg);
149
150 /* break the circular outline so we can use std. techniques to deallocate */
151 Start = list_rest (Outline);
152 set_rest(Outline, NIL_LIST);
153 while (Start != nullptr) {
154 free(first_node(Start));
155 Start = pop (Start);
156 }
157
158} /* FreeMFOutline */
LIST pop(LIST list)
Definition: oldlist.cpp:201
#define set_rest(l, cell)
Definition: oldlist.h:111
#define first_node(l)
Definition: oldlist.h:92
#define list_rest(l)
Definition: oldlist.h:91

◆ FreeOutlines()

void FreeOutlines ( LIST  Outlines)

Release all memory consumed by the specified list of outlines.

Parameters
Outlineslist of mf-outlines to be freed

Definition at line 167 of file mfoutline.cpp.

167 {
168 destroy_nodes(Outlines, FreeMFOutline);
169} /* FreeOutlines */
void FreeMFOutline(void *arg)
Definition: mfoutline.cpp:146
void destroy_nodes(LIST list, void_dest destructor)
Definition: oldlist.cpp:157

◆ 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

Definition at line 183 of file mfoutline.cpp.

183 {
184 MFOUTLINE Current;
185 MFOUTLINE Last;
186 MFOUTLINE First;
187
188 if (DegenerateOutline (Outline))
189 return;
190
191 First = NextDirectionChange (Outline);
192 Last = First;
193 do {
194 Current = NextDirectionChange (Last);
195 PointAt(Current)->MarkPoint();
196 Last = Current;
197 }
198 while (Last != First);
199
200} /* MarkDirectionChanges */
MFOUTLINE NextDirectionChange(MFOUTLINE EdgePoint)
Definition: mfoutline.cpp:435

◆ NewEdgePoint()

MFEDGEPT * NewEdgePoint ( )

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

Definition at line 205 of file mfoutline.cpp.

205 {
206 return reinterpret_cast<MFEDGEPT *>(malloc(sizeof(MFEDGEPT)));
207}

◆ 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 435 of file mfoutline.cpp.

435 {
436 DIRECTION InitialDirection;
437
438 InitialDirection = PointAt (EdgePoint)->Direction;
439
440 MFOUTLINE next_pt = nullptr;
441 do {
442 EdgePoint = NextPointAfter(EdgePoint);
443 next_pt = NextPointAfter(EdgePoint);
444 } while (PointAt(EdgePoint)->Direction == InitialDirection &&
445 !PointAt(EdgePoint)->Hidden &&
446 next_pt != nullptr && !PointAt(next_pt)->Hidden);
447
448 return (EdgePoint);
449}
DIRECTION
Definition: mfoutline.h:31

◆ 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 220 of file mfoutline.cpp.

220 {
221 EdgePoint = NextPointAfter(EdgePoint);
222 while (!PointAt(EdgePoint)->ExtremityMark)
223 EdgePoint = NextPointAfter(EdgePoint);
224
225 return (EdgePoint);
226
227} /* NextExtremity */

◆ 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

Definition at line 242 of file mfoutline.cpp.

243 {
244 if (Outline == NIL_LIST)
245 return;
246
247 MFOUTLINE EdgePoint = Outline;
248 do {
249 MFEDGEPT *Current = PointAt(EdgePoint);
250 Current->Point.y = MF_SCALE_FACTOR *
251 (Current->Point.y - kBlnBaselineOffset);
252 Current->Point.x = MF_SCALE_FACTOR * (Current->Point.x - XOrigin);
253 EdgePoint = NextPointAfter(EdgePoint);
254 } while (EdgePoint != Outline);
255} /* NormalizeOutline */
const int kBlnBaselineOffset
Definition: normalis.h:25