Skip to content

Commit

Permalink
Add unit test for OSD, update apiexample test (#1359)
Browse files Browse the repository at this point in the history
* Update apiexample_test.cc

* Add OSD test and logging function

* Add images for OSD unittest
  • Loading branch information
Shreeshrii authored and zdenop committed Mar 4, 2018
1 parent 7972b13 commit 5845e1a
Show file tree
Hide file tree
Showing 9 changed files with 194 additions and 25 deletions.
Binary file added testing/devatest-rotated-270.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added testing/devatest.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added testing/phototest-rotated-180.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added testing/phototest-rotated-L.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added testing/phototest-rotated-R.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 8 additions & 2 deletions unittest/Makefile.am
Expand Up @@ -30,8 +30,10 @@ AM_CPPFLAGS += -isystem $(top_srcdir)/googletest/googletest/include
check_PROGRAMS = \
apiexample_test \
intsimdmatrix_test \
tesseracttests \
matrix_test
matrix_test \
osd_test \
tesseracttests


TESTS = $(check_PROGRAMS)

Expand All @@ -47,6 +49,9 @@ intsimdmatrix_test_LDADD = $(GTEST_LIBS) $(TESS_LIBS)
matrix_test_SOURCES = matrix_test.cc
matrix_test_LDADD = $(GTEST_LIBS) $(TESS_LIBS)

osd_test_SOURCES = osd_test.cc
osd_test_LDADD = $(GTEST_LIBS) $(TESS_LIBS) $(LEPTONICA_LIBS)

tesseracttests_SOURCES = ../tests/tesseracttests.cpp
tesseracttests_LDADD = $(GTEST_LIBS) $(TESS_LIBS) $(LEPTONICA_LIBS)

Expand All @@ -55,6 +60,7 @@ if T_WIN
apiexample_test_LDADD += -lws2_32
intsimdmatrix_test_LDADD += -lws2_32
matrix_test_LDADD += -lws2_32
osd_test_LDADD += -lws2_32
tesseracttests_LDADD += -lws2_32

AM_CPPFLAGS += -I$(top_srcdir)/vs2010/port
Expand Down
71 changes: 48 additions & 23 deletions unittest/apiexample_test.cc
@@ -1,6 +1,6 @@
///////////////////////////////////////////////////////////////////////
// File: apiexample_test.cc
// Description: Api Example for Tesseract.
// Description: Api Test for Tesseract using text fixtures and parameters.
// Author: ShreeDevi Kumar
//
// Licensed under the Apache License, Version 2.0 (the "License");
Expand All @@ -13,44 +13,69 @@
// See the License for the specific language governing permissions and
// limitations under the License.
///////////////////////////////////////////////////////////////////////
#include "gtest/gtest.h"

// expects clone of tessdata_fast repo in ../../tessdata_fast

//#include "log.h"
#include "include_gunit.h"
#include "baseapi.h"
#include "leptonica/allheaders.h"
#include <iostream>
#include <string>
#include <fstream>
#include <locale>
#include <limits.h>
#include <time.h>

namespace {

class QuickTest : public testing::Test {
protected:
virtual void SetUp() {
start_time_ = time(NULL);
}
virtual void TearDown() {
const time_t end_time = time(NULL);
EXPECT_TRUE(end_time - start_time_ <=25) << "The test took too long - " << ::testing::PrintToString(end_time - start_time_);
}
time_t start_time_;
};

TEST(TesseractTest, ApiExample)
{
void OCRTester(const char* imgname, const char* groundtruth, const char* tessdatadir, const char* lang) {
//log.info() << tessdatadir << " for language: " << lang << std::endl;
char *outText;
std::locale loc("C"); // You can also use "" for the default system locale
std::ifstream file("../testing/phototest.txt");
std::ifstream file(groundtruth);
file.imbue(loc); // Use it for file input
std::string gtText((std::istreambuf_iterator<char>(file)),
std::istreambuf_iterator<char>());

std::string gtText((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
tesseract::TessBaseAPI *api = new tesseract::TessBaseAPI();
// Initialize tesseract-ocr with English, without specifying tessdata path
ASSERT_FALSE(api->Init(nullptr, "eng")) << "Could not initialize tesseract.";

// Open input image with leptonica library
Pix *image = pixRead("../testing/phototest.tif");
ASSERT_FALSE(api->Init(tessdatadir, lang)) << "Could not initialize tesseract.";
Pix *image = pixRead(imgname);
ASSERT_TRUE(image != nullptr) << "Failed to read test image.";
api->SetImage(image);
// Get OCR result
outText = api->GetUTF8Text();

ASSERT_EQ(gtText,outText) << "Phototest.tif with default values OCR does not match ground truth";

// Destroy used object and release memory
EXPECT_EQ(gtText,outText) << "Phototest.tif OCR does not match ground truth for " << ::testing::PrintToString(lang);
api->End();
delete [] outText;
pixDestroy(&image);
}

}
class MatchGroundTruth : public QuickTest ,
public ::testing::WithParamInterface<const char*> {
};

TEST_P(MatchGroundTruth, FastPhototestOCR) {
OCRTester("../testing/phototest.tif" ,"../testing/phototest.txt" , "../../tessdata_fast", GetParam());
}

INSTANTIATE_TEST_CASE_P( EngLatinDevaArabLang, MatchGroundTruth,
::testing::Values("eng", "Latin", "Devanagari", "Arabic") );

int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
class EuroText : public QuickTest {
};

TEST_F(EuroText, FastOCR) {
OCRTester("../testing/eurotext.tif" ,"../testing/eurotext.txt" , "../../tessdata_fast", "Latin");
}

} // namespace
28 changes: 28 additions & 0 deletions unittest/log.h
@@ -0,0 +1,28 @@
///////////////////////////////////////////////////////////////////////
// File: log.h
// Description: Include for custom log message for unittest for tesseract.
// based on //https://stackoverflow.com/questions/16491675/how-to-send-custom-message-in-google-c-testing-framework
//
// 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.
///////////////////////////////////////////////////////////////////////
#ifndef TESSERACT_UNITTEST_LOG_H_
#define TESSERACT_UNITTEST_LOG_H_

#include <iostream>

static class LOG { public: LOG() {}
std::ostream& info() {
std::cout << "[ LOG MSG ] ";
return std::cout;
}
} log;

#endif // TESSERACT_UNITTEST_LOG_H_
110 changes: 110 additions & 0 deletions unittest/osd_test.cc
@@ -0,0 +1,110 @@
// File: osd_test.cc
// Description: OSD Tests for Tesseract.
// Author: ShreeDevi Kumar
//
// 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.
///////////////////////////////////////////////////////////////////////

//based on https://gist.github.com/amitdo/7c7a522004dd79b398340c9595b377e1

// expects clones of tessdata, tessdata_fast and tessdata_best repos

#include "log.h"
#include "include_gunit.h"
#include "baseapi.h"
#include "leptonica/allheaders.h"
#include <iostream>
#include <string>

namespace {

class TestClass : public testing::Test {
protected:
};

void OSDTester( int expected_deg, const char* imgname, const char* tessdatadir) {
log.info() << tessdatadir << " for image: " << imgname << std::endl;
tesseract::TessBaseAPI *api = new tesseract::TessBaseAPI();
ASSERT_FALSE(api->Init(tessdatadir, "osd")) << "Could not initialize tesseract.";
Pix *image = pixRead(imgname);
ASSERT_TRUE(image != nullptr) << "Failed to read test image.";
api->SetImage(image);
int orient_deg;
float orient_conf;
const char* script_name;
float script_conf;
bool detected = api->DetectOrientationScript(&orient_deg, &orient_conf, &script_name, &script_conf);
ASSERT_FALSE(!detected) << "Failed to detect OSD.";
printf("************ Orientation in degrees: %d, Orientation confidence: %.2f\n"
" Script: %s, Script confidence: %.2f\n",
orient_deg, orient_conf,
script_name, script_conf);
EXPECT_EQ(expected_deg, orient_deg);
api->End();
pixDestroy(&image);
}

class OSDTest : public TestClass ,
public ::testing::WithParamInterface<std::tuple<int, const char*, const char*>> {};

TEST_P(OSDTest, MatchOrientationDegrees) {
OSDTester(std::get<0>(GetParam()), std::get<1>(GetParam()), std::get<2>(GetParam()));
}

INSTANTIATE_TEST_CASE_P( TessdataEngEuroHebrew, OSDTest,
::testing::Combine(
::testing::Values(0),
::testing::Values("../testing/phototest.tif" , "../testing/eurotext.tif" , "../testing/hebrew.png"),
::testing::Values("../../tessdata")));

INSTANTIATE_TEST_CASE_P( TessdataBestEngEuroHebrew, OSDTest,
::testing::Combine(
::testing::Values(0),
::testing::Values("../testing/phototest.tif" , "../testing/eurotext.tif" , "../testing/hebrew.png"),
::testing::Values("../../tessdata_best")));

INSTANTIATE_TEST_CASE_P( TessdataFastEngEuroHebrew, OSDTest,
::testing::Combine(
::testing::Values(0),
::testing::Values("../testing/phototest.tif" , "../testing/eurotext.tif" , "../testing/hebrew.png"),
::testing::Values("../../tessdata_fast")));

INSTANTIATE_TEST_CASE_P( TessdataFastRotated90, OSDTest,
::testing::Combine(
::testing::Values(90),
::testing::Values("../testing/phototest-rotated-R.png"),
::testing::Values("../../tessdata_fast")));

INSTANTIATE_TEST_CASE_P( TessdataFastRotated180, OSDTest,
::testing::Combine(
::testing::Values(180),
::testing::Values("../testing/phototest-rotated-180.png"),
::testing::Values("../../tessdata_fast")));

INSTANTIATE_TEST_CASE_P( TessdataFastRotated270, OSDTest,
::testing::Combine(
::testing::Values(270),
::testing::Values("../testing/phototest-rotated-L.png"),
::testing::Values("../../tessdata_fast")));

INSTANTIATE_TEST_CASE_P( TessdataFastDevaRotated270, OSDTest,
::testing::Combine(
::testing::Values(270),
::testing::Values("../testing/devatest-rotated-270.png"),
::testing::Values("../../tessdata_fast")));

INSTANTIATE_TEST_CASE_P( TessdataFastDeva, OSDTest,
::testing::Combine(
::testing::Values(0),
::testing::Values("../testing/devatest.png"),
::testing::Values("../../tessdata_fast")));

} // namespace

0 comments on commit 5845e1a

Please sign in to comment.