Skip to content

Commit 51a3398

Browse files
committed
Improved character position tracking when LSTM models are used
When using LSTM models the accuracy of character bounding boxes is low with many blobs assigned to wrong characters. This is caused by the fact that LSTM model output produces only approximate character positions without boundary data. As a result the input blobs cannot be accurately mapped to characters and which compromises the accuracy of character bounding boxes. Current this problem is solved as follows. The character boundaries are computed according to the character positions from the LSTM output by placing the boundaries at the middle between two character positions. The blobs are then assigned according to which character the center of the blob falls to. In other words the blobs are assigned to the nearest characters. This unfortunately produces a lot of errors because the character positions in the LSTM output have a tendency to drift, thus the nearest character is often not the right one. Fortunately while the LSTM model produces approximate positions, the blob boundaries produced by the regular segmenter are pretty good. Most of the time a single blob corresponds to a single character and vice-versa. The above is used to create an optimization algorithm that treats the output of the regular segmenter as a template to which LSTM model output is matched. The selection of best match is done by assigning each unwanted property of the outcome a cost and then minimizing the total cost of the solution. This reliably solves the most frequent error present in the current solution when blobs are simply assigned to wrong character. As a result the current algorithm produces up to 20 times less errors. Fixes tesseract-ocr#1712.
1 parent dbb2adb commit 51a3398

File tree

5 files changed

+1078
-45
lines changed

5 files changed

+1078
-45
lines changed

Makefile.am

+7
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,7 @@ endif
250250
# Rules for src/ccstruct.
251251

252252
noinst_HEADERS += src/ccstruct/blamer.h
253+
noinst_HEADERS += src/ccstruct/blob_bounds_calculator.h
253254
noinst_HEADERS += src/ccstruct/blobbox.h
254255
noinst_HEADERS += src/ccstruct/blobs.h
255256
noinst_HEADERS += src/ccstruct/blread.h
@@ -293,6 +294,7 @@ noinst_HEADERS += src/ccstruct/params_training_featdef.h
293294
endif
294295

295296
libtesseract_la_SOURCES += src/ccstruct/blamer.cpp
297+
libtesseract_la_SOURCES += src/ccstruct/blob_bounds_calculator.cpp
296298
libtesseract_la_SOURCES += src/ccstruct/blobbox.cpp
297299
libtesseract_la_SOURCES += src/ccstruct/blobs.cpp
298300
libtesseract_la_SOURCES += src/ccstruct/blread.cpp
@@ -1197,6 +1199,7 @@ if !DISABLED_LEGACY_ENGINE
11971199
check_PROGRAMS += bitvector_test
11981200
endif # !DISABLED_LEGACY_ENGINE
11991201
endif # ENABLE_TRAINING
1202+
check_PROGRAMS += blob_bounds_calculator_test
12001203
check_PROGRAMS += cleanapi_test
12011204
check_PROGRAMS += colpartition_test
12021205
if ENABLE_TRAINING
@@ -1309,6 +1312,10 @@ bitvector_test_CPPFLAGS = $(unittest_CPPFLAGS)
13091312
bitvector_test_LDADD = $(TRAINING_LIBS)
13101313
endif # !DISABLED_LEGACY_ENGINE
13111314

1315+
blob_bounds_calculator_test_SOURCES = unittest/blob_bounds_calculator_test.cc
1316+
blob_bounds_calculator_test_CPPFLAGS = $(unittest_CPPFLAGS)
1317+
blob_bounds_calculator_test_LDADD = $(TESS_LIBS)
1318+
13121319
cleanapi_test_SOURCES = unittest/cleanapi_test.cc
13131320
cleanapi_test_CPPFLAGS = $(unittest_CPPFLAGS)
13141321
cleanapi_test_LDADD = $(TESS_LIBS)

0 commit comments

Comments
 (0)