tesseract  5.0.0
networkio_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 "networkio.h"
13 #include "include_gunit.h"
14 #include "stridemap.h"
15 #ifdef INCLUDE_TENSORFLOW
16 # include <tensorflow/compiler/xla/array2d.h> // for xla::Array2D
17 #endif
18 
19 namespace tesseract {
20 
21 class NetworkioTest : public ::testing::Test {
22 protected:
23  void SetUp() override {
24  std::locale::global(std::locale(""));
25  }
26 
27 #ifdef INCLUDE_TENSORFLOW
28  // Sets up an Array2d object of the given size, initialized to increasing
29  // values starting with start.
30  std::unique_ptr<xla::Array2D<int>> SetupArray(int ysize, int xsize, int start) {
31  std::unique_ptr<xla::Array2D<int>> a(new xla::Array2D<int>(ysize, xsize));
32  int value = start;
33  for (int y = 0; y < ysize; ++y) {
34  for (int x = 0; x < xsize; ++x) {
35  (*a)(y, x) = value++;
36  }
37  }
38  return a;
39  }
40  // Sets up a NetworkIO with a batch of 2 "images" of known values.
41  void SetupNetworkIO(NetworkIO *nio) {
42  std::vector<std::unique_ptr<xla::Array2D<int>>> arrays;
43  arrays.push_back(SetupArray(3, 4, 0));
44  arrays.push_back(SetupArray(4, 5, 12));
45  std::vector<std::pair<int, int>> h_w_sizes;
46  for (size_t i = 0; i < arrays.size(); ++i) {
47  h_w_sizes.emplace_back(arrays[i].get()->height(), arrays[i].get()->width());
48  }
49  StrideMap stride_map;
50  stride_map.SetStride(h_w_sizes);
51  nio->ResizeToMap(true, stride_map, 2);
52  // Iterate over the map, setting nio's contents from the arrays.
53  StrideMap::Index index(stride_map);
54  do {
55  int value = (*arrays[index.index(FD_BATCH)])(index.index(FD_HEIGHT), index.index(FD_WIDTH));
56  nio->SetPixel(index.t(), 0, 128 + value, 0.0f, 128.0f);
57  nio->SetPixel(index.t(), 1, 128 - value, 0.0f, 128.0f);
58  } while (index.Increment());
59  }
60 #endif
61 };
62 
63 // Tests that the initialization via SetPixel works and the resize correctly
64 // fills with zero where image sizes don't match.
65 TEST_F(NetworkioTest, InitWithZeroFill) {
66 #ifdef INCLUDE_TENSORFLOW
67  NetworkIO nio;
68  nio.Resize2d(true, 32, 2);
69  int width = nio.Width();
70  for (int t = 0; t < width; ++t) {
71  nio.SetPixel(t, 0, 0, 0.0f, 128.0f);
72  nio.SetPixel(t, 1, 0, 0.0f, 128.0f);
73  }
74  // The initialization will wipe out all previously set values.
75  SetupNetworkIO(&nio);
76  nio.ZeroInvalidElements();
77  StrideMap::Index index(nio.stride_map());
78  int next_t = 0;
79  int pos = 0;
80  do {
81  int t = index.t();
82  // The indexed values just increase monotonically.
83  int value = nio.i(t)[0];
84  EXPECT_EQ(value, pos);
85  value = nio.i(t)[1];
86  EXPECT_EQ(value, -pos);
87  // When we skip t values, the data is always 0.
88  while (next_t < t) {
89  EXPECT_EQ(nio.i(next_t)[0], 0);
90  EXPECT_EQ(nio.i(next_t)[1], 0);
91  ++next_t;
92  }
93  ++pos;
94  ++next_t;
95  } while (index.Increment());
96  EXPECT_EQ(pos, 32);
97  EXPECT_EQ(next_t, 40);
98 #else
99  LOG(INFO) << "Skip test because of missing xla::Array2D";
100  GTEST_SKIP();
101 #endif
102 }
103 
104 // Tests that CopyWithYReversal works.
105 TEST_F(NetworkioTest, CopyWithYReversal) {
106 #ifdef INCLUDE_TENSORFLOW
107  NetworkIO nio;
108  SetupNetworkIO(&nio);
109  NetworkIO copy;
110  copy.CopyWithYReversal(nio);
111  StrideMap::Index index(copy.stride_map());
112  int next_t = 0;
113  int pos = 0;
114  std::vector<int> expected_values = {8, 9, 10, 11, 4, 5, 6, 7, 0, 1, 2,
115  3, 27, 28, 29, 30, 31, 22, 23, 24, 25, 26,
116  17, 18, 19, 20, 21, 12, 13, 14, 15, 16};
117  do {
118  int t = index.t();
119  // The indexed values match the expected values.
120  int value = copy.i(t)[0];
121  EXPECT_EQ(value, expected_values[pos]);
122  value = copy.i(t)[1];
123  EXPECT_EQ(value, -expected_values[pos]);
124  // When we skip t values, the data is always 0.
125  while (next_t < t) {
126  EXPECT_EQ(copy.i(next_t)[0], 0) << "Failure t = " << next_t;
127  EXPECT_EQ(copy.i(next_t)[1], 0) << "Failure t = " << next_t;
128  ++next_t;
129  }
130  ++pos;
131  ++next_t;
132  } while (index.Increment());
133  EXPECT_EQ(pos, 32);
134  EXPECT_EQ(next_t, 40);
135 #else
136  LOG(INFO) << "Skip test because of missing xla::Array2D";
137  GTEST_SKIP();
138 #endif
139 }
140 
141 // Tests that CopyWithXReversal works.
142 TEST_F(NetworkioTest, CopyWithXReversal) {
143 #ifdef INCLUDE_TENSORFLOW
144  NetworkIO nio;
145  SetupNetworkIO(&nio);
146  NetworkIO copy;
147  copy.CopyWithXReversal(nio);
148  StrideMap::Index index(copy.stride_map());
149  int next_t = 0;
150  int pos = 0;
151  std::vector<int> expected_values = {3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9,
152  8, 16, 15, 14, 13, 12, 21, 20, 19, 18, 17,
153  26, 25, 24, 23, 22, 31, 30, 29, 28, 27};
154  do {
155  int t = index.t();
156  // The indexed values match the expected values.
157  int value = copy.i(t)[0];
158  EXPECT_EQ(value, expected_values[pos]);
159  value = copy.i(t)[1];
160  EXPECT_EQ(value, -expected_values[pos]);
161  // When we skip t values, the data is always 0.
162  while (next_t < t) {
163  EXPECT_EQ(copy.i(next_t)[0], 0) << "Failure t = " << next_t;
164  EXPECT_EQ(copy.i(next_t)[1], 0) << "Failure t = " << next_t;
165  ++next_t;
166  }
167  ++pos;
168  ++next_t;
169  } while (index.Increment());
170  EXPECT_EQ(pos, 32);
171  EXPECT_EQ(next_t, 40);
172 #else
173  LOG(INFO) << "Skip test because of missing xla::Array2D";
174  GTEST_SKIP();
175 #endif
176 }
177 
178 // Tests that CopyWithXYTranspose works.
179 TEST_F(NetworkioTest, CopyWithXYTranspose) {
180 #ifdef INCLUDE_TENSORFLOW
181  NetworkIO nio;
182  SetupNetworkIO(&nio);
183  NetworkIO copy;
184  copy.CopyWithXYTranspose(nio);
185  StrideMap::Index index(copy.stride_map());
186  int next_t = 0;
187  int pos = 0;
188  std::vector<int> expected_values = {0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7,
189  11, 12, 17, 22, 27, 13, 18, 23, 28, 14, 19,
190  24, 29, 15, 20, 25, 30, 16, 21, 26, 31};
191  do {
192  int t = index.t();
193  // The indexed values match the expected values.
194  int value = copy.i(t)[0];
195  EXPECT_EQ(value, expected_values[pos]);
196  value = copy.i(t)[1];
197  EXPECT_EQ(value, -expected_values[pos]);
198  // When we skip t values, the data is always 0.
199  while (next_t < t) {
200  EXPECT_EQ(copy.i(next_t)[0], 0);
201  EXPECT_EQ(copy.i(next_t)[1], 0);
202  ++next_t;
203  }
204  ++pos;
205  ++next_t;
206  } while (index.Increment());
207  EXPECT_EQ(pos, 32);
208  EXPECT_EQ(next_t, 40);
209 #else
210  LOG(INFO) << "Skip test because of missing xla::Array2D";
211  GTEST_SKIP();
212 #endif
213 }
214 
215 } // namespace tesseract
@ LOG
@ INFO
Definition: log.h:28
@ FD_WIDTH
Definition: stridemap.h:35
@ FD_BATCH
Definition: stridemap.h:33
@ FD_HEIGHT
Definition: stridemap.h:34
TEST_F(EuroText, FastLatinOCR)
void ZeroInvalidElements()
Definition: networkio.cpp:86
const StrideMap & stride_map() const
Definition: networkio.h:129
const int8_t * i(int t) const
Definition: networkio.h:119
void CopyWithXReversal(const NetworkIO &src)
Definition: networkio.cpp:897
void CopyWithXYTranspose(const NetworkIO &src)
Definition: networkio.cpp:915
int Width() const
Definition: networkio.h:103
void Resize2d(bool int_mode, int width, int num_features)
Definition: networkio.cpp:35
void CopyWithYReversal(const NetworkIO &src)
Definition: networkio.cpp:877
void SetPixel(int t, int f, int pixel, float black, float contrast)
Definition: networkio.cpp:290