tesseract  5.0.0-alpha-619-ge9db
intfeaturemap_test.cc
Go to the documentation of this file.
1 // (C) Copyright 2017, Google Inc.
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 // http://www.apache.org/licenses/LICENSE-2.0
6 // Unless required by applicable law or agreed to in writing, software
7 // distributed under the License is distributed on an "AS IS" BASIS,
8 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9 // See the License for the specific language governing permissions and
10 // limitations under the License.
11 
12 #include "intfeaturemap.h"
13 #include "intfeaturespace.h"
14 
15 #include "include_gunit.h"
16 
19 
20 // Random re-quantization to test that they don't have to be easy.
21 // WARNING! Change these and change the expected_misses calculation below.
22 const int kXBuckets = 16;
23 const int kYBuckets = 24;
24 const int kThetaBuckets = 13;
25 
26 namespace {
27 
28 class IntFeatureMapTest : public testing::Test {
29  protected:
30  void SetUp() {
31  std::locale::global(std::locale(""));
32  }
33 
34  public:
35  // Expects that the given vector has contiguous integer values in the
36  // range [start, end).
37  void ExpectContiguous(const GenericVector<int>& v, int start, int end) {
38  for (int i = start; i < end; ++i) {
39  EXPECT_EQ(i, v[i - start]);
40  }
41  }
42 };
43 
44 // Tests the IntFeatureMap and implicitly the IntFeatureSpace underneath.
45 TEST_F(IntFeatureMapTest, Exhaustive) {
46 #ifdef DISABLED_LEGACY_ENGINE
47  // Skip test because IntFeatureSpace is missing.
48  GTEST_SKIP();
49 #else
50  IntFeatureSpace space;
52  IntFeatureMap map;
53  map.Init(space);
55  std::unique_ptr<INT_FEATURE_STRUCT[]> features(
56  new INT_FEATURE_STRUCT[total_size]);
57  // Fill the features with every value.
58  for (int y = 0; y < kIntFeatureExtent; ++y) {
59  for (int x = 0; x < kIntFeatureExtent; ++x) {
60  for (int theta = 0; theta < kIntFeatureExtent; ++theta) {
61  int f_index = (y * kIntFeatureExtent + x) * kIntFeatureExtent + theta;
62  features[f_index].X = x;
63  features[f_index].Y = y;
64  features[f_index].Theta = theta;
65  }
66  }
67  }
68  GenericVector<int> index_features;
69  map.IndexAndSortFeatures(features.get(), total_size, &index_features);
70  EXPECT_EQ(total_size, index_features.size());
71  int total_buckets = kXBuckets * kYBuckets * kThetaBuckets;
72  GenericVector<int> map_features;
73  int misses = map.MapIndexedFeatures(index_features, &map_features);
74  EXPECT_EQ(0, misses);
75  EXPECT_EQ(total_buckets, map_features.size());
76  ExpectContiguous(map_features, 0, total_buckets);
77  EXPECT_EQ(total_buckets, map.compact_size());
78  EXPECT_EQ(total_buckets, map.sparse_size());
79 
80  // Every offset should be within dx, dy, dtheta of the start point.
81  int dx = kIntFeatureExtent / kXBuckets + 1;
82  int dy = kIntFeatureExtent / kYBuckets + 1;
83  int dtheta = kIntFeatureExtent / kThetaBuckets + 1;
84  int bad_offsets = 0;
85  for (int index = 0; index < total_buckets; ++index) {
86  for (int dir = -tesseract::kNumOffsetMaps; dir <= tesseract::kNumOffsetMaps;
87  ++dir) {
88  int offset_index = map.OffsetFeature(index, dir);
89  if (dir == 0) {
90  EXPECT_EQ(index, offset_index);
91  } else if (offset_index >= 0) {
93  INT_FEATURE_STRUCT f2 = map.InverseIndexFeature(offset_index);
94  EXPECT_TRUE(f.X != f2.X || f.Y != f2.Y || f.Theta != f2.Theta);
95  EXPECT_LE(abs(f.X - f2.X), dx);
96  EXPECT_LE(abs(f.Y - f2.Y), dy);
97  int theta_delta = abs(f.Theta - f2.Theta);
98  if (theta_delta > kIntFeatureExtent / 2)
99  theta_delta = kIntFeatureExtent - theta_delta;
100  EXPECT_LE(theta_delta, dtheta);
101  } else {
102  ++bad_offsets;
104  }
105  }
106  }
107  EXPECT_LE(bad_offsets, (kXBuckets + kYBuckets) * kThetaBuckets);
108 
109  // To test the mapping further, delete the 1st and last map feature, and
110  // test again.
111  map.DeleteMapFeature(0);
112  map.DeleteMapFeature(total_buckets - 1);
113  map.FinalizeMapping(nullptr);
114  map.IndexAndSortFeatures(features.get(), total_size, &index_features);
115  // Has no effect on index features.
116  EXPECT_EQ(total_size, index_features.size());
117  misses = map.MapIndexedFeatures(index_features, &map_features);
118  int expected_misses = (kIntFeatureExtent / kXBuckets) *
121  expected_misses += (kIntFeatureExtent / kXBuckets) *
122  (kIntFeatureExtent / kYBuckets + 1) *
124  EXPECT_EQ(expected_misses, misses);
125  EXPECT_EQ(total_buckets - 2, map_features.size());
126  ExpectContiguous(map_features, 0, total_buckets - 2);
127  EXPECT_EQ(total_buckets - 2, map.compact_size());
128  EXPECT_EQ(total_buckets, map.sparse_size());
129 #endif
130 }
131 
132 } // namespace.
tesseract::IntFeatureMap::IndexAndSortFeatures
void IndexAndSortFeatures(const INT_FEATURE_STRUCT *features, int num_features, GenericVector< int > *sorted_features) const
Definition: intfeaturemap.h:104
tesseract::IntFeatureMap::DeleteMapFeature
void DeleteMapFeature(int map_feature)
Definition: intfeaturemap.cpp:63
kThetaBuckets
const int kThetaBuckets
Definition: intfeaturemap_test.cc:24
INT_FEATURE_STRUCT::Theta
uint8_t Theta
Definition: intproto.h:141
tesseract::IntFeatureMap::FinalizeMapping
int FinalizeMapping(SampleIterator *it)
Definition: intfeaturemap.cpp:159
tesseract::IntFeatureMap::Init
void Init(const IntFeatureSpace &feature_space)
Definition: intfeaturemap.cpp:73
tesseract::IntFeatureMap::InverseIndexFeature
INT_FEATURE_STRUCT InverseIndexFeature(int index_feature) const
Definition: intfeaturemap.cpp:56
intfeaturespace.h
include_gunit.h
tesseract::TEST_F
TEST_F(EquationFinderTest, IdentifySpecialText)
Definition: equationdetect_test.cc:181
tesseract::IntFeatureMap::OffsetFeature
int OffsetFeature(int index_feature, int dir) const
Definition: intfeaturemap.cpp:113
tesseract::IntFeatureSpace::Init
void Init(uint8_t xbuckets, uint8_t ybuckets, uint8_t thetabuckets)
Definition: intfeaturespace.cpp:30
kXBuckets
const int kXBuckets
Definition: intfeaturemap_test.cc:22
INT_FEATURE_STRUCT::Y
uint8_t Y
Definition: intproto.h:140
kYBuckets
const int kYBuckets
Definition: intfeaturemap_test.cc:23
GenericVector< int >
tesseract::IntFeatureSpace
Definition: intfeaturespace.h:38
tesseract::IntFeatureMap::compact_size
int compact_size() const
Definition: intfeaturemap.h:57
INT_FEATURE_STRUCT
Definition: intproto.h:131
tesseract::IntFeatureMap
Definition: intfeaturemap.h:48
tesseract::IntFeatureMap::MapIndexedFeatures
int MapIndexedFeatures(const GenericVector< int > &index_features, GenericVector< int > *map_features) const
Definition: intfeaturemap.h:115
tesseract::IntFeatureMap::sparse_size
int sparse_size() const
Definition: intfeaturemap.h:54
INT_FEATURE_STRUCT::X
uint8_t X
Definition: intproto.h:139
GenericVector::size
int size() const
Definition: genericvector.h:71
kIntFeatureExtent
const int kIntFeatureExtent
Definition: intfeaturespace.h:27
intfeaturemap.h