12 #include <allheaders.h>
15 #include "absl/strings/str_format.h"
39 class TextlineProjectionTest :
public testing::Test {
45 TextlineProjectionTest() {
51 projection_ =
nullptr;
53 virtual ~TextlineProjectionTest() {
54 pixDestroy(&src_pix_);
55 pixDestroy(&bin_pix_);
60 void SetImage(
const char* filename) {
61 pixDestroy(&src_pix_);
65 api_.SetImage(src_pix_);
75 void SetupProjection() {
77 Tesseract* osd_tess =
new Tesseract;
79 EXPECT_EQ(osd_tess->init_tesseract(TESSDATA_DIR,
nullptr,
"osd",
81 nullptr,
nullptr,
false, &mgr),
83 tesseract_ =
new Tesseract;
84 EXPECT_EQ(tesseract_->init_tesseract(TESSDATA_DIR,
nullptr,
"eng",
86 nullptr,
nullptr,
false, &mgr),
88 bin_pix_ = api_.GetThresholdedImage();
89 *tesseract_->mutable_pix_binary() = pixClone(bin_pix_);
90 osd_tess->set_source_resolution(api_.tesseract()->source_resolution());
91 tesseract_->set_source_resolution(api_.tesseract()->source_resolution());
92 int width = pixGetWidth(bin_pix_);
93 int height = pixGetHeight(bin_pix_);
95 BLOCK* block =
new BLOCK(
"",
true, 0, 0, 0, 0, width, height);
97 BLOCK_LIST src_blocks;
98 BLOCK_IT block_it(&src_blocks);
99 block_it.add_to_end(block);
100 Pix* photomask_pix =
nullptr;
102 BLOCK_LIST found_blocks;
103 TO_BLOCK_LIST temp_blocks;
104 finder_ = tesseract_->SetupPageSegAndDetectOrientation(
106 &photomask_pix,
nullptr);
107 TO_BLOCK_IT to_block_it(&temp_blocks);
108 TO_BLOCK* to_block = to_block_it.data();
109 denorm_ = finder_->denorm();
110 TO_BLOCK_LIST to_blocks;
111 BLOBNBOX_LIST diacritic_blobs;
113 photomask_pix,
nullptr,
nullptr,
nullptr,
114 &found_blocks, &diacritic_blobs, &to_blocks),
116 projection_ = finder_->projection();
117 pixDestroy(&photomask_pix);
123 void EvaluateBox(
const TBOX& box,
bool greater_or_equal,
int target_value,
124 const char* text,
const char* message) {
125 int value = projection_->EvaluateBox(box, denorm_,
false);
126 if (greater_or_equal != (value > target_value)) {
128 "EvaluateBox too %s:%d vs %d for %s word '%s' at:",
129 greater_or_equal ?
"low" :
"high", value, target_value, message,
132 value = projection_->EvaluateBox(box, denorm_,
true);
134 LOG(
INFO) << absl::StrFormat(
"EvaluateBox OK(%d) for %s word '%s'",
135 value, message, text);
137 if (greater_or_equal) {
138 EXPECT_GE(value, target_value);
140 EXPECT_LT(value, target_value);
146 void EvaluateDistance(
const TBOX& box,
const TBOX& true_box,
147 const TBOX& false_box,
const char* text,
148 const char* message) {
150 projection_->DistanceOfBoxFromBox(box, true_box,
true, denorm_,
false);
152 projection_->DistanceOfBoxFromBox(box, false_box,
true, denorm_,
false);
153 if (false_dist <= true_dist) {
155 "Distance wrong:%d vs %d for %s word '%s' at:",
156 false_dist, true_dist, message, text);
158 projection_->DistanceOfBoxFromBox(box, true_box,
true, denorm_,
true);
159 projection_->DistanceOfBoxFromBox(box, false_box,
true, denorm_,
true);
161 LOG(
INFO) << absl::StrFormat(
"Distance OK(%d vs %d) for %s word '%s'",
162 false_dist, true_dist, message, text);
168 void VerifyBoxes(
const char* imagefile,
int line_height) {
170 api_.Recognize(
nullptr);
172 MutableIterator* it = api_.GetMutableIterator();
179 bool small_word = word_box.
height() * 1.5 < line_height;
180 bool tall_word = word_box.
height() * 1.125 > line_height;
185 padding = word_box.
height();
186 }
else if (tall_word) {
187 padding = word_box.
height() / 3;
189 padding = word_box.
height() / 2;
195 TBOX upper_box(word_box);
196 upper_box.set_bottom(word_box.
top());
197 upper_box.set_top(word_box.
top() + padding);
199 EvaluateBox(upper_box,
true, -1, text,
"Upper Word not vertical");
200 TBOX lower_box = word_box;
203 if (tall_word) lower_box.
move(
ICOORD(0, padding / 2));
205 EvaluateBox(lower_box,
true, -1, text,
"Lower Word not vertical");
209 bool upper_or_lower_out_of_textline =
210 projection_->BoxOutOfHTextline(upper_box, denorm_,
false) ||
211 projection_->BoxOutOfHTextline(lower_box, denorm_,
false);
212 if (!upper_or_lower_out_of_textline) {
213 projection_->BoxOutOfHTextline(upper_box, denorm_,
true);
214 projection_->BoxOutOfHTextline(lower_box, denorm_,
true);
216 EXPECT_TRUE(upper_or_lower_out_of_textline);
222 padding = line_height / 4;
223 upper_box.set_top(upper_box.bottom() + padding);
224 TBOX target_box(word_box);
226 upper_box.move(
ICOORD(0, -padding * 3 / 2));
228 target_box.set_top(upper_box.bottom());
229 TBOX upper_challenger(upper_box);
230 upper_challenger.set_bottom(upper_box.top());
231 upper_challenger.set_top(upper_box.top() + word_box.
height());
232 EvaluateDistance(upper_box, target_box, upper_challenger, text,
234 if (tall_word) lower_box.
move(
ICOORD(0, padding / 2));
236 target_box = word_box;
238 TBOX lower_challenger(lower_box);
239 lower_challenger.set_top(lower_box.
bottom());
240 lower_challenger.set_bottom(lower_box.
bottom() - word_box.
height());
241 EvaluateDistance(lower_box, target_box, lower_challenger, text,
254 Tesseract* tesseract_;
255 ColumnFinder* finder_;
257 const TextlineProjection* projection_;
261 TEST_F(TextlineProjectionTest, Unrotated) { VerifyBoxes(
"phototest.tif", 31); }
264 TEST_F(TextlineProjectionTest, Rotated) { VerifyBoxes(
"phototestrot.tif", 31); }