Tesseract
3.02
|
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 = {static_cast<uinT8>(x), static_cast<uinT8>(y), 00094 0, 0}; 00095 int index = -1; 00096 for (int theta = 0; theta <= MAX_UINT8 && index < 0; ++theta) { 00097 feature.Theta = theta; 00098 index = Index(feature); 00099 } 00100 if (index < 0) { 00101 tprintf("(%d,%d) does not exist in feature space!\n", x, y); 00102 return -1; 00103 } 00104 feature = PositionFromIndex(index); 00105 tprintf("Click at (%d, %d) ->(%d, %d), ->(%d, %d)\n", 00106 x, y, feature.X, feature.Y, x - feature.X, y - feature.Y); 00107 // Get the relative position of x,y from the rounded feature. 00108 x -= feature.X; 00109 y -= feature.Y; 00110 if (x != 0 || y != 0) { 00111 double angle = atan2(static_cast<double>(y), static_cast<double>(x)) + PI; 00112 angle *= kIntFeatureExtent / (2.0 * PI); 00113 feature.Theta = static_cast<uinT8>(angle + 0.5); 00114 index = Index(feature); 00115 if (index < 0) { 00116 tprintf("Feature failed to map to a valid index:"); 00117 feature.print(); 00118 return -1; 00119 } 00120 feature = PositionFromIndex(index); 00121 } 00122 feature.print(); 00123 return index; 00124 } 00125 00126 // Returns an INT_FEATURE_STRUCT corresponding to the given bucket coords. 00127 INT_FEATURE_STRUCT IntFeatureSpace::PositionFromBuckets(int x, 00128 int y, 00129 int theta) const { 00130 INT_FEATURE_STRUCT pos = { 00131 static_cast<uinT8>(ClipToRange( 00132 (x * kIntFeatureExtent + kIntFeatureExtent / 2) / x_buckets_, 00133 0, MAX_UINT8)), 00134 static_cast<uinT8>(ClipToRange( 00135 (y * kIntFeatureExtent + kIntFeatureExtent / 2) / y_buckets_, 00136 0, MAX_UINT8)), 00137 static_cast<uinT8>(ClipToRange( 00138 DivRounded(theta * kIntFeatureExtent, theta_buckets_), 00139 0, MAX_UINT8))}; 00140 return pos; 00141 } 00142 00143 } // namespace tesseract.