Tesseract  3.02
tesseract-ocr/cube/feature_chebyshev.cpp
Go to the documentation of this file.
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