/src/tesseract/src/classify/outfeat.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /****************************************************************************** |
2 | | ** Filename: outfeat.c |
3 | | ** Purpose: Definition of outline-features. |
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 "outfeat.h" |
19 | | |
20 | | #include "classify.h" |
21 | | #include "featdefs.h" |
22 | | #include "mfoutline.h" |
23 | | #include "ocrfeatures.h" |
24 | | |
25 | | #include <cstdio> |
26 | | |
27 | | namespace tesseract { |
28 | | |
29 | | /*---------------------------------------------------------------------------- |
30 | | Public Code |
31 | | ----------------------------------------------------------------------------*/ |
32 | | |
33 | | /** |
34 | | * Convert each segment in the outline to a feature |
35 | | * and return the features. |
36 | | * @param Blob blob to extract pico-features from |
37 | | * @return Outline-features for Blob. |
38 | | * @note Globals: none |
39 | | */ |
40 | 1.48k | FEATURE_SET Classify::ExtractOutlineFeatures(TBLOB *Blob) { |
41 | 1.48k | auto FeatureSet = new FEATURE_SET_STRUCT(MAX_OUTLINE_FEATURES); |
42 | 1.48k | if (Blob == nullptr) { |
43 | 0 | return (FeatureSet); |
44 | 0 | } |
45 | | |
46 | 1.48k | auto Outlines = ConvertBlob(Blob); |
47 | | |
48 | 1.48k | float XScale, YScale; |
49 | 1.48k | NormalizeOutlines(Outlines, &XScale, &YScale); |
50 | 1.48k | auto RemainingOutlines = Outlines; |
51 | 2.79k | iterate(RemainingOutlines) { |
52 | 2.79k | auto Outline = static_cast<MFOUTLINE>(RemainingOutlines->first_node()); |
53 | 2.79k | ConvertToOutlineFeatures(Outline, FeatureSet); |
54 | 2.79k | } |
55 | 1.48k | if (classify_norm_method == baseline) { |
56 | 1.48k | NormalizeOutlineX(FeatureSet); |
57 | 1.48k | } |
58 | 1.48k | FreeOutlines(Outlines); |
59 | 1.48k | return (FeatureSet); |
60 | 1.48k | } /* ExtractOutlineFeatures */ |
61 | | |
62 | | /*---------------------------------------------------------------------------- |
63 | | Private Code |
64 | | ----------------------------------------------------------------------------*/ |
65 | | /*---------------------------------------------------------------------------*/ |
66 | | /** |
67 | | * This routine computes the midpoint between Start and |
68 | | * End to obtain the x,y position of the outline-feature. It |
69 | | * also computes the direction from Start to End as the |
70 | | * direction of the outline-feature and the distance from |
71 | | * Start to End as the length of the outline-feature. |
72 | | * This feature is then |
73 | | * inserted into the next feature slot in FeatureSet. |
74 | | * @param Start starting point of outline-feature |
75 | | * @param End ending point of outline-feature |
76 | | * @param FeatureSet set to add outline-feature to |
77 | | */ |
78 | 15.6k | void AddOutlineFeatureToSet(FPOINT *Start, FPOINT *End, FEATURE_SET FeatureSet) { |
79 | 15.6k | auto Feature = new FEATURE_STRUCT(&OutlineFeatDesc); |
80 | 15.6k | Feature->Params[OutlineFeatDir] = NormalizedAngleFrom(Start, End, 1.0); |
81 | 15.6k | Feature->Params[OutlineFeatX] = AverageOf(Start->x, End->x); |
82 | 15.6k | Feature->Params[OutlineFeatY] = AverageOf(Start->y, End->y); |
83 | 15.6k | Feature->Params[OutlineFeatLength] = DistanceBetween(*Start, *End); |
84 | 15.6k | AddFeature(FeatureSet, Feature); |
85 | | |
86 | 15.6k | } /* AddOutlineFeatureToSet */ |
87 | | |
88 | | /*---------------------------------------------------------------------------*/ |
89 | | /** |
90 | | * This routine steps converts each section in the specified |
91 | | * outline to a feature described by its x,y position, length |
92 | | * and angle. |
93 | | * Results are returned in FeatureSet. |
94 | | * @param Outline outline to extract outline-features from |
95 | | * @param FeatureSet set of features to add outline-features to |
96 | | */ |
97 | 2.79k | void ConvertToOutlineFeatures(MFOUTLINE Outline, FEATURE_SET FeatureSet) { |
98 | 2.79k | MFOUTLINE Next; |
99 | 2.79k | MFOUTLINE First; |
100 | 2.79k | FPOINT FeatureStart; |
101 | 2.79k | FPOINT FeatureEnd; |
102 | | |
103 | 2.79k | if (DegenerateOutline(Outline)) { |
104 | 0 | return; |
105 | 0 | } |
106 | | |
107 | 2.79k | First = Outline; |
108 | 2.79k | Next = First; |
109 | 15.6k | do { |
110 | 15.6k | FeatureStart = PointAt(Next)->Point; |
111 | 15.6k | Next = NextPointAfter(Next); |
112 | | |
113 | | /* note that an edge is hidden if the ending point of the edge is |
114 | | marked as hidden. This situation happens because the order of |
115 | | the outlines is reversed when they are converted from the old |
116 | | format. In the old format, a hidden edge is marked by the |
117 | | starting point for that edge. */ |
118 | 15.6k | if (!PointAt(Next)->Hidden) { |
119 | 15.6k | FeatureEnd = PointAt(Next)->Point; |
120 | 15.6k | AddOutlineFeatureToSet(&FeatureStart, &FeatureEnd, FeatureSet); |
121 | 15.6k | } |
122 | 15.6k | } while (Next != First); |
123 | 2.79k | } /* ConvertToOutlineFeatures */ |
124 | | |
125 | | /*---------------------------------------------------------------------------*/ |
126 | | /** |
127 | | * This routine computes the weighted average x position |
128 | | * over all of the outline-features in FeatureSet and then |
129 | | * renormalizes the outline-features to force this average |
130 | | * to be the x origin (i.e. x=0). |
131 | | * FeatureSet is changed. |
132 | | * @param FeatureSet outline-features to be normalized |
133 | | */ |
134 | 1.48k | void NormalizeOutlineX(FEATURE_SET FeatureSet) { |
135 | 1.48k | int i; |
136 | 1.48k | FEATURE Feature; |
137 | 1.48k | float Length; |
138 | 1.48k | float TotalX = 0.0; |
139 | 1.48k | float TotalWeight = 0.0; |
140 | 1.48k | float Origin; |
141 | | |
142 | 1.48k | if (FeatureSet->NumFeatures <= 0) { |
143 | 0 | return; |
144 | 0 | } |
145 | | |
146 | 16.8k | for (i = 0; i < FeatureSet->NumFeatures; i++) { |
147 | 15.3k | Feature = FeatureSet->Features[i]; |
148 | 15.3k | Length = Feature->Params[OutlineFeatLength]; |
149 | 15.3k | TotalX += Feature->Params[OutlineFeatX] * Length; |
150 | 15.3k | TotalWeight += Length; |
151 | 15.3k | } |
152 | 1.48k | Origin = TotalX / TotalWeight; |
153 | | |
154 | 16.8k | for (i = 0; i < FeatureSet->NumFeatures; i++) { |
155 | 15.3k | Feature = FeatureSet->Features[i]; |
156 | 15.3k | Feature->Params[OutlineFeatX] -= Origin; |
157 | 15.3k | } |
158 | 1.48k | } /* NormalizeOutlineX */ |
159 | | |
160 | | } // namespace tesseract |