Revert "Merge pull request #3330 from Sintun/master" (#3505)

This reverts commit 122daf1d64, reversing
changes made to 4cd56dc5f5.

Those changes caused two regressions which resulted in an assertion
or a segmentation fault.

Signed-off-by: Stefan Weil <sw@weilnetz.de>
This commit is contained in:
Stefan Weil 2021-07-22 08:04:23 +02:00 committed by GitHub
parent e176169a90
commit 4df822a3fc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 13 additions and 268 deletions

View File

@ -284,7 +284,6 @@ noinst_HEADERS += src/ccstruct/seam.h
noinst_HEADERS += src/ccstruct/split.h
noinst_HEADERS += src/ccstruct/statistc.h
noinst_HEADERS += src/ccstruct/stepblob.h
noinst_HEADERS += src/ccstruct/tabletransfer.h
noinst_HEADERS += src/ccstruct/werd.h
if !DISABLED_LEGACY_ENGINE
noinst_HEADERS += src/ccstruct/fontinfo.h

View File

@ -32,7 +32,6 @@
#include <tesseract/version.h>
#include <cstdio>
#include <tuple> // for std::tuple
#include <vector> // for std::vector
struct Pix;
@ -539,31 +538,6 @@ public:
*/
char *GetUTF8Text();
size_t GetNumberOfTables() const;
/// Return the i-th table bounding box coordinates
///
/// Gives the (top_left.x, top_left.y, bottom_right.x, bottom_right.y)
/// coordinates of the i-th table.
std::tuple<int, int, int, int> GetTableBoundingBox(
unsigned
i ///< Index of the table, for upper limit \see GetNumberOfTables()
);
/// Get bounding boxes of the rows of a table
/// return values are (top_left.x, top_left.y, bottom_right.x, bottom_right.y)
std::vector<std::tuple<int, int, int, int> > GetTableRows(
unsigned
i ///< Index of the table, for upper limit \see GetNumberOfTables()
);
/// Get bounding boxes of the cols of a table
/// return values are (top_left.x, top_left.y, bottom_right.x, bottom_right.y)
std::vector<std::tuple<int, int, int, int> > GetTableCols(
unsigned
i ///< Index of the table, for upper limit \see GetNumberOfTables()
);
/**
* Make a HTML-formatted string with hOCR markup from the internal
* data structures.

View File

@ -56,7 +56,6 @@
#include "tesseractclass.h" // for Tesseract
#include "tprintf.h" // for tprintf
#include "werd.h" // for WERD, WERD_IT, W_FUZZY_NON, W_FUZZY_SP
#include "tabletransfer.h" // for detected tables from tablefind.h
#include "thresholder.h" // for ImageThresholder
#include <tesseract/baseapi.h>
@ -1370,66 +1369,6 @@ char *TessBaseAPI::GetUTF8Text() {
return result;
}
size_t TessBaseAPI::GetNumberOfTables() const
{
return constUniqueInstance<std::vector<TessTable>>().size();
}
std::tuple<int,int,int,int> TessBaseAPI::GetTableBoundingBox(unsigned i)
{
const auto &t = constUniqueInstance<std::vector<TessTable>>();
if (i >= t.size()) {
return std::tuple<int, int, int, int>(0, 0, 0, 0);
}
const int height = tesseract_->ImageHeight();
return std::make_tuple<int,int,int,int>(
t[i].box.left(), height - t[i].box.top(),
t[i].box.right(), height - t[i].box.bottom());
}
std::vector<std::tuple<int,int,int,int>> TessBaseAPI::GetTableRows(unsigned i)
{
const auto &t = constUniqueInstance<std::vector<TessTable>>();
if (i >= t.size()) {
return std::vector<std::tuple<int, int, int, int>>();
}
std::vector<std::tuple<int,int,int,int>> rows(t[i].rows.size());
const int height = tesseract_->ImageHeight();
for (unsigned j = 0; j < t[i].rows.size(); ++j) {
rows[j] =
std::make_tuple<int, int, int, int>(t[i].rows[j].left(), height - t[i].rows[j].top(),
t[i].rows[j].right(), height - t[i].rows[j].bottom());
}
return rows;
}
std::vector<std::tuple<int,int,int,int> > TessBaseAPI::GetTableCols(unsigned i)
{
const auto &t = constUniqueInstance<std::vector<TessTable>>();
if (i >= t.size()) {
return std::vector<std::tuple<int, int, int, int>>();
}
std::vector<std::tuple<int,int,int,int>> cols(t[i].cols.size());
const int height = tesseract_->ImageHeight();
for (unsigned j = 0; j < t[i].cols.size(); ++j) {
cols[j] =
std::make_tuple<int, int, int, int>(t[i].cols[j].left(), height - t[i].cols[j].top(),
t[i].cols[j].right(), height - t[i].cols[j].bottom());
}
return cols;
}
static void AddBoxToTSV(const PageIterator *it, PageIteratorLevel level, std::string &text) {
int left, top, right, bottom;
it->BoundingBox(level, &left, &top, &right, &bottom);
@ -2252,8 +2191,6 @@ void TessBaseAPI::ClearResults() {
delete paragraph_models_;
paragraph_models_ = nullptr;
}
uniqueInstance<std::vector<TessTable>>().clear();
}
/**

View File

@ -1,67 +0,0 @@
/******************************************************************************
* File: tabletransfer.h
* Description: Infrastructure for the transfer of table detection results
* Author: Stefan Brechtken
*
* (C) Copyright 2021, Stefan Brechtken
* 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_CCSTRUCT_TABLETRANSFER_H_
#define TESSERACT_CCSTRUCT_TABLETRANSFER_H_
#include <memory>
#include <vector>
#include "rect.h"
namespace tesseract {
/// Structure for data transfer from table detector
struct TessTable {
tesseract::TBOX box;
std::vector<tesseract::TBOX> rows;
std::vector<tesseract::TBOX> cols;
};
/** \brief You can use this small template function to ensure that one and
* only one object of type T exists. It implements the Singleton Pattern.
*
* T must be default-constructable.
* Usage examples:
* A& a = uniqueInstance<A>();
* a.xyz();
* uniqueInstance<A>(make_unique<A>(42)); // replace instance
* a.foo();
* or
* uniqueInstance<A>().xyz();
*/
template<typename T>
T& uniqueInstance(std::unique_ptr<T> new_instance = nullptr)
{
static std::unique_ptr<T> _instance = std::make_unique<T>();
if (new_instance) {
_instance = std::move(new_instance);
}
return *_instance.get();
}
/// return const version of \see uniqueInstance
template<typename T>
const T& constUniqueInstance(std::unique_ptr<T> new_instance = nullptr)
{
return uniqueInstance<T>(std::move(new_instance));
}
} // namespace tesseract
#endif // TESSERACT_CCSTRUCT_TABLETRANSFER_H_

View File

@ -38,7 +38,6 @@
#include "strokewidth.h"
#include "tablefind.h"
#include "workingpartset.h"
#include "tabletransfer.h"
#include <algorithm>
@ -1591,11 +1590,6 @@ void ColumnFinder::RotateAndReskewBlocks(bool input_is_rtl, TO_BLOCK_LIST *block
tprintf("Block median size = (%d, %d)\n", block->median_size().x(), block->median_size().y());
}
}
auto &tables = uniqueInstance<std::vector<TessTable>>();
for (TessTable &mt : tables) {
mt.box.rotate_large(reskew_);
}
}
// Computes the rotations for the block (to make textlines horizontal) and

View File

@ -28,7 +28,6 @@
#include "colpartitionset.h"
#include "tablerecog.h"
#include "tabletransfer.h"
namespace tesseract {
@ -263,13 +262,12 @@ void TableFinder::LocateTables(ColPartitionGrid *grid, ColPartitionSet **all_col
#ifndef GRAPHICS_DISABLED
if (textord_show_tables) {
ScrollView *table_win = MakeWindow(0, 300,
"Step 1: Column Partitions & Neighbors");
ScrollView *table_win = MakeWindow(0, 300, "Column Partitions & Neighbors");
DisplayColPartitions(table_win, &clean_part_grid_, ScrollView::BLUE);
DisplayColPartitions(table_win, &leader_and_ruling_grid_, ScrollView::AQUAMARINE);
DisplayColPartitionConnections(table_win, &clean_part_grid_, ScrollView::ORANGE);
table_win = MakeWindow(100, 300, "Step 2: Fragmented Text");
table_win = MakeWindow(100, 300, "Fragmented Text");
DisplayColPartitions(table_win, &fragmented_text_grid_, ScrollView::BLUE);
}
#endif // !GRAPHICS_DISABLED
@ -304,8 +302,7 @@ void TableFinder::LocateTables(ColPartitionGrid *grid, ColPartitionSet **all_col
#ifndef GRAPHICS_DISABLED
if (textord_tablefind_show_mark) {
ScrollView *table_win = MakeWindow(1200, 300,
"Step 7: Table Columns and Regions");
ScrollView *table_win = MakeWindow(1200, 300, "Table Columns and Regions");
DisplayColSegments(table_win, &table_columns, ScrollView::DARK_TURQUOISE);
DisplayColSegments(table_win, &table_regions, ScrollView::YELLOW);
}
@ -327,8 +324,7 @@ void TableFinder::LocateTables(ColPartitionGrid *grid, ColPartitionSet **all_col
#ifndef GRAPHICS_DISABLED
if (textord_show_tables) {
ScrollView *table_win = MakeWindow(1200, 300,
"Step 8: Detected Table Locations");
ScrollView *table_win = MakeWindow(1200, 300, "Detected Table Locations");
DisplayColPartitions(table_win, &clean_part_grid_, ScrollView::BLUE);
DisplayColSegments(table_win, &table_columns, ScrollView::KHAKI);
table_grid_.DisplayBoxes(table_win);
@ -342,10 +338,8 @@ void TableFinder::LocateTables(ColPartitionGrid *grid, ColPartitionSet **all_col
#ifndef GRAPHICS_DISABLED
if (textord_show_tables) {
ScrollView *table_win = MakeWindow(1400, 600,
"Step 10: Recognized Tables");
DisplayColPartitions(table_win, &clean_part_grid_,
ScrollView::BLUE, ScrollView::BLUE);
ScrollView *table_win = MakeWindow(1400, 600, "Recognized Tables");
DisplayColPartitions(table_win, &clean_part_grid_, ScrollView::BLUE, ScrollView::BLUE);
table_grid_.DisplayBoxes(table_win);
}
#endif // !GRAPHICS_DISABLED
@ -358,9 +352,8 @@ void TableFinder::LocateTables(ColPartitionGrid *grid, ColPartitionSet **all_col
#ifndef GRAPHICS_DISABLED
if (textord_show_tables) {
ScrollView *table_win = MakeWindow(1500, 300, "Step 11: Detected Tables");
DisplayColPartitions(table_win, &clean_part_grid_,
ScrollView::BLUE, ScrollView::BLUE);
ScrollView *table_win = MakeWindow(1500, 300, "Detected Tables");
DisplayColPartitions(table_win, &clean_part_grid_, ScrollView::BLUE, ScrollView::BLUE);
table_grid_.DisplayBoxes(table_win);
}
#endif // !GRAPHICS_DISABLED
@ -782,8 +775,7 @@ void TableFinder::MarkTablePartitions() {
MarkPartitionsUsingLocalInformation();
#ifndef GRAPHICS_DISABLED
if (textord_tablefind_show_mark) {
ScrollView *table_win = MakeWindow(300, 300,
"Step 3: Initial Table Partitions");
ScrollView *table_win = MakeWindow(300, 300, "Initial Table Partitions");
DisplayColPartitions(table_win, &clean_part_grid_, ScrollView::BLUE);
DisplayColPartitions(table_win, &leader_and_ruling_grid_, ScrollView::AQUAMARINE);
}
@ -791,8 +783,7 @@ void TableFinder::MarkTablePartitions() {
FilterFalseAlarms();
#ifndef GRAPHICS_DISABLED
if (textord_tablefind_show_mark) {
ScrollView *table_win = MakeWindow(600, 300,
"Step 4: Filtered Table Partitions");
ScrollView *table_win = MakeWindow(600, 300, "Filtered Table Partitions");
DisplayColPartitions(table_win, &clean_part_grid_, ScrollView::BLUE);
DisplayColPartitions(table_win, &leader_and_ruling_grid_, ScrollView::AQUAMARINE);
}
@ -800,8 +791,7 @@ void TableFinder::MarkTablePartitions() {
SmoothTablePartitionRuns();
#ifndef GRAPHICS_DISABLED
if (textord_tablefind_show_mark) {
ScrollView *table_win = MakeWindow(900, 300,
"Step 5: Smoothed Table Partitions");
ScrollView *table_win = MakeWindow(900, 300, "Smoothed Table Partitions");
DisplayColPartitions(table_win, &clean_part_grid_, ScrollView::BLUE);
DisplayColPartitions(table_win, &leader_and_ruling_grid_, ScrollView::AQUAMARINE);
}
@ -809,8 +799,7 @@ void TableFinder::MarkTablePartitions() {
FilterFalseAlarms();
#ifndef GRAPHICS_DISABLED
if (textord_tablefind_show_mark || textord_show_tables) {
ScrollView *table_win = MakeWindow(900, 300,
"Step 6: Final Table Partitions");
ScrollView *table_win = MakeWindow(900, 300, "Final Table Partitions");
DisplayColPartitions(table_win, &clean_part_grid_, ScrollView::BLUE);
DisplayColPartitions(table_win, &leader_and_ruling_grid_, ScrollView::AQUAMARINE);
}
@ -1842,7 +1831,7 @@ void TableFinder::RecognizeTables() {
#ifndef GRAPHICS_DISABLED
ScrollView *table_win = nullptr;
if (textord_show_tables) {
table_win = MakeWindow(0, 0, "Step 9: Table Structure");
table_win = MakeWindow(0, 0, "Table Structure");
DisplayColPartitions(table_win, &fragmented_text_grid_, ScrollView::BLUE,
ScrollView::LIGHT_BLUE);
// table_grid_.DisplayBoxes(table_win);
@ -1995,25 +1984,6 @@ void TableFinder::DisplayColPartitionConnections(ScrollView *win, ColPartitionGr
// assigned to any table to their original types.
void TableFinder::MakeTableBlocks(ColPartitionGrid *grid, ColPartitionSet **all_columns,
WidthCallback width_cb) {
#ifndef GRAPHICS_DISABLED
ScrollView* table_win = nullptr;
if (textord_show_tables) {
table_win = MakeWindow(0, 0, "Step 12: Final tables");
DisplayColPartitions(table_win, &fragmented_text_grid_,
ScrollView::BLUE, ScrollView::LIGHT_BLUE);
}
#endif // GRAPHICS_DISABLED
// initializing recognizer in order to extract table row and columnd info
TableRecognizer recognizer;
{
recognizer.Init();
recognizer.set_line_grid(&leader_and_ruling_grid_);
recognizer.set_text_grid(&fragmented_text_grid_);
recognizer.set_max_text_height(global_median_xheight_ * 2.0);
recognizer.set_min_height(1.5 * gridheight());
}
// Since we have table blocks already, remove table tags from all
// colpartitions
GridSearch<ColPartition, ColPartition_CLIST, ColPartition_C_IT> gsearch(grid);
@ -2068,30 +2038,8 @@ void TableFinder::MakeTableBlocks(ColPartitionGrid *grid, ColPartitionSet **all_
table_partition->set_flow(BTFT_CHAIN);
table_partition->SetBlobTypes();
grid->InsertBBox(true, true, table_partition);
// Insert table columns and rows into an api accessible object
StructuredTable* table_structure = recognizer.RecognizeTable(table_box);
if (table_structure != nullptr) {
#ifndef GRAPHICS_DISABLED
if (textord_show_tables) {
table_structure->Display(table_win, ScrollView::LIME_GREEN);
}
#endif // GRAPHICS_DISABLED
auto &tables = uniqueInstance<std::vector<TessTable>>();
tables.push_back(
TessTable{table_box, table_structure->getRows(), table_structure->getCols()});
delete table_structure;
}
}
}
#ifndef GRAPHICS_DISABLED
if (textord_show_tables) {
table_grid_.DisplayBoxes(table_win);
}
#endif // GRAPHICS_DISABLED
}
//////// ColSegment code

View File

@ -310,39 +310,6 @@ void StructuredTable::Display(ScrollView *window, ScrollView::Color color) {
#endif
std::vector<TBOX> StructuredTable::getRows()
{
if (cell_y_.size() < 2) {
return std::vector<TBOX>();
}
std::vector<TBOX> rows(cell_y_.size() - 1);
unsigned ct = cell_y_.size() - 2;
for(unsigned i = 0; i + 1 < cell_y_.size(); i++) {
const ICOORD left(bounding_box_.left(), cell_y_[i]);
const ICOORD right(bounding_box_.right(), cell_y_[i + 1]);
rows[ct - i] = TBOX(left, right);
}
return rows;
}
std::vector<TBOX> StructuredTable::getCols()
{
if (cell_x_.size() < 2) {
return std::vector<TBOX>();
}
std::vector<TBOX> cols(cell_x_.size() - 1);
for(unsigned i = 0; i + 1 < cell_x_.size(); i++) {
const ICOORD top(cell_x_[i], bounding_box_.top());
const ICOORD bot(cell_x_[i+1], bounding_box_.bottom());
cols[i] = TBOX(top, bot);
}
return cols;
}
// Clear structure information.
void StructuredTable::ClearStructure() {
cell_x_.clear();

View File

@ -2,7 +2,6 @@
// File: tablerecog.h
// Description: Functions to detect structure of tables.
// Author: Nicholas Beato
// Created: Aug 17, 2010
//
// (C) Copyright 2010, Google Inc.
// Licensed under the Apache License, Version 2.0 (the "License");
@ -21,7 +20,6 @@
#define TABLERECOG_H_
#include "colpartitiongrid.h"
#include <vector>
namespace tesseract {
@ -136,11 +134,6 @@ public:
// valid, the table and "best" grid lines are still drawn in the given color.
void Display(ScrollView *window, ScrollView::Color color);
/// Calculate bounding boxes of the rows and return them.
std::vector<TBOX> getRows();
/// Calculate bounding boxes of the columns and return them.
std::vector<TBOX> getCols();
protected:
// Clear the structure information.
void ClearStructure();