Coverage Report

Created: 2025-07-23 07:12

/src/tesseract/src/classify/mfx.cpp
Line
Count
Source (jump to first uncovered line)
1
/******************************************************************************
2
 ** Filename:       mfx.c
3
 ** Purpose:        Micro feature extraction routines
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 "mfx.h"
19
20
#include "clusttool.h" //NEEDED
21
#include "intfx.h"
22
#include "mfdefs.h"
23
#include "mfoutline.h"
24
#include "normalis.h"
25
#include "params.h"
26
27
namespace tesseract {
28
29
/* old numbers corresponded to 10.0 degrees and 80.0 degrees */
30
double_VAR(classify_min_slope, 0.414213562, "Slope below which lines are called horizontal");
31
double_VAR(classify_max_slope, 2.414213562, "Slope above which lines are called vertical");
32
33
/*----------------------------------------------------------------------------
34
          Private Function Prototypes
35
-----------------------------------------------------------------------------*/
36
37
MICROFEATURES ConvertToMicroFeatures(MFOUTLINE Outline, MICROFEATURES MicroFeatures);
38
39
MicroFeature ExtractMicroFeature(MFOUTLINE Start, MFOUTLINE End);
40
41
/*----------------------------------------------------------------------------
42
            Public Code
43
----------------------------------------------------------------------------*/
44
45
/**
46
 * This routine extracts micro-features from the specified
47
 * blob and returns a list of the micro-features.  All
48
 * micro-features are normalized according to the specified
49
 * line statistics.
50
 * @param Blob blob to extract micro-features from
51
 * @param cn_denorm control parameter to feature extractor
52
 * @return List of micro-features extracted from the blob.
53
 */
54
0
MICROFEATURES BlobMicroFeatures(TBLOB *Blob, const DENORM &cn_denorm) {
55
0
  MICROFEATURES MicroFeatures;
56
0
  LIST Outlines;
57
0
  LIST RemainingOutlines;
58
59
0
  if (Blob != nullptr) {
60
0
    Outlines = ConvertBlob(Blob);
61
62
0
    RemainingOutlines = Outlines;
63
0
    iterate(RemainingOutlines) {
64
0
      auto Outline = static_cast<MFOUTLINE>(RemainingOutlines->first_node());
65
0
      CharNormalizeOutline(Outline, cn_denorm);
66
0
    }
67
68
0
    RemainingOutlines = Outlines;
69
0
    iterate(RemainingOutlines) {
70
0
      auto Outline = static_cast<MFOUTLINE>(RemainingOutlines->first_node());
71
0
      FindDirectionChanges(Outline, classify_min_slope, classify_max_slope);
72
0
      MarkDirectionChanges(Outline);
73
0
      MicroFeatures = ConvertToMicroFeatures(Outline, MicroFeatures);
74
0
    }
75
0
    FreeOutlines(Outlines);
76
0
  }
77
0
  return MicroFeatures;
78
0
} /* BlobMicroFeatures */
79
80
/*---------------------------------------------------------------------------
81
            Private Code
82
---------------------------------------------------------------------------*/
83
84
/**
85
 * Convert Outline to MicroFeatures
86
 * @param Outline         outline to extract micro-features from
87
 * @param MicroFeatures   list of micro-features to add to
88
 * @return List of micro-features with new features added to front.
89
 * @note Globals: none
90
 */
91
0
MICROFEATURES ConvertToMicroFeatures(MFOUTLINE Outline, MICROFEATURES MicroFeatures) {
92
0
  MFOUTLINE Current;
93
0
  MFOUTLINE Last;
94
0
  MFOUTLINE First;
95
96
0
  if (DegenerateOutline(Outline)) {
97
0
    return (MicroFeatures);
98
0
  }
99
100
0
  First = NextExtremity(Outline);
101
0
  Last = First;
102
0
  do {
103
0
    Current = NextExtremity(Last);
104
0
    if (!PointAt(Current)->Hidden) {
105
0
      auto NewFeature = ExtractMicroFeature(Last, Current);
106
0
      MicroFeatures.push_front(NewFeature);
107
0
    }
108
0
    Last = Current;
109
0
  } while (Last != First);
110
111
0
  return MicroFeatures;
112
0
} /* ConvertToMicroFeatures */
113
114
/**
115
 * This routine computes the feature parameters which describe
116
 * the micro-feature that starts and Start and ends at End.
117
 * A new micro-feature is allocated, filled with the feature
118
 * parameters, and returned.  The routine assumes that
119
 * Start and End are not the same point.  If they are the
120
 * same point, nullptr is returned, a warning message is
121
 * printed, and the current outline is dumped to stdout.
122
 * @param Start starting point of micro-feature
123
 * @param End ending point of micro-feature
124
 * @return New micro-feature or nullptr if the feature was rejected.
125
 * @note Globals: none
126
 */
127
0
MicroFeature ExtractMicroFeature(MFOUTLINE Start, MFOUTLINE End) {
128
0
  MFEDGEPT *P1, *P2;
129
130
0
  P1 = PointAt(Start);
131
0
  P2 = PointAt(End);
132
133
0
  MicroFeature NewFeature;
134
0
  NewFeature[(int)MicroFeatureParameter::MFXPosition] = AverageOf(P1->Point.x, P2->Point.x);
135
0
  NewFeature[(int)MicroFeatureParameter::MFYPosition] = AverageOf(P1->Point.y, P2->Point.y);
136
0
  NewFeature[(int)MicroFeatureParameter::MFLength] = DistanceBetween(P1->Point, P2->Point);
137
0
  NewFeature[(int)MicroFeatureParameter::MFDirection] = NormalizedAngleFrom(&P1->Point, &P2->Point, 1.0);
138
0
  NewFeature[(int)MicroFeatureParameter::MFBulge1] = 0.0f;  // deprecated
139
0
  NewFeature[(int)MicroFeatureParameter::MFBulge2] = 0.0f; // deprecated
140
141
0
  return NewFeature;
142
0
} /* ExtractMicroFeature */
143
144
} // namespace tesseract