Tesseract 3.02

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
feature_chebyshev.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 * File: feature_chebyshev.cpp
3 * Description: Implementation of the Chebyshev coefficients Feature Class
4 * Author: Ahmad Abdulkader
5 * Created: 2008
6 *
7 * (C) Copyright 2008, Google Inc.
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
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <math.h>
23 #include <string>
24 #include <vector>
25 #include <algorithm>
26 #include "feature_base.h"
27 #include "feature_chebyshev.h"
28 #include "cube_utils.h"
29 #include "const.h"
30 #include "char_samp.h"
31
32 #ifdef _WIN32
33 #ifndef M_PI
34 #define M_PI 3.14159265358979323846
35 #endif
36 #endif
37
38 namespace tesseract {
39
40 FeatureChebyshev::FeatureChebyshev(TuningParams *params)
41 : FeatureBase(params) {
42 }
43
44 FeatureChebyshev::~FeatureChebyshev() {
45 }
46
47 // Render a visualization of the features to a CharSamp.
48 // This is mainly used by visual-debuggers
49 CharSamp *FeatureChebyshev::ComputeFeatureBitmap(CharSamp *char_samp) {
50 return char_samp;
51 }
52
53 // Compute Chebyshev coefficients for the specified vector
54 void FeatureChebyshev::ChebyshevCoefficients(const vector<float> &input,
55 int coeff_cnt, float *coeff) {
56 // re-sample function
57 int input_range = (input.size() - 1);
58 vector<float> resamp(coeff_cnt);
59 for (int samp_idx = 0; samp_idx < coeff_cnt; samp_idx++) {
60 // compute sampling position
61 float samp_pos = input_range *
62 (1 + cos(M_PI * (samp_idx + 0.5) / coeff_cnt)) / 2;
63 // interpolate
64 int samp_start = static_cast<int>(samp_pos);
65 int samp_end = static_cast<int>(samp_pos + 0.5);
66 float func_delta = input[samp_end] - input[samp_start];
67 resamp[samp_idx] = input[samp_start] +
68 ((samp_pos - samp_start) * func_delta);
69 }
70 // compute the coefficients
71 float normalizer = 2.0 / coeff_cnt;
72 for (int coeff_idx = 0; coeff_idx < coeff_cnt; coeff_idx++, coeff++) {
73 double sum = 0.0;
74 for (int samp_idx = 0; samp_idx < coeff_cnt; samp_idx++) {
75 sum += resamp[samp_idx] * cos(M_PI * coeff_idx * (samp_idx + 0.5) /
76 coeff_cnt);
77 }
78 (*coeff) = (normalizer * sum);
79 }
80 }
81
82 // Compute the features of a given CharSamp
83 bool FeatureChebyshev::ComputeFeatures(CharSamp *char_samp, float *features) {
84 return ComputeChebyshevCoefficients(char_samp, features);
85 }
86
87 // Compute the Chebyshev coefficients of a given CharSamp
88 bool FeatureChebyshev::ComputeChebyshevCoefficients(CharSamp *char_samp,
89 float *features) {
90 if (char_samp->NormBottom() <= 0) {
91 return false;
92 }
93 unsigned char *raw_data = char_samp->RawData();
94 int stride = char_samp->Stride();
95 // compute the height of the word
96 int word_hgt = (255 * (char_samp->Top() + char_samp->Height()) /
97 char_samp->NormBottom());
98 // compute left & right profiles
99 vector<float> left_profile(word_hgt, 0.0);
100 vector<float> right_profile(word_hgt, 0.0);
101 unsigned char *line_data = raw_data;
102 for (int y = 0; y < char_samp->Height(); y++, line_data += stride) {
103 int min_x = char_samp->Width();
104 int max_x = -1;
105 for (int x = 0; x < char_samp->Width(); x++) {
106 if (line_data[x] == 0) {
107 UpdateRange(x, &min_x, &max_x);
108 }
109 }
110 left_profile[char_samp->Top() + y] =
111 1.0 * (min_x == char_samp->Width() ? 0 : (min_x + 1)) /
112 char_samp->Width();
113 right_profile[char_samp->Top() + y] =
114 1.0 * (max_x == -1 ? 0 : char_samp->Width() - max_x) /
115 char_samp->Width();
116 }
117
118 // compute top and bottom profiles
119 vector<float> top_profile(char_samp->Width(), 0);
120 vector<float> bottom_profile(char_samp->Width(), 0);
121 for (int x = 0; x < char_samp->Width(); x++) {
122 int min_y = word_hgt;
123 int max_y = -1;
124 line_data = raw_data;
125 for (int y = 0; y < char_samp->Height(); y++, line_data += stride) {
126 if (line_data[x] == 0) {
127 UpdateRange(y + char_samp->Top(), &min_y, &max_y);
128 }
129 }
130 top_profile[x] = 1.0 * (min_y == word_hgt ? 0 : (min_y + 1)) / word_hgt;
131 bottom_profile[x] = 1.0 * (max_y == -1 ? 0 : (word_hgt - max_y)) / word_hgt;
132 }
133
134 // compute the chebyshev coefficients of each profile
135 ChebyshevCoefficients(left_profile, kChebychevCoefficientCnt, features);
136 ChebyshevCoefficients(top_profile, kChebychevCoefficientCnt,
137 features + kChebychevCoefficientCnt);
138 ChebyshevCoefficients(right_profile, kChebychevCoefficientCnt,
139 features + (2 * kChebychevCoefficientCnt));
140 ChebyshevCoefficients(bottom_profile, kChebychevCoefficientCnt,
141 features + (3 * kChebychevCoefficientCnt));
142 return true;
143 }
144 } // namespace tesseract