Skip to content

Commit 5845e1a

Browse files
Shreeshriizdenop
authored andcommitted
Add unit test for OSD, update apiexample test (#1359)
* Update apiexample_test.cc * Add OSD test and logging function * Add images for OSD unittest
1 parent 7972b13 commit 5845e1a

9 files changed

+194
-25
lines changed

testing/devatest-rotated-270.png

598 KB
Loading

testing/devatest.png

522 KB
Loading

testing/phototest-rotated-180.png

5.15 KB
Loading

testing/phototest-rotated-L.png

6.63 KB
Loading

testing/phototest-rotated-R.png

6.7 KB
Loading

unittest/Makefile.am

+8-2
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,10 @@ AM_CPPFLAGS += -isystem $(top_srcdir)/googletest/googletest/include
3030
check_PROGRAMS = \
3131
apiexample_test \
3232
intsimdmatrix_test \
33-
tesseracttests \
34-
matrix_test
33+
matrix_test \
34+
osd_test \
35+
tesseracttests
36+
3537

3638
TESTS = $(check_PROGRAMS)
3739

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

52+
osd_test_SOURCES = osd_test.cc
53+
osd_test_LDADD = $(GTEST_LIBS) $(TESS_LIBS) $(LEPTONICA_LIBS)
54+
5055
tesseracttests_SOURCES = ../tests/tesseracttests.cpp
5156
tesseracttests_LDADD = $(GTEST_LIBS) $(TESS_LIBS) $(LEPTONICA_LIBS)
5257

@@ -55,6 +60,7 @@ if T_WIN
5560
apiexample_test_LDADD += -lws2_32
5661
intsimdmatrix_test_LDADD += -lws2_32
5762
matrix_test_LDADD += -lws2_32
63+
osd_test_LDADD += -lws2_32
5864
tesseracttests_LDADD += -lws2_32
5965

6066
AM_CPPFLAGS += -I$(top_srcdir)/vs2010/port

unittest/apiexample_test.cc

+48-23
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
///////////////////////////////////////////////////////////////////////
22
// File: apiexample_test.cc
3-
// Description: Api Example for Tesseract.
3+
// Description: Api Test for Tesseract using text fixtures and parameters.
44
// Author: ShreeDevi Kumar
55
//
66
// Licensed under the Apache License, Version 2.0 (the "License");
@@ -13,44 +13,69 @@
1313
// See the License for the specific language governing permissions and
1414
// limitations under the License.
1515
///////////////////////////////////////////////////////////////////////
16-
#include "gtest/gtest.h"
16+
17+
// expects clone of tessdata_fast repo in ../../tessdata_fast
18+
19+
//#include "log.h"
20+
#include "include_gunit.h"
1721
#include "baseapi.h"
1822
#include "leptonica/allheaders.h"
1923
#include <iostream>
2024
#include <string>
2125
#include <fstream>
2226
#include <locale>
27+
#include <limits.h>
28+
#include <time.h>
29+
30+
namespace {
31+
32+
class QuickTest : public testing::Test {
33+
protected:
34+
virtual void SetUp() {
35+
start_time_ = time(NULL);
36+
}
37+
virtual void TearDown() {
38+
const time_t end_time = time(NULL);
39+
EXPECT_TRUE(end_time - start_time_ <=25) << "The test took too long - " << ::testing::PrintToString(end_time - start_time_);
40+
}
41+
time_t start_time_;
42+
};
2343

24-
TEST(TesseractTest, ApiExample)
25-
{
44+
void OCRTester(const char* imgname, const char* groundtruth, const char* tessdatadir, const char* lang) {
45+
//log.info() << tessdatadir << " for language: " << lang << std::endl;
2646
char *outText;
2747
std::locale loc("C"); // You can also use "" for the default system locale
28-
std::ifstream file("../testing/phototest.txt");
48+
std::ifstream file(groundtruth);
2949
file.imbue(loc); // Use it for file input
30-
std::string gtText((std::istreambuf_iterator<char>(file)),
31-
std::istreambuf_iterator<char>());
32-
50+
std::string gtText((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
3351
tesseract::TessBaseAPI *api = new tesseract::TessBaseAPI();
34-
// Initialize tesseract-ocr with English, without specifying tessdata path
35-
ASSERT_FALSE(api->Init(nullptr, "eng")) << "Could not initialize tesseract.";
36-
37-
// Open input image with leptonica library
38-
Pix *image = pixRead("../testing/phototest.tif");
52+
ASSERT_FALSE(api->Init(tessdatadir, lang)) << "Could not initialize tesseract.";
53+
Pix *image = pixRead(imgname);
3954
ASSERT_TRUE(image != nullptr) << "Failed to read test image.";
4055
api->SetImage(image);
41-
// Get OCR result
4256
outText = api->GetUTF8Text();
43-
44-
ASSERT_EQ(gtText,outText) << "Phototest.tif with default values OCR does not match ground truth";
45-
46-
// Destroy used object and release memory
57+
EXPECT_EQ(gtText,outText) << "Phototest.tif OCR does not match ground truth for " << ::testing::PrintToString(lang);
4758
api->End();
4859
delete [] outText;
4960
pixDestroy(&image);
61+
}
5062

51-
}
63+
class MatchGroundTruth : public QuickTest ,
64+
public ::testing::WithParamInterface<const char*> {
65+
};
66+
67+
TEST_P(MatchGroundTruth, FastPhototestOCR) {
68+
OCRTester("../testing/phototest.tif" ,"../testing/phototest.txt" , "../../tessdata_fast", GetParam());
69+
}
70+
71+
INSTANTIATE_TEST_CASE_P( EngLatinDevaArabLang, MatchGroundTruth,
72+
::testing::Values("eng", "Latin", "Devanagari", "Arabic") );
5273

53-
int main(int argc, char **argv) {
54-
::testing::InitGoogleTest(&argc, argv);
55-
return RUN_ALL_TESTS();
56-
}
74+
class EuroText : public QuickTest {
75+
};
76+
77+
TEST_F(EuroText, FastOCR) {
78+
OCRTester("../testing/eurotext.tif" ,"../testing/eurotext.txt" , "../../tessdata_fast", "Latin");
79+
}
80+
81+
} // namespace

unittest/log.h

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
///////////////////////////////////////////////////////////////////////
2+
// File: log.h
3+
// Description: Include for custom log message for unittest for tesseract.
4+
// based on //https://stackoverflow.com/questions/16491675/how-to-send-custom-message-in-google-c-testing-framework
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
///////////////////////////////////////////////////////////////////////
16+
#ifndef TESSERACT_UNITTEST_LOG_H_
17+
#define TESSERACT_UNITTEST_LOG_H_
18+
19+
#include <iostream>
20+
21+
static class LOG { public: LOG() {}
22+
std::ostream& info() {
23+
std::cout << "[ LOG MSG ] ";
24+
return std::cout;
25+
}
26+
} log;
27+
28+
#endif // TESSERACT_UNITTEST_LOG_H_

unittest/osd_test.cc

+110
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
// File: osd_test.cc
2+
// Description: OSD Tests for Tesseract.
3+
// Author: ShreeDevi Kumar
4+
//
5+
// Licensed under the Apache License, Version 2.0 (the "License");
6+
// you may not use this file except in compliance with the License.
7+
// You may obtain a copy of the License at
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
///////////////////////////////////////////////////////////////////////
15+
16+
//based on https://gist.github.com/amitdo/7c7a522004dd79b398340c9595b377e1
17+
18+
// expects clones of tessdata, tessdata_fast and tessdata_best repos
19+
20+
#include "log.h"
21+
#include "include_gunit.h"
22+
#include "baseapi.h"
23+
#include "leptonica/allheaders.h"
24+
#include <iostream>
25+
#include <string>
26+
27+
namespace {
28+
29+
class TestClass : public testing::Test {
30+
protected:
31+
};
32+
33+
void OSDTester( int expected_deg, const char* imgname, const char* tessdatadir) {
34+
log.info() << tessdatadir << " for image: " << imgname << std::endl;
35+
tesseract::TessBaseAPI *api = new tesseract::TessBaseAPI();
36+
ASSERT_FALSE(api->Init(tessdatadir, "osd")) << "Could not initialize tesseract.";
37+
Pix *image = pixRead(imgname);
38+
ASSERT_TRUE(image != nullptr) << "Failed to read test image.";
39+
api->SetImage(image);
40+
int orient_deg;
41+
float orient_conf;
42+
const char* script_name;
43+
float script_conf;
44+
bool detected = api->DetectOrientationScript(&orient_deg, &orient_conf, &script_name, &script_conf);
45+
ASSERT_FALSE(!detected) << "Failed to detect OSD.";
46+
printf("************ Orientation in degrees: %d, Orientation confidence: %.2f\n"
47+
" Script: %s, Script confidence: %.2f\n",
48+
orient_deg, orient_conf,
49+
script_name, script_conf);
50+
EXPECT_EQ(expected_deg, orient_deg);
51+
api->End();
52+
pixDestroy(&image);
53+
}
54+
55+
class OSDTest : public TestClass ,
56+
public ::testing::WithParamInterface<std::tuple<int, const char*, const char*>> {};
57+
58+
TEST_P(OSDTest, MatchOrientationDegrees) {
59+
OSDTester(std::get<0>(GetParam()), std::get<1>(GetParam()), std::get<2>(GetParam()));
60+
}
61+
62+
INSTANTIATE_TEST_CASE_P( TessdataEngEuroHebrew, OSDTest,
63+
::testing::Combine(
64+
::testing::Values(0),
65+
::testing::Values("../testing/phototest.tif" , "../testing/eurotext.tif" , "../testing/hebrew.png"),
66+
::testing::Values("../../tessdata")));
67+
68+
INSTANTIATE_TEST_CASE_P( TessdataBestEngEuroHebrew, OSDTest,
69+
::testing::Combine(
70+
::testing::Values(0),
71+
::testing::Values("../testing/phototest.tif" , "../testing/eurotext.tif" , "../testing/hebrew.png"),
72+
::testing::Values("../../tessdata_best")));
73+
74+
INSTANTIATE_TEST_CASE_P( TessdataFastEngEuroHebrew, OSDTest,
75+
::testing::Combine(
76+
::testing::Values(0),
77+
::testing::Values("../testing/phototest.tif" , "../testing/eurotext.tif" , "../testing/hebrew.png"),
78+
::testing::Values("../../tessdata_fast")));
79+
80+
INSTANTIATE_TEST_CASE_P( TessdataFastRotated90, OSDTest,
81+
::testing::Combine(
82+
::testing::Values(90),
83+
::testing::Values("../testing/phototest-rotated-R.png"),
84+
::testing::Values("../../tessdata_fast")));
85+
86+
INSTANTIATE_TEST_CASE_P( TessdataFastRotated180, OSDTest,
87+
::testing::Combine(
88+
::testing::Values(180),
89+
::testing::Values("../testing/phototest-rotated-180.png"),
90+
::testing::Values("../../tessdata_fast")));
91+
92+
INSTANTIATE_TEST_CASE_P( TessdataFastRotated270, OSDTest,
93+
::testing::Combine(
94+
::testing::Values(270),
95+
::testing::Values("../testing/phototest-rotated-L.png"),
96+
::testing::Values("../../tessdata_fast")));
97+
98+
INSTANTIATE_TEST_CASE_P( TessdataFastDevaRotated270, OSDTest,
99+
::testing::Combine(
100+
::testing::Values(270),
101+
::testing::Values("../testing/devatest-rotated-270.png"),
102+
::testing::Values("../../tessdata_fast")));
103+
104+
INSTANTIATE_TEST_CASE_P( TessdataFastDeva, OSDTest,
105+
::testing::Combine(
106+
::testing::Values(0),
107+
::testing::Values("../testing/devatest.png"),
108+
::testing::Values("../../tessdata_fast")));
109+
110+
} // namespace

0 commit comments

Comments
 (0)