// (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. #include #include #include #include #include "boxread.h" #include "rect.h" #include "include_gunit.h" namespace tesseract { const char *kTruthTextWords = "To simple burn running of goods lately.\n"; const char *kTruthTextLine = "Tosimpleburnrunningofgoodslately.\n"; // The fixture for testing Tesseract. class ApplyBoxTest : public testing::Test { protected: std::string TestDataNameToPath(const std::string &name) { return file::JoinPath(TESTING_DIR, name); } std::string TessdataPath() { return TESSDATA_DIR; } ApplyBoxTest() { src_pix_ = nullptr; } ~ApplyBoxTest() override { src_pix_.destroy(); } bool SetImage(const char *filename) { bool found = false; src_pix_.destroy(); src_pix_ = pixRead(TestDataNameToPath(filename).c_str()); 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; } // 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. void VerifyBoxesAndText(const char *imagefile, const char *truth_str, const char *target_box_file, bool line_mode) { if (!SetImage(imagefile)) { // eng.traineddata not found or other problem during Init. GTEST_SKIP(); } if (line_mode) { api_.SetVariable("tessedit_resegment_from_line_boxes", "1"); } else { api_.SetVariable("tessedit_resegment_from_boxes", "1"); } api_.Recognize(nullptr); char *ocr_text = api_.GetUTF8Text(); EXPECT_STREQ(truth_str, ocr_text); delete[] ocr_text; // Test the boxes by reading the target box file in parallel with the // bounding boxes in the ocr output. std::string box_filename = TestDataNameToPath(target_box_file); FILE *box_file = OpenBoxFile(box_filename.c_str()); ASSERT_TRUE(box_file != nullptr); int height = pixGetHeight(src_pix_); ResultIterator *it = api_.GetIterator(); do { int left, top, right, bottom; EXPECT_TRUE(it->BoundingBox(tesseract::RIL_SYMBOL, &left, &top, &right, &bottom)); TBOX ocr_box(ICOORD(left, height - bottom), ICOORD(right, height - top)); int line_number = 0; TBOX truth_box; std::string box_text; EXPECT_TRUE(ReadNextBox(0, &line_number, box_file, box_text, &truth_box)); // 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. char *symbol_text = it->GetUTF8Text(tesseract::RIL_SYMBOL); EXPECT_STREQ(box_text.c_str(), symbol_text); delete[] symbol_text; } while (it->Next(tesseract::RIL_SYMBOL)); delete it; } Image src_pix_; std::string ocr_text_; tesseract::TessBaseAPI api_; }; // Tests character-level applyboxes on normal Times New Roman. TEST_F(ApplyBoxTest, TimesCharLevel) { VerifyBoxesAndText("trainingtimes.tif", kTruthTextWords, "trainingtimes.box", false); } // Tests character-level applyboxes on italic Times New Roman. TEST_F(ApplyBoxTest, ItalicCharLevel) { VerifyBoxesAndText("trainingital.tif", kTruthTextWords, "trainingital.box", false); } // Tests line-level applyboxes on normal Times New Roman. TEST_F(ApplyBoxTest, TimesLineLevel) { VerifyBoxesAndText("trainingtimesline.tif", kTruthTextLine, "trainingtimes.box", true); } // Tests line-level applyboxes on italic Times New Roman. TEST_F(ApplyBoxTest, ItalLineLevel) { VerifyBoxesAndText("trainingitalline.tif", kTruthTextLine, "trainingital.box", true); } } // namespace tesseract