2018-08-29 03:03:49 +08:00
|
|
|
// (C) Copyright 2017, Google Inc.
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
2018-08-24 21:07:48 +08:00
|
|
|
|
2021-02-13 17:17:20 +08:00
|
|
|
#include <allheaders.h>
|
2019-10-30 01:01:18 +08:00
|
|
|
#include <tesseract/baseapi.h>
|
2021-03-13 05:06:34 +08:00
|
|
|
#include <tesseract/resultiterator.h>
|
|
|
|
#include <string>
|
2018-08-29 03:03:49 +08:00
|
|
|
#include "boxread.h"
|
|
|
|
#include "rect.h"
|
|
|
|
|
|
|
|
#include "include_gunit.h"
|
2018-08-24 21:07:48 +08:00
|
|
|
|
2020-12-27 17:41:48 +08:00
|
|
|
namespace tesseract {
|
2018-08-24 21:07:48 +08:00
|
|
|
|
2021-03-13 05:06:34 +08:00
|
|
|
const char *kTruthTextWords = "To simple burn running of goods lately.\n";
|
|
|
|
const char *kTruthTextLine = "Tosimpleburnrunningofgoodslately.\n";
|
2018-08-24 21:07:48 +08:00
|
|
|
|
|
|
|
// The fixture for testing Tesseract.
|
|
|
|
class ApplyBoxTest : public testing::Test {
|
2021-03-13 05:06:34 +08:00
|
|
|
protected:
|
|
|
|
std::string TestDataNameToPath(const std::string &name) {
|
2018-08-29 03:03:49 +08:00
|
|
|
return file::JoinPath(TESTING_DIR, name);
|
2018-08-24 21:07:48 +08:00
|
|
|
}
|
2021-03-13 05:06:34 +08:00
|
|
|
std::string TessdataPath() {
|
|
|
|
return TESSDATA_DIR;
|
|
|
|
}
|
2018-08-24 21:07:48 +08:00
|
|
|
|
2021-03-13 05:06:34 +08:00
|
|
|
ApplyBoxTest() {
|
|
|
|
src_pix_ = nullptr;
|
|
|
|
}
|
2021-03-22 15:26:05 +08:00
|
|
|
~ApplyBoxTest() override {
|
2021-04-01 03:39:43 +08:00
|
|
|
src_pix_.destroy();
|
2021-03-13 05:06:34 +08:00
|
|
|
}
|
2018-08-24 21:07:48 +08:00
|
|
|
|
2021-03-13 05:06:34 +08:00
|
|
|
bool SetImage(const char *filename) {
|
2019-01-24 23:10:52 +08:00
|
|
|
bool found = false;
|
2021-04-01 03:39:43 +08:00
|
|
|
src_pix_.destroy();
|
2018-08-24 21:07:48 +08:00
|
|
|
src_pix_ = pixRead(TestDataNameToPath(filename).c_str());
|
2019-01-24 23:10:52 +08:00
|
|
|
if (api_.Init(TessdataPath().c_str(), "eng", tesseract::OEM_TESSERACT_ONLY) != -1) {
|
|
|
|
api_.SetPageSegMode(tesseract::PSM_SINGLE_BLOCK);
|
|
|
|
api_.SetImage(src_pix_);
|
|
|
|
api_.SetVariable("tessedit_make_boxes_from_boxes", "1");
|
|
|
|
api_.SetInputName(TestDataNameToPath(filename).c_str());
|
|
|
|
found = true;
|
|
|
|
}
|
|
|
|
return found;
|
2018-08-24 21:07:48 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Runs ApplyBoxes (via setting the appropriate variables and Recognize)
|
|
|
|
// and checks that the output ocr text matches the truth_str, and that
|
|
|
|
// the boxes match the given box file well enough.
|
|
|
|
// If line_mode is true, ApplyBoxes is run in line segmentation mode,
|
|
|
|
// otherwise the input box file is assumed to have character-level boxes.
|
2021-03-13 05:06:34 +08:00
|
|
|
void VerifyBoxesAndText(const char *imagefile, const char *truth_str, const char *target_box_file,
|
|
|
|
bool line_mode) {
|
2019-01-24 23:10:52 +08:00
|
|
|
if (!SetImage(imagefile)) {
|
|
|
|
// eng.traineddata not found or other problem during Init.
|
|
|
|
GTEST_SKIP();
|
|
|
|
}
|
2021-03-22 15:48:50 +08:00
|
|
|
if (line_mode) {
|
2018-08-24 21:07:48 +08:00
|
|
|
api_.SetVariable("tessedit_resegment_from_line_boxes", "1");
|
2021-03-22 15:48:50 +08:00
|
|
|
} else {
|
2018-08-24 21:07:48 +08:00
|
|
|
api_.SetVariable("tessedit_resegment_from_boxes", "1");
|
2021-03-22 15:48:50 +08:00
|
|
|
}
|
2018-09-29 15:27:12 +08:00
|
|
|
api_.Recognize(nullptr);
|
2021-03-13 05:06:34 +08:00
|
|
|
char *ocr_text = api_.GetUTF8Text();
|
2018-08-24 21:07:48 +08:00
|
|
|
EXPECT_STREQ(truth_str, ocr_text);
|
2018-09-29 15:19:13 +08:00
|
|
|
delete[] ocr_text;
|
2018-08-24 21:07:48 +08:00
|
|
|
// Test the boxes by reading the target box file in parallel with the
|
|
|
|
// bounding boxes in the ocr output.
|
2018-08-29 03:03:49 +08:00
|
|
|
std::string box_filename = TestDataNameToPath(target_box_file);
|
2021-03-13 05:06:34 +08:00
|
|
|
FILE *box_file = OpenBoxFile(box_filename.c_str());
|
2018-09-29 15:27:12 +08:00
|
|
|
ASSERT_TRUE(box_file != nullptr);
|
2018-08-24 21:07:48 +08:00
|
|
|
int height = pixGetHeight(src_pix_);
|
2021-03-13 05:06:34 +08:00
|
|
|
ResultIterator *it = api_.GetIterator();
|
2018-08-24 21:07:48 +08:00
|
|
|
do {
|
|
|
|
int left, top, right, bottom;
|
2021-03-13 05:06:34 +08:00
|
|
|
EXPECT_TRUE(it->BoundingBox(tesseract::RIL_SYMBOL, &left, &top, &right, &bottom));
|
2018-09-29 15:19:13 +08:00
|
|
|
TBOX ocr_box(ICOORD(left, height - bottom), ICOORD(right, height - top));
|
2018-10-16 19:23:57 +08:00
|
|
|
int line_number = 0;
|
2018-08-24 21:07:48 +08:00
|
|
|
TBOX truth_box;
|
2021-03-14 22:13:37 +08:00
|
|
|
std::string box_text;
|
|
|
|
EXPECT_TRUE(ReadNextBox(0, &line_number, box_file, box_text, &truth_box));
|
2018-08-24 21:07:48 +08:00
|
|
|
// Testing for major overlap is a bit weak, but if they all
|
|
|
|
// major overlap successfully, then it has to be fairly close.
|
|
|
|
EXPECT_TRUE(ocr_box.major_overlap(truth_box));
|
|
|
|
// Also check that the symbol text matches the box text.
|
2021-03-13 05:06:34 +08:00
|
|
|
char *symbol_text = it->GetUTF8Text(tesseract::RIL_SYMBOL);
|
2019-09-25 16:07:51 +08:00
|
|
|
EXPECT_STREQ(box_text.c_str(), symbol_text);
|
2018-09-29 15:19:13 +08:00
|
|
|
delete[] symbol_text;
|
2018-08-24 21:07:48 +08:00
|
|
|
} while (it->Next(tesseract::RIL_SYMBOL));
|
|
|
|
delete it;
|
|
|
|
}
|
|
|
|
|
2021-04-01 03:39:43 +08:00
|
|
|
Image src_pix_;
|
2018-08-29 03:03:49 +08:00
|
|
|
std::string ocr_text_;
|
2018-08-24 21:07:48 +08:00
|
|
|
tesseract::TessBaseAPI api_;
|
|
|
|
};
|
|
|
|
|
|
|
|
// Tests character-level applyboxes on normal Times New Roman.
|
|
|
|
TEST_F(ApplyBoxTest, TimesCharLevel) {
|
2021-03-13 05:06:34 +08:00
|
|
|
VerifyBoxesAndText("trainingtimes.tif", kTruthTextWords, "trainingtimes.box", false);
|
2018-08-24 21:07:48 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Tests character-level applyboxes on italic Times New Roman.
|
|
|
|
TEST_F(ApplyBoxTest, ItalicCharLevel) {
|
2021-03-13 05:06:34 +08:00
|
|
|
VerifyBoxesAndText("trainingital.tif", kTruthTextWords, "trainingital.box", false);
|
2018-08-24 21:07:48 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Tests line-level applyboxes on normal Times New Roman.
|
|
|
|
TEST_F(ApplyBoxTest, TimesLineLevel) {
|
2021-03-13 05:06:34 +08:00
|
|
|
VerifyBoxesAndText("trainingtimesline.tif", kTruthTextLine, "trainingtimes.box", true);
|
2018-08-24 21:07:48 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Tests line-level applyboxes on italic Times New Roman.
|
|
|
|
TEST_F(ApplyBoxTest, ItalLineLevel) {
|
2021-03-13 05:06:34 +08:00
|
|
|
VerifyBoxesAndText("trainingitalline.tif", kTruthTextLine, "trainingital.box", true);
|
2018-08-24 21:07:48 +08:00
|
|
|
}
|
|
|
|
|
2021-03-13 05:06:34 +08:00
|
|
|
} // namespace tesseract
|