tesseract 4.1.1
Loading...
Searching...
No Matches
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 **
6 ** (c) Copyright Hewlett-Packard Company, 1988.
7 ** Licensed under the Apache License, Version 2.0 (the "License");
8 ** you may not use this file except in compliance with the License.
9 ** You may obtain a copy of the License at
10 ** http://www.apache.org/licenses/LICENSE-2.0
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 ******************************************************************************/
17/*----------------------------------------------------------------------------
18 Include Files and Type Defines
19----------------------------------------------------------------------------*/
20#include "clusttool.h" //If remove you get cought in a loop somewhere
21#include "mfoutline.h"
22#include "blobs.h"
23#include "mfx.h"
24#include "params.h"
25#include "classify.h"
26
27#include <cmath>
28#include <cstdio>
29
30/*----------------------------------------------------------------------------
31 Public Code
32----------------------------------------------------------------------------*/
33
34/*---------------------------------------------------------------------------*/
38 LIST outlines = NIL_LIST;
39 return (blob == nullptr)
40 ? NIL_LIST
41 : ConvertOutlines(blob->outlines, outlines, outer);
42}
43
44
45/*---------------------------------------------------------------------------*/
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}
79
80
81/*---------------------------------------------------------------------------*/
90 LIST mf_outlines,
91 OUTLINETYPE outline_type) {
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}
102
103/*---------------------------------------------------------------------------*/
116 float MinSlope,
117 float MaxSlope) {
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 */
138
139
140/*---------------------------------------------------------------------------*/
146void FreeMFOutline(void *arg) { //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 */
159
160
161/*---------------------------------------------------------------------------*/
167void FreeOutlines(LIST Outlines) {
168 destroy_nodes(Outlines, FreeMFOutline);
169} /* FreeOutlines */
170
171
172/*---------------------------------------------------------------------------*/
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 */
201
202
203/*---------------------------------------------------------------------------*/
206 return reinterpret_cast<MFEDGEPT *>(malloc(sizeof(MFEDGEPT)));
207}
208
209/*---------------------------------------------------------------------------*/
221 EdgePoint = NextPointAfter(EdgePoint);
222 while (!PointAt(EdgePoint)->ExtremityMark)
223 EdgePoint = NextPointAfter(EdgePoint);
224
225 return (EdgePoint);
226
227} /* NextExtremity */
228
229
230/*---------------------------------------------------------------------------*/
243 float XOrigin) {
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 */
256
257
258/*---------------------------------------------------------------------------*/
259namespace tesseract {
277 float *XScale,
278 float *YScale) {
279 MFOUTLINE Outline;
280
281 switch (classify_norm_method) {
282 case character:
283 ASSERT_HOST(!"How did NormalizeOutlines get called in character mode?");
284 break;
285
286 case baseline:
287 iterate(Outlines) {
288 Outline = static_cast<MFOUTLINE>first_node(Outlines);
289 NormalizeOutline(Outline, 0.0);
290 }
291 *XScale = *YScale = MF_SCALE_FACTOR;
292 break;
293 }
294} /* NormalizeOutlines */
295} // namespace tesseract
296
297/*----------------------------------------------------------------------------
298 Private Code
299----------------------------------------------------------------------------*/
310void ChangeDirection(MFOUTLINE Start, MFOUTLINE End, DIRECTION Direction) {
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 */
319
327void CharNormalizeOutline(MFOUTLINE Outline, const DENORM& cn_denorm) {
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 */
348
365 MFEDGEPT *Finish,
366 float MinSlope,
367 float MaxSlope) {
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}
425
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}
const int kBlnBaselineOffset
Definition: normalis.h:25
#define ASSERT_HOST(x)
Definition: errcode.h:88
MFEDGEPT * NewEdgePoint()
Definition: mfoutline.cpp:205
MFOUTLINE NextDirectionChange(MFOUTLINE EdgePoint)
Definition: mfoutline.cpp:435
void FreeMFOutline(void *arg)
Definition: mfoutline.cpp:146
LIST ConvertBlob(TBLOB *blob)
Definition: mfoutline.cpp:37
LIST ConvertOutlines(TESSLINE *outline, LIST mf_outlines, OUTLINETYPE outline_type)
Definition: mfoutline.cpp:89
void FreeOutlines(LIST Outlines)
Definition: mfoutline.cpp:167
void NormalizeOutline(MFOUTLINE Outline, float XOrigin)
Definition: mfoutline.cpp:242
void ComputeDirection(MFEDGEPT *Start, MFEDGEPT *Finish, float MinSlope, float MaxSlope)
Definition: mfoutline.cpp:364
void FindDirectionChanges(MFOUTLINE Outline, float MinSlope, float MaxSlope)
Definition: mfoutline.cpp:115
MFOUTLINE ConvertOutline(TESSLINE *outline)
Definition: mfoutline.cpp:47
void ChangeDirection(MFOUTLINE Start, MFOUTLINE End, DIRECTION Direction)
Definition: mfoutline.cpp:310
MFOUTLINE NextExtremity(MFOUTLINE EdgePoint)
Definition: mfoutline.cpp:220
void CharNormalizeOutline(MFOUTLINE Outline, const DENORM &cn_denorm)
Definition: mfoutline.cpp:327
void MarkDirectionChanges(MFOUTLINE Outline)
Definition: mfoutline.cpp:183
@ baseline
Definition: mfoutline.h:63
@ character
Definition: mfoutline.h:63
const float MF_SCALE_FACTOR
Definition: mfoutline.h:71
DIRECTION
Definition: mfoutline.h:31
@ 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
OUTLINETYPE
Definition: mfoutline.h:61
@ outer
Definition: mfoutline.h:61
void destroy_nodes(LIST list, void_dest destructor)
Definition: oldlist.cpp:157
LIST pop(LIST list)
Definition: oldlist.cpp:201
LIST push(LIST list, void *element)
Definition: oldlist.cpp:213
#define iterate(l)
Definition: oldlist.h:101
#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
#define NIL_LIST
Definition: oldlist.h:76
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
TESSLINE * next
Definition: blobs.h:281
Definition: blobs.h:284
TESSLINE * outlines
Definition: blobs.h:400
void LocalNormTransform(const TPOINT &pt, TPOINT *transformed) const
Definition: normalis.cpp:306
Definition: points.h:189
float y() const
Definition: points.h:210
float x() const
Definition: points.h:207
void NormalizeOutlines(LIST Outlines, float *XScale, float *YScale)
Definition: mfoutline.cpp:276
Definition: fpoint.h:29
float y
Definition: fpoint.h:30
float x
Definition: fpoint.h:30
FPOINT Point
Definition: mfoutline.h:53
DIRECTION Direction
Definition: mfoutline.h:57
DIRECTION PreviousDirection
Definition: mfoutline.h:58
float Slope
Definition: mfoutline.h:54
void ClearMark()
Definition: mfoutline.h:45
bool Hidden
Definition: mfoutline.h:55