All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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 /*---------------------------------------------------------------------------*/
40  LIST outlines = NIL_LIST;
41  return (blob == NULL)
42  ? NIL_LIST
43  : ConvertOutlines(blob->outlines, outlines, outer);
44 }
45 
46 
47 /*---------------------------------------------------------------------------*/
50  MFEDGEPT *NewPoint;
51  MFOUTLINE MFOutline = NIL_LIST;
52  EDGEPT *EdgePoint;
53  EDGEPT *StartPoint;
54  EDGEPT *NextPoint;
55 
56  if (outline == NULL || outline->loop == NULL)
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 != NULL)
78  MakeOutlineCircular(MFOutline);
79  return MFOutline;
80 }
81 
82 
83 /*---------------------------------------------------------------------------*/
92  LIST mf_outlines,
93  OUTLINETYPE outline_type) {
94  MFOUTLINE mf_outline;
95 
96  while (outline != NULL) {
97  mf_outline = ConvertOutline(outline);
98  if (mf_outline != NULL)
99  mf_outlines = push(mf_outlines, mf_outline);
100  outline = outline->next;
101  }
102  return mf_outlines;
103 }
104 
105 /*---------------------------------------------------------------------------*/
121  FLOAT32 MinSlope,
122  FLOAT32 MaxSlope) {
123  MFEDGEPT *Current;
124  MFEDGEPT *Last;
125  MFOUTLINE EdgePoint;
126 
127  if (DegenerateOutline (Outline))
128  return;
129 
130  Last = PointAt (Outline);
131  Outline = NextPointAfter (Outline);
132  EdgePoint = Outline;
133  do {
134  Current = PointAt (EdgePoint);
135  ComputeDirection(Last, Current, MinSlope, MaxSlope);
136 
137  Last = Current;
138  EdgePoint = NextPointAfter (EdgePoint);
139  }
140  while (EdgePoint != Outline);
141 
142 } /* FindDirectionChanges */
143 
144 
145 /*---------------------------------------------------------------------------*/
154 void FreeMFOutline(void *arg) { //MFOUTLINE Outline)
155  MFOUTLINE Start;
156  MFOUTLINE Outline = (MFOUTLINE) arg;
157 
158  /* break the circular outline so we can use std. techniques to deallocate */
159  Start = list_rest (Outline);
160  set_rest(Outline, NIL_LIST);
161  while (Start != NULL) {
162  free_struct (first_node (Start), sizeof (MFEDGEPT), "MFEDGEPT");
163  Start = pop (Start);
164  }
165 
166 } /* FreeMFOutline */
167 
168 
169 /*---------------------------------------------------------------------------*/
178 void FreeOutlines(LIST Outlines) {
179  destroy_nodes(Outlines, FreeMFOutline);
180 } /* FreeOutlines */
181 
182 
183 /*---------------------------------------------------------------------------*/
199  MFOUTLINE Current;
200  MFOUTLINE Last;
201  MFOUTLINE First;
202 
203  if (DegenerateOutline (Outline))
204  return;
205 
206  First = NextDirectionChange (Outline);
207  Last = First;
208  do {
209  Current = NextDirectionChange (Last);
210  MarkPoint (PointAt (Current));
211  Last = Current;
212  }
213  while (Last != First);
214 
215 } /* MarkDirectionChanges */
216 
217 
218 /*---------------------------------------------------------------------------*/
221  return ((MFEDGEPT *) alloc_struct(sizeof(MFEDGEPT), "MFEDGEPT"));
222 }
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 
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 
381 
402  MFEDGEPT *Finish,
403  FLOAT32 MinSlope,
404  FLOAT32 MaxSlope) {
405  FVECTOR Delta;
406 
407  Delta.x = Finish->Point.x - Start->Point.x;
408  Delta.y = Finish->Point.y - Start->Point.y;
409  if (Delta.x == 0)
410  if (Delta.y < 0) {
411  Start->Slope = -MAX_FLOAT32;
412  Start->Direction = south;
413  }
414  else {
415  Start->Slope = MAX_FLOAT32;
416  Start->Direction = north;
417  }
418  else {
419  Start->Slope = Delta.y / Delta.x;
420  if (Delta.x > 0)
421  if (Delta.y > 0)
422  if (Start->Slope > MinSlope)
423  if (Start->Slope < MaxSlope)
424  Start->Direction = northeast;
425  else
426  Start->Direction = north;
427  else
428  Start->Direction = east;
429  else if (Start->Slope < -MinSlope)
430  if (Start->Slope > -MaxSlope)
431  Start->Direction = southeast;
432  else
433  Start->Direction = south;
434  else
435  Start->Direction = east;
436  else if (Delta.y > 0)
437  if (Start->Slope < -MinSlope)
438  if (Start->Slope > -MaxSlope)
439  Start->Direction = northwest;
440  else
441  Start->Direction = north;
442  else
443  Start->Direction = west;
444  else if (Start->Slope > MinSlope)
445  if (Start->Slope < MaxSlope)
446  Start->Direction = southwest;
447  else
448  Start->Direction = south;
449  else
450  Start->Direction = west;
451  }
452  Finish->PreviousDirection = Start->Direction;
453 }
454 
467  DIRECTION InitialDirection;
468 
469  InitialDirection = PointAt (EdgePoint)->Direction;
470 
471  MFOUTLINE next_pt = NULL;
472  do {
473  EdgePoint = NextPointAfter(EdgePoint);
474  next_pt = NextPointAfter(EdgePoint);
475  } while (PointAt(EdgePoint)->Direction == InitialDirection &&
476  !PointAt(EdgePoint)->Hidden &&
477  next_pt != NULL && !PointAt(next_pt)->Hidden);
478 
479  return (EdgePoint);
480 }
Definition: blobs.h:261
void LocalNormTransform(const TPOINT &pt, TPOINT *transformed) const
Definition: normalis.cpp:305
float FLOAT32
Definition: host.h:111
void CharNormalizeOutline(MFOUTLINE Outline, const DENORM &cn_denorm)
Definition: mfoutline.cpp:359
#define NIL_LIST
Definition: oldlist.h:126
float x() const
Definition: points.h:209
inT16 y
Definition: blobs.h:72
TESSLINE * next
Definition: blobs.h:258
#define ClearMark(P)
Definition: mfoutline.h:72
void FreeMFOutline(void *arg)
Definition: mfoutline.cpp:154
#define set_rest(l, cell)
Definition: oldlist.h:222
MFOUTLINE NextExtremity(MFOUTLINE EdgePoint)
Definition: mfoutline.cpp:238
OUTLINETYPE
Definition: mfoutline.h:49
Definition: mfoutline.h:36
#define ASSERT_HOST(x)
Definition: errcode.h:84
void FindDirectionChanges(MFOUTLINE Outline, FLOAT32 MinSlope, FLOAT32 MaxSlope)
Definition: mfoutline.cpp:120
void NormalizeOutline(MFOUTLINE Outline, FLOAT32 XOrigin)
Definition: mfoutline.cpp:264
Definition: fpoint.h:29
MFOUTLINE NextDirectionChange(MFOUTLINE EdgePoint)
Definition: mfoutline.cpp:466
void ChangeDirection(MFOUTLINE Start, MFOUTLINE End, DIRECTION Direction)
Definition: mfoutline.cpp:337
MFOUTLINE ConvertOutline(TESSLINE *outline)
Definition: mfoutline.cpp:49
void ComputeDirection(MFEDGEPT *Start, MFEDGEPT *Finish, FLOAT32 MinSlope, FLOAT32 MaxSlope)
Definition: mfoutline.cpp:401
DIRECTION Direction
Definition: mfoutline.h:45
EDGEPT * next
Definition: blobs.h:169
void destroy_nodes(LIST list, void_dest destructor)
Definition: oldlist.cpp:204
LIST ConvertBlob(TBLOB *blob)
Definition: mfoutline.cpp:39
#define PointAt(O)
Definition: mfoutline.h:67
const int kBlnBaselineOffset
Definition: normalis.h:29
void FreeOutlines(LIST Outlines)
Definition: mfoutline.cpp:178
#define MAX_UINT8
Definition: host.h:121
inT16 x
Definition: blobs.h:71
bool IsHidden() const
Definition: blobs.h:153
DIRECTION
Definition: mfoutline.h:35
FLOAT32 y
Definition: fpoint.h:31
#define first_node(l)
Definition: oldlist.h:139
#define MarkPoint(P)
Definition: mfoutline.h:73
#define iterate(l)
Definition: oldlist.h:159
LIST pop(LIST list)
Definition: oldlist.cpp:305
#define DegenerateOutline(O)
Definition: mfoutline.h:66
Definition: mfoutline.h:36
void * alloc_struct(inT32 count, const char *)
Definition: memry.cpp:39
FLOAT32 Slope
Definition: mfoutline.h:41
DIRECTION PreviousDirection
Definition: mfoutline.h:46
LIST ConvertOutlines(TESSLINE *outline, LIST mf_outlines, OUTLINETYPE outline_type)
Definition: mfoutline.cpp:91
TPOINT pos
Definition: blobs.h:163
Definition: blobs.h:76
void MarkDirectionChanges(MFOUTLINE Outline)
Definition: mfoutline.cpp:198
BOOL8 Hidden
Definition: mfoutline.h:43
#define NextPointAfter(E)
Definition: mfoutline.h:68
float y() const
Definition: points.h:212
#define MAX_FLOAT32
Definition: host.h:124
MFEDGEPT * NewEdgePoint()
Definition: mfoutline.cpp:220
#define NULL
Definition: host.h:144
TESSLINE * outlines
Definition: blobs.h:377
EDGEPT * loop
Definition: blobs.h:257
void free_struct(void *deadstruct, inT32, const char *)
Definition: memry.cpp:43
FPOINT Point
Definition: mfoutline.h:40
Definition: points.h:189
LIST MFOUTLINE
Definition: mfoutline.h:33
#define MakeOutlineCircular(O)
Definition: mfoutline.h:69
#define list_rest(l)
Definition: oldlist.h:138
FLOAT32 x
Definition: fpoint.h:31
void NormalizeOutlines(LIST Outlines, FLOAT32 *XScale, FLOAT32 *YScale)
Definition: mfoutline.cpp:300
LIST push(LIST list, void *element)
Definition: oldlist.cpp:323
#define MF_SCALE_FACTOR
Definition: mfoutline.h:63