Tesseract
3.02
|
00001 /********************************************************************** 00002 * File: feature_chebyshev.cpp 00003 * Description: Implementation of the Chebyshev coefficients Feature Class 00004 * Author: Ahmad Abdulkader 00005 * Created: 2008 00006 * 00007 * (C) Copyright 2008, Google Inc. 00008 ** Licensed under the Apache License, Version 2.0 (the "License"); 00009 ** you may not use this file except in compliance with the License. 00010 ** You may obtain a copy of the License at 00011 ** http://www.apache.org/licenses/LICENSE-2.0 00012 ** Unless required by applicable law or agreed to in writing, software 00013 ** distributed under the License is distributed on an "AS IS" BASIS, 00014 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00015 ** See the License for the specific language governing permissions and 00016 ** limitations under the License. 00017 * 00018 **********************************************************************/ 00019 00020 #include <stdio.h> 00021 #include <stdlib.h> 00022 #include <math.h> 00023 #include <string> 00024 #include <vector> 00025 #include <algorithm> 00026 #include "feature_base.h" 00027 #include "feature_chebyshev.h" 00028 #include "cube_utils.h" 00029 #include "const.h" 00030 #include "char_samp.h" 00031 00032 #ifdef _WIN32 00033 #ifndef M_PI 00034 #define M_PI 3.14159265358979323846 00035 #endif 00036 #endif 00037 00038 namespace tesseract { 00039 00040 FeatureChebyshev::FeatureChebyshev(TuningParams *params) 00041 : FeatureBase(params) { 00042 } 00043 00044 FeatureChebyshev::~FeatureChebyshev() { 00045 } 00046 00047 // Render a visualization of the features to a CharSamp. 00048 // This is mainly used by visual-debuggers 00049 CharSamp *FeatureChebyshev::ComputeFeatureBitmap(CharSamp *char_samp) { 00050 return char_samp; 00051 } 00052 00053 // Compute Chebyshev coefficients for the specified vector 00054 void FeatureChebyshev::ChebyshevCoefficients(const vector<float> &input, 00055 int coeff_cnt, float *coeff) { 00056 // re-sample function 00057 int input_range = (input.size() - 1); 00058 vector<float> resamp(coeff_cnt); 00059 for (int samp_idx = 0; samp_idx < coeff_cnt; samp_idx++) { 00060 // compute sampling position 00061 float samp_pos = input_range * 00062 (1 + cos(M_PI * (samp_idx + 0.5) / coeff_cnt)) / 2; 00063 // interpolate 00064 int samp_start = static_cast<int>(samp_pos); 00065 int samp_end = static_cast<int>(samp_pos + 0.5); 00066 float func_delta = input[samp_end] - input[samp_start]; 00067 resamp[samp_idx] = input[samp_start] + 00068 ((samp_pos - samp_start) * func_delta); 00069 } 00070 // compute the coefficients 00071 float normalizer = 2.0 / coeff_cnt; 00072 for (int coeff_idx = 0; coeff_idx < coeff_cnt; coeff_idx++, coeff++) { 00073 double sum = 0.0; 00074 for (int samp_idx = 0; samp_idx < coeff_cnt; samp_idx++) { 00075 sum += resamp[samp_idx] * cos(M_PI * coeff_idx * (samp_idx + 0.5) / 00076 coeff_cnt); 00077 } 00078 (*coeff) = (normalizer * sum); 00079 } 00080 } 00081 00082 // Compute the features of a given CharSamp 00083 bool FeatureChebyshev::ComputeFeatures(CharSamp *char_samp, float *features) { 00084 return ComputeChebyshevCoefficients(char_samp, features); 00085 } 00086 00087 // Compute the Chebyshev coefficients of a given CharSamp 00088 bool FeatureChebyshev::ComputeChebyshevCoefficients(CharSamp *char_samp, 00089 float *features) { 00090 if (char_samp->NormBottom() <= 0) { 00091 return false; 00092 } 00093 unsigned char *raw_data = char_samp->RawData(); 00094 int stride = char_samp->Stride(); 00095 // compute the height of the word 00096 int word_hgt = (255 * (char_samp->Top() + char_samp->Height()) / 00097 char_samp->NormBottom()); 00098 // compute left & right profiles 00099 vector<float> left_profile(word_hgt, 0.0); 00100 vector<float> right_profile(word_hgt, 0.0); 00101 unsigned char *line_data = raw_data; 00102 for (int y = 0; y < char_samp->Height(); y++, line_data += stride) { 00103 int min_x = char_samp->Width(); 00104 int max_x = -1; 00105 for (int x = 0; x < char_samp->Width(); x++) { 00106 if (line_data[x] == 0) { 00107 UpdateRange(x, &min_x, &max_x); 00108 } 00109 } 00110 left_profile[char_samp->Top() + y] = 00111 1.0 * (min_x == char_samp->Width() ? 0 : (min_x + 1)) / 00112 char_samp->Width(); 00113 right_profile[char_samp->Top() + y] = 00114 1.0 * (max_x == -1 ? 0 : char_samp->Width() - max_x) / 00115 char_samp->Width(); 00116 } 00117 00118 // compute top and bottom profiles 00119 vector<float> top_profile(char_samp->Width(), 0); 00120 vector<float> bottom_profile(char_samp->Width(), 0); 00121 for (int x = 0; x < char_samp->Width(); x++) { 00122 int min_y = word_hgt; 00123 int max_y = -1; 00124 line_data = raw_data; 00125 for (int y = 0; y < char_samp->Height(); y++, line_data += stride) { 00126 if (line_data[x] == 0) { 00127 UpdateRange(y + char_samp->Top(), &min_y, &max_y); 00128 } 00129 } 00130 top_profile[x] = 1.0 * (min_y == word_hgt ? 0 : (min_y + 1)) / word_hgt; 00131 bottom_profile[x] = 1.0 * (max_y == -1 ? 0 : (word_hgt - max_y)) / word_hgt; 00132 } 00133 00134 // compute the chebyshev coefficients of each profile 00135 ChebyshevCoefficients(left_profile, kChebychevCoefficientCnt, features); 00136 ChebyshevCoefficients(top_profile, kChebychevCoefficientCnt, 00137 features + kChebychevCoefficientCnt); 00138 ChebyshevCoefficients(right_profile, kChebychevCoefficientCnt, 00139 features + (2 * kChebychevCoefficientCnt)); 00140 ChebyshevCoefficients(bottom_profile, kChebychevCoefficientCnt, 00141 features + (3 * kChebychevCoefficientCnt)); 00142 return true; 00143 } 00144 } // namespace tesseract