tesseract  4.00.00dev
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 "const.h"
26 #include "mfx.h"
27 #include "params.h"
28 #include "classify.h"
29 
30 #include <math.h>
31 #include <stdio.h>
32 
33 /*----------------------------------------------------------------------------
34  Public Code
35 ----------------------------------------------------------------------------*/
36 
37 /*---------------------------------------------------------------------------*/
41  LIST outlines = NIL_LIST;
42  return (blob == NULL)
43  ? NIL_LIST
44  : ConvertOutlines(blob->outlines, outlines, outer);
45 }
46 
47 
48 /*---------------------------------------------------------------------------*/
51  MFEDGEPT *NewPoint;
52  MFOUTLINE MFOutline = NIL_LIST;
53  EDGEPT *EdgePoint;
54  EDGEPT *StartPoint;
55  EDGEPT *NextPoint;
56 
57  if (outline == NULL || outline->loop == NULL)
58  return MFOutline;
59 
60  StartPoint = outline->loop;
61  EdgePoint = StartPoint;
62  do {
63  NextPoint = EdgePoint->next;
64 
65  /* filter out duplicate points */
66  if (EdgePoint->pos.x != NextPoint->pos.x ||
67  EdgePoint->pos.y != NextPoint->pos.y) {
68  NewPoint = NewEdgePoint();
69  ClearMark(NewPoint);
70  NewPoint->Hidden = EdgePoint->IsHidden();
71  NewPoint->Point.x = EdgePoint->pos.x;
72  NewPoint->Point.y = EdgePoint->pos.y;
73  MFOutline = push(MFOutline, NewPoint);
74  }
75  EdgePoint = NextPoint;
76  } while (EdgePoint != StartPoint);
77 
78  if (MFOutline != NULL)
79  MakeOutlineCircular(MFOutline);
80  return MFOutline;
81 }
82 
83 
84 /*---------------------------------------------------------------------------*/
93  LIST mf_outlines,
94  OUTLINETYPE outline_type) {
95  MFOUTLINE mf_outline;
96 
97  while (outline != NULL) {
98  mf_outline = ConvertOutline(outline);
99  if (mf_outline != NULL)
100  mf_outlines = push(mf_outlines, mf_outline);
101  outline = outline->next;
102  }
103  return mf_outlines;
104 }
105 
106 /*---------------------------------------------------------------------------*/
122  FLOAT32 MinSlope,
123  FLOAT32 MaxSlope) {
124  MFEDGEPT *Current;
125  MFEDGEPT *Last;
126  MFOUTLINE EdgePoint;
127 
128  if (DegenerateOutline (Outline))
129  return;
130 
131  Last = PointAt (Outline);
132  Outline = NextPointAfter (Outline);
133  EdgePoint = Outline;
134  do {
135  Current = PointAt (EdgePoint);
136  ComputeDirection(Last, Current, MinSlope, MaxSlope);
137 
138  Last = Current;
139  EdgePoint = NextPointAfter (EdgePoint);
140  }
141  while (EdgePoint != Outline);
142 
143 } /* FindDirectionChanges */
144 
145 
146 /*---------------------------------------------------------------------------*/
155 void FreeMFOutline(void *arg) { //MFOUTLINE Outline)
156  MFOUTLINE Start;
157  MFOUTLINE Outline = (MFOUTLINE) arg;
158 
159  /* break the circular outline so we can use std. techniques to deallocate */
160  Start = list_rest (Outline);
161  set_rest(Outline, NIL_LIST);
162  while (Start != NULL) {
163  free(first_node(Start));
164  Start = pop (Start);
165  }
166 
167 } /* FreeMFOutline */
168 
169 
170 /*---------------------------------------------------------------------------*/
179 void FreeOutlines(LIST Outlines) {
180  destroy_nodes(Outlines, FreeMFOutline);
181 } /* FreeOutlines */
182 
183 
184 /*---------------------------------------------------------------------------*/
200  MFOUTLINE Current;
201  MFOUTLINE Last;
202  MFOUTLINE First;
203 
204  if (DegenerateOutline (Outline))
205  return;
206 
207  First = NextDirectionChange (Outline);
208  Last = First;
209  do {
210  Current = NextDirectionChange (Last);
211  MarkPoint (PointAt (Current));
212  Last = Current;
213  }
214  while (Last != First);
215 
216 } /* MarkDirectionChanges */
217 
218 
219 /*---------------------------------------------------------------------------*/
222  return (MFEDGEPT *) malloc(sizeof(MFEDGEPT));
223 }
224 
225 
226 /*---------------------------------------------------------------------------*/
240  EdgePoint = NextPointAfter(EdgePoint);
241  while (!PointAt(EdgePoint)->ExtremityMark)
242  EdgePoint = NextPointAfter(EdgePoint);
243 
244  return (EdgePoint);
245 
246 } /* NextExtremity */
247 
248 
249 /*---------------------------------------------------------------------------*/
266  FLOAT32 XOrigin) {
267  if (Outline == NIL_LIST)
268  return;
269 
270  MFOUTLINE EdgePoint = Outline;
271  do {
272  MFEDGEPT *Current = PointAt(EdgePoint);
273  Current->Point.y = MF_SCALE_FACTOR *
274  (Current->Point.y - kBlnBaselineOffset);
275  Current->Point.x = MF_SCALE_FACTOR * (Current->Point.x - XOrigin);
276  EdgePoint = NextPointAfter(EdgePoint);
277  } while (EdgePoint != Outline);
278 } /* NormalizeOutline */
279 
280 
281 /*---------------------------------------------------------------------------*/
282 namespace tesseract {
302  FLOAT32 *XScale,
303  FLOAT32 *YScale) {
304  MFOUTLINE Outline;
305 
306  switch (classify_norm_method) {
307  case character:
308  ASSERT_HOST(!"How did NormalizeOutlines get called in character mode?");
309  break;
310 
311  case baseline:
312  iterate(Outlines) {
313  Outline = (MFOUTLINE) first_node(Outlines);
314  NormalizeOutline(Outline, 0.0);
315  }
316  *XScale = *YScale = MF_SCALE_FACTOR;
317  break;
318  }
319 } /* NormalizeOutlines */
320 } // namespace tesseract
321 
322 /*----------------------------------------------------------------------------
323  Private Code
324 ----------------------------------------------------------------------------*/
338 void ChangeDirection(MFOUTLINE Start, MFOUTLINE End, DIRECTION Direction) {
339  MFOUTLINE Current;
340 
341  for (Current = Start; Current != End; Current = NextPointAfter (Current))
342  PointAt (Current)->Direction = Direction;
343 
344  PointAt (End)->PreviousDirection = Direction;
345 
346 } /* ChangeDirection */
347 
359 void CharNormalizeOutline(MFOUTLINE Outline, const DENORM& cn_denorm) {
360  MFOUTLINE First, Current;
361  MFEDGEPT *CurrentPoint;
362 
363  if (Outline == NIL_LIST)
364  return;
365 
366  First = Outline;
367  Current = First;
368  do {
369  CurrentPoint = PointAt(Current);
370  FCOORD pos(CurrentPoint->Point.x, CurrentPoint->Point.y);
371  cn_denorm.LocalNormTransform(pos, &pos);
372  CurrentPoint->Point.x = (pos.x() - MAX_UINT8 / 2) * MF_SCALE_FACTOR;
373  CurrentPoint->Point.y = (pos.y() - MAX_UINT8 / 2) * MF_SCALE_FACTOR;
374 
375  Current = NextPointAfter(Current);
376  }
377  while (Current != First);
378 
379 } /* CharNormalizeOutline */
380 
401  MFEDGEPT *Finish,
402  FLOAT32 MinSlope,
403  FLOAT32 MaxSlope) {
404  FVECTOR Delta;
405 
406  Delta.x = Finish->Point.x - Start->Point.x;
407  Delta.y = Finish->Point.y - Start->Point.y;
408  if (Delta.x == 0)
409  if (Delta.y < 0) {
410  Start->Slope = -MAX_FLOAT32;
411  Start->Direction = south;
412  }
413  else {
414  Start->Slope = MAX_FLOAT32;
415  Start->Direction = north;
416  }
417  else {
418  Start->Slope = Delta.y / Delta.x;
419  if (Delta.x > 0)
420  if (Delta.y > 0)
421  if (Start->Slope > MinSlope)
422  if (Start->Slope < MaxSlope)
423  Start->Direction = northeast;
424  else
425  Start->Direction = north;
426  else
427  Start->Direction = east;
428  else if (Start->Slope < -MinSlope)
429  if (Start->Slope > -MaxSlope)
430  Start->Direction = southeast;
431  else
432  Start->Direction = south;
433  else
434  Start->Direction = east;
435  else if (Delta.y > 0)
436  if (Start->Slope < -MinSlope)
437  if (Start->Slope > -MaxSlope)
438  Start->Direction = northwest;
439  else
440  Start->Direction = north;
441  else
442  Start->Direction = west;
443  else if (Start->Slope > MinSlope)
444  if (Start->Slope < MaxSlope)
445  Start->Direction = southwest;
446  else
447  Start->Direction = south;
448  else
449  Start->Direction = west;
450  }
451  Finish->PreviousDirection = Start->Direction;
452 }
453 
466  DIRECTION InitialDirection;
467 
468  InitialDirection = PointAt (EdgePoint)->Direction;
469 
470  MFOUTLINE next_pt = NULL;
471  do {
472  EdgePoint = NextPointAfter(EdgePoint);
473  next_pt = NextPointAfter(EdgePoint);
474  } while (PointAt(EdgePoint)->Direction == InitialDirection &&
475  !PointAt(EdgePoint)->Hidden &&
476  next_pt != NULL && !PointAt(next_pt)->Hidden);
477 
478  return (EdgePoint);
479 }
LIST ConvertOutlines(TESSLINE *outline, LIST mf_outlines, OUTLINETYPE outline_type)
Definition: mfoutline.cpp:92
TESSLINE * next
Definition: blobs.h:258
Definition: fpoint.h:29
TPOINT pos
Definition: blobs.h:163
DIRECTION PreviousDirection
Definition: mfoutline.h:46
void NormalizeOutline(MFOUTLINE Outline, FLOAT32 XOrigin)
Definition: mfoutline.cpp:265
Definition: points.h:189
#define MAX_UINT8
Definition: host.h:63
void FindDirectionChanges(MFOUTLINE Outline, FLOAT32 MinSlope, FLOAT32 MaxSlope)
Definition: mfoutline.cpp:121
MFOUTLINE NextDirectionChange(MFOUTLINE EdgePoint)
Definition: mfoutline.cpp:465
#define MarkPoint(P)
Definition: mfoutline.h:73
TESSLINE * outlines
Definition: blobs.h:377
void MarkDirectionChanges(MFOUTLINE Outline)
Definition: mfoutline.cpp:199
void CharNormalizeOutline(MFOUTLINE Outline, const DENORM &cn_denorm)
Definition: mfoutline.cpp:359
LIST ConvertBlob(TBLOB *blob)
Definition: mfoutline.cpp:40
const int kBlnBaselineOffset
Definition: normalis.h:29
#define MF_SCALE_FACTOR
Definition: mfoutline.h:63
void ComputeDirection(MFEDGEPT *Start, MFEDGEPT *Finish, FLOAT32 MinSlope, FLOAT32 MaxSlope)
Definition: mfoutline.cpp:400
void NormalizeOutlines(LIST Outlines, FLOAT32 *XScale, FLOAT32 *YScale)
Definition: mfoutline.cpp:301
#define NIL_LIST
Definition: oldlist.h:126
#define MakeOutlineCircular(O)
Definition: mfoutline.h:69
void LocalNormTransform(const TPOINT &pt, TPOINT *transformed) const
Definition: normalis.cpp:305
LIST pop(LIST list)
Definition: oldlist.cpp:299
#define ASSERT_HOST(x)
Definition: errcode.h:84
#define PointAt(O)
Definition: mfoutline.h:67
#define ClearMark(P)
Definition: mfoutline.h:72
LIST MFOUTLINE
Definition: mfoutline.h:33
EDGEPT * loop
Definition: blobs.h:257
bool IsHidden() const
Definition: blobs.h:153
inT16 x
Definition: blobs.h:71
BOOL8 Hidden
Definition: mfoutline.h:43
#define set_rest(l, cell)
Definition: oldlist.h:222
EDGEPT * next
Definition: blobs.h:169
#define MAX_FLOAT32
Definition: host.h:66
Definition: blobs.h:76
void FreeMFOutline(void *arg)
Definition: mfoutline.cpp:155
#define first_node(l)
Definition: oldlist.h:139
Definition: mfoutline.h:36
MFEDGEPT * NewEdgePoint()
Definition: mfoutline.cpp:221
void destroy_nodes(LIST list, void_dest destructor)
Definition: oldlist.cpp:199
#define DegenerateOutline(O)
Definition: mfoutline.h:66
FLOAT32 y
Definition: fpoint.h:31
DIRECTION Direction
Definition: mfoutline.h:45
inT16 y
Definition: blobs.h:72
float FLOAT32
Definition: host.h:42
Definition: blobs.h:261
FPOINT Point
Definition: mfoutline.h:40
float y() const
Definition: points.h:212
OUTLINETYPE
Definition: mfoutline.h:49
MFOUTLINE ConvertOutline(TESSLINE *outline)
Definition: mfoutline.cpp:50
FLOAT32 x
Definition: fpoint.h:31
void ChangeDirection(MFOUTLINE Start, MFOUTLINE End, DIRECTION Direction)
Definition: mfoutline.cpp:338
#define NextPointAfter(E)
Definition: mfoutline.h:68
MFOUTLINE NextExtremity(MFOUTLINE EdgePoint)
Definition: mfoutline.cpp:239
#define iterate(l)
Definition: oldlist.h:159
void FreeOutlines(LIST Outlines)
Definition: mfoutline.cpp:179
Definition: mfoutline.h:36
float x() const
Definition: points.h:209
LIST push(LIST list, void *element)
Definition: oldlist.cpp:317
DIRECTION
Definition: mfoutline.h:35
FLOAT32 Slope
Definition: mfoutline.h:41
#define list_rest(l)
Definition: oldlist.h:138