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 reinterpret_cast<MFEDGEPT *>(malloc(sizeof(MFEDGEPT)));
223 }
224 
225 /*---------------------------------------------------------------------------*/
239  EdgePoint = NextPointAfter(EdgePoint);
240  while (!PointAt(EdgePoint)->ExtremityMark)
241  EdgePoint = NextPointAfter(EdgePoint);
242 
243  return (EdgePoint);
244 
245 } /* NextExtremity */
246 
247 
248 /*---------------------------------------------------------------------------*/
265  FLOAT32 XOrigin) {
266  if (Outline == NIL_LIST)
267  return;
268 
269  MFOUTLINE EdgePoint = Outline;
270  do {
271  MFEDGEPT *Current = PointAt(EdgePoint);
272  Current->Point.y = MF_SCALE_FACTOR *
273  (Current->Point.y - kBlnBaselineOffset);
274  Current->Point.x = MF_SCALE_FACTOR * (Current->Point.x - XOrigin);
275  EdgePoint = NextPointAfter(EdgePoint);
276  } while (EdgePoint != Outline);
277 } /* NormalizeOutline */
278 
279 
280 /*---------------------------------------------------------------------------*/
281 namespace tesseract {
301  FLOAT32 *XScale,
302  FLOAT32 *YScale) {
303  MFOUTLINE Outline;
304 
305  switch (classify_norm_method) {
306  case character:
307  ASSERT_HOST(!"How did NormalizeOutlines get called in character mode?");
308  break;
309 
310  case baseline:
311  iterate(Outlines) {
312  Outline = (MFOUTLINE) first_node(Outlines);
313  NormalizeOutline(Outline, 0.0);
314  }
315  *XScale = *YScale = MF_SCALE_FACTOR;
316  break;
317  }
318 } /* NormalizeOutlines */
319 } // namespace tesseract
320 
321 /*----------------------------------------------------------------------------
322  Private Code
323 ----------------------------------------------------------------------------*/
337 void ChangeDirection(MFOUTLINE Start, MFOUTLINE End, DIRECTION Direction) {
338  MFOUTLINE Current;
339 
340  for (Current = Start; Current != End; Current = NextPointAfter (Current))
341  PointAt (Current)->Direction = Direction;
342 
343  PointAt (End)->PreviousDirection = Direction;
344 
345 } /* ChangeDirection */
346 
358 void CharNormalizeOutline(MFOUTLINE Outline, const DENORM& cn_denorm) {
359  MFOUTLINE First, Current;
360  MFEDGEPT *CurrentPoint;
361 
362  if (Outline == NIL_LIST)
363  return;
364 
365  First = Outline;
366  Current = First;
367  do {
368  CurrentPoint = PointAt(Current);
369  FCOORD pos(CurrentPoint->Point.x, CurrentPoint->Point.y);
370  cn_denorm.LocalNormTransform(pos, &pos);
371  CurrentPoint->Point.x = (pos.x() - MAX_UINT8 / 2) * MF_SCALE_FACTOR;
372  CurrentPoint->Point.y = (pos.y() - MAX_UINT8 / 2) * MF_SCALE_FACTOR;
373 
374  Current = NextPointAfter(Current);
375  }
376  while (Current != First);
377 
378 } /* CharNormalizeOutline */
379 
400  MFEDGEPT *Finish,
401  FLOAT32 MinSlope,
402  FLOAT32 MaxSlope) {
403  FVECTOR Delta;
404 
405  Delta.x = Finish->Point.x - Start->Point.x;
406  Delta.y = Finish->Point.y - Start->Point.y;
407  if (Delta.x == 0)
408  if (Delta.y < 0) {
409  Start->Slope = -MAX_FLOAT32;
410  Start->Direction = south;
411  }
412  else {
413  Start->Slope = MAX_FLOAT32;
414  Start->Direction = north;
415  }
416  else {
417  Start->Slope = Delta.y / Delta.x;
418  if (Delta.x > 0)
419  if (Delta.y > 0)
420  if (Start->Slope > MinSlope)
421  if (Start->Slope < MaxSlope)
422  Start->Direction = northeast;
423  else
424  Start->Direction = north;
425  else
426  Start->Direction = east;
427  else if (Start->Slope < -MinSlope)
428  if (Start->Slope > -MaxSlope)
429  Start->Direction = southeast;
430  else
431  Start->Direction = south;
432  else
433  Start->Direction = east;
434  else if (Delta.y > 0)
435  if (Start->Slope < -MinSlope)
436  if (Start->Slope > -MaxSlope)
437  Start->Direction = northwest;
438  else
439  Start->Direction = north;
440  else
441  Start->Direction = west;
442  else if (Start->Slope > MinSlope)
443  if (Start->Slope < MaxSlope)
444  Start->Direction = southwest;
445  else
446  Start->Direction = south;
447  else
448  Start->Direction = west;
449  }
450  Finish->PreviousDirection = Start->Direction;
451 }
452 
465  DIRECTION InitialDirection;
466 
467  InitialDirection = PointAt (EdgePoint)->Direction;
468 
469  MFOUTLINE next_pt = NULL;
470  do {
471  EdgePoint = NextPointAfter(EdgePoint);
472  next_pt = NextPointAfter(EdgePoint);
473  } while (PointAt(EdgePoint)->Direction == InitialDirection &&
474  !PointAt(EdgePoint)->Hidden &&
475  next_pt != NULL && !PointAt(next_pt)->Hidden);
476 
477  return (EdgePoint);
478 }
Definition: points.h:189
LIST ConvertOutlines(TESSLINE *outline, LIST mf_outlines, OUTLINETYPE outline_type)
Definition: mfoutline.cpp:92
void FindDirectionChanges(MFOUTLINE Outline, FLOAT32 MinSlope, FLOAT32 MaxSlope)
Definition: mfoutline.cpp:121
float y() const
Definition: points.h:212
LIST pop(LIST list)
Definition: oldlist.cpp:271
TESSLINE * outlines
Definition: blobs.h:377
void CharNormalizeOutline(MFOUTLINE Outline, const DENORM &cn_denorm)
Definition: mfoutline.cpp:358
void MarkDirectionChanges(MFOUTLINE Outline)
Definition: mfoutline.cpp:199
#define NextPointAfter(E)
Definition: mfoutline.h:68
MFOUTLINE NextDirectionChange(MFOUTLINE EdgePoint)
Definition: mfoutline.cpp:464
TESSLINE * next
Definition: blobs.h:258
MFOUTLINE NextExtremity(MFOUTLINE EdgePoint)
Definition: mfoutline.cpp:238
LIST ConvertBlob(TBLOB *blob)
Definition: mfoutline.cpp:40
#define MF_SCALE_FACTOR
Definition: mfoutline.h:63
LIST push(LIST list, void *element)
Definition: oldlist.cpp:288
void NormalizeOutline(MFOUTLINE Outline, FLOAT32 XOrigin)
Definition: mfoutline.cpp:264
void FreeMFOutline(void *arg)
Definition: mfoutline.cpp:155
bool IsHidden() const
Definition: blobs.h:153
DIRECTION
Definition: mfoutline.h:35
DIRECTION PreviousDirection
Definition: mfoutline.h:46
#define MAX_UINT8
Definition: host.h:63
#define PointAt(O)
Definition: mfoutline.h:67
OUTLINETYPE
Definition: mfoutline.h:49
EDGEPT * next
Definition: blobs.h:169
EDGEPT * loop
Definition: blobs.h:257
void ComputeDirection(MFEDGEPT *Start, MFEDGEPT *Finish, FLOAT32 MinSlope, FLOAT32 MaxSlope)
Definition: mfoutline.cpp:399
#define list_rest(l)
Definition: oldlist.h:138
FPOINT Point
Definition: mfoutline.h:40
Definition: blobs.h:76
float x() const
Definition: points.h:209
Definition: mfoutline.h:36
FLOAT32 x
Definition: fpoint.h:31
#define MakeOutlineCircular(O)
Definition: mfoutline.h:69
#define set_rest(l, cell)
Definition: oldlist.h:222
Definition: blobs.h:261
#define NIL_LIST
Definition: oldlist.h:126
#define ASSERT_HOST(x)
Definition: errcode.h:84
FLOAT32 Slope
Definition: mfoutline.h:41
MFEDGEPT * NewEdgePoint()
Definition: mfoutline.cpp:221
DIRECTION Direction
Definition: mfoutline.h:45
inT16 y
Definition: blobs.h:72
LIST MFOUTLINE
Definition: mfoutline.h:33
#define first_node(l)
Definition: oldlist.h:139
void LocalNormTransform(const TPOINT &pt, TPOINT *transformed) const
Definition: normalis.cpp:305
#define DegenerateOutline(O)
Definition: mfoutline.h:66
#define iterate(l)
Definition: oldlist.h:159
MFOUTLINE ConvertOutline(TESSLINE *outline)
Definition: mfoutline.cpp:50
float FLOAT32
Definition: host.h:42
const int kBlnBaselineOffset
Definition: normalis.h:29
TPOINT pos
Definition: blobs.h:163
void ChangeDirection(MFOUTLINE Start, MFOUTLINE End, DIRECTION Direction)
Definition: mfoutline.cpp:337
Definition: fpoint.h:29
BOOL8 Hidden
Definition: mfoutline.h:43
#define ClearMark(P)
Definition: mfoutline.h:72
#define MarkPoint(P)
Definition: mfoutline.h:73
#define MAX_FLOAT32
Definition: host.h:66
void destroy_nodes(LIST list, void_dest destructor)
Definition: oldlist.cpp:191
void NormalizeOutlines(LIST Outlines, FLOAT32 *XScale, FLOAT32 *YScale)
Definition: mfoutline.cpp:300
inT16 x
Definition: blobs.h:71
void FreeOutlines(LIST Outlines)
Definition: mfoutline.cpp:179
FLOAT32 y
Definition: fpoint.h:31
Definition: mfoutline.h:36