/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 |