tesseract
3.03
|
00001 // Copyright 2010 Google Inc. All Rights Reserved. 00002 // Author: rays@google.com (Ray Smith) 00004 // File: intfeaturespace.cpp 00005 // Description: Indexed feature space based on INT_FEATURE_STRUCT. 00006 // Created: Wed Mar 24 11:21:27 PDT 2010 00007 // 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 // 00019 00020 #include "intfeaturespace.h" 00021 #include "intfx.h" 00022 00023 namespace tesseract { 00024 00025 IntFeatureSpace::IntFeatureSpace() 00026 : x_buckets_(0), y_buckets_(0), theta_buckets_(0) { 00027 } 00028 00029 void IntFeatureSpace::Init(uinT8 xbuckets, uinT8 ybuckets, uinT8 thetabuckets) { 00030 x_buckets_ = xbuckets; 00031 y_buckets_ = ybuckets; 00032 theta_buckets_ = thetabuckets; 00033 } 00034 00035 // Serializes the feature space definition to the given file. 00036 // Returns false on error. 00037 bool IntFeatureSpace::Serialize(FILE* fp) const { 00038 if (fwrite(&x_buckets_, sizeof(x_buckets_), 1, fp) != 1) 00039 return false; 00040 if (fwrite(&y_buckets_, sizeof(y_buckets_), 1, fp) != 1) 00041 return false; 00042 if (fwrite(&theta_buckets_, sizeof(theta_buckets_), 1, fp) != 1) 00043 return false; 00044 return true; 00045 } 00046 00047 // DeSerializes the feature space definition from the given file. 00048 // If swap is true, the data is big/little-endian swapped. 00049 // Returns false on error. 00050 bool IntFeatureSpace::DeSerialize(bool swap, FILE* fp) { 00051 if (fread(&x_buckets_, sizeof(x_buckets_), 1, fp) != 1) 00052 return false; 00053 if (fread(&y_buckets_, sizeof(y_buckets_), 1, fp) != 1) 00054 return false; 00055 if (fread(&theta_buckets_, sizeof(theta_buckets_), 1, fp) != 1) 00056 return false; 00057 return true; 00058 } 00059 00060 // Returns an INT_FEATURE_STRUCT corresponding to the given index. 00061 // This is the inverse of the Index member. 00062 INT_FEATURE_STRUCT IntFeatureSpace::PositionFromIndex(int index) const { 00063 return PositionFromBuckets(index / (y_buckets_ * theta_buckets_), 00064 index / theta_buckets_ % y_buckets_, 00065 index % theta_buckets_); 00066 } 00067 00068 // Bulk calls to Index. Maps the given array of features to a vector of 00069 // inT32 indices in the same order as the input. 00070 void IntFeatureSpace::IndexFeatures(const INT_FEATURE_STRUCT* features, 00071 int num_features, 00072 GenericVector<int>* mapped_features) const { 00073 mapped_features->truncate(0); 00074 for (int f = 0; f < num_features; ++f) 00075 mapped_features->push_back(Index(features[f])); 00076 } 00077 00078 // Bulk calls to Index. Maps the given array of features to a vector of 00079 // sorted inT32 indices. 00080 void IntFeatureSpace::IndexAndSortFeatures( 00081 const INT_FEATURE_STRUCT* features, int num_features, 00082 GenericVector<int>* sorted_features) const { 00083 sorted_features->truncate(0); 00084 for (int f = 0; f < num_features; ++f) 00085 sorted_features->push_back(Index(features[f])); 00086 sorted_features->sort(); 00087 } 00088 00089 // Returns a feature space index for the given x,y position in a display 00090 // window, or -1 if the feature is a miss. 00091 int IntFeatureSpace::XYToFeatureIndex(int x, int y) const { 00092 // Round the x,y position to a feature. Search for a valid theta. 00093 INT_FEATURE_STRUCT feature(x, y, 0); 00094 int index = -1; 00095 for (int theta = 0; theta <= MAX_UINT8 && index < 0; ++theta) { 00096 feature.Theta = theta; 00097 index = Index(feature); 00098 } 00099 if (index < 0) { 00100 tprintf("(%d,%d) does not exist in feature space!\n", x, y); 00101 return -1; 00102 } 00103 feature = PositionFromIndex(index); 00104 tprintf("Click at (%d, %d) ->(%d, %d), ->(%d, %d)\n", 00105 x, y, feature.X, feature.Y, x - feature.X, y - feature.Y); 00106 // Get the relative position of x,y from the rounded feature. 00107 x -= feature.X; 00108 y -= feature.Y; 00109 if (x != 0 || y != 0) { 00110 double angle = atan2(static_cast<double>(y), static_cast<double>(x)) + PI; 00111 angle *= kIntFeatureExtent / (2.0 * PI); 00112 feature.Theta = static_cast<uinT8>(angle + 0.5); 00113 index = Index(feature); 00114 if (index < 0) { 00115 tprintf("Feature failed to map to a valid index:"); 00116 feature.print(); 00117 return -1; 00118 } 00119 feature = PositionFromIndex(index); 00120 } 00121 feature.print(); 00122 return index; 00123 } 00124 00125 // Returns an INT_FEATURE_STRUCT corresponding to the given bucket coords. 00126 INT_FEATURE_STRUCT IntFeatureSpace::PositionFromBuckets(int x, 00127 int y, 00128 int theta) const { 00129 INT_FEATURE_STRUCT pos( 00130 (x * kIntFeatureExtent + kIntFeatureExtent / 2) / x_buckets_, 00131 (y * kIntFeatureExtent + kIntFeatureExtent / 2) / y_buckets_, 00132 DivRounded(theta * kIntFeatureExtent, theta_buckets_)); 00133 return pos; 00134 } 00135 00136 } // namespace tesseract.