last-svn-commit-707-gf9fd47c Integrate the DIA toolchain in Scribo viewer.

* demo/viewer/Makefile.am: Add new files. * demo/viewer/main.cc: Initialize libMagick++. * demo/viewer/step_widget.cc, * demo/viewer/step_widget.hh: Improve interface. * demo/viewer/viewer.cc, * demo/viewer/viewer.hh, * demo/viewer/viewer.hxx: Handle calls to the DIA toolchain. * demo/viewer/preprocess.cc, * demo/viewer/preprocess.hh, * demo/viewer/process.cc, * demo/viewer/process.hh, * demo/viewer/runner.cc, * demo/viewer/runner.hh: New. --- scribo/ChangeLog | 22 +++ scribo/demo/viewer/Makefile.am | 73 +++++++--- scribo/demo/viewer/main.cc | 2 + .../viewer/{option_widget.cc => preprocess.cc} | 13 +- .../{preferences_dialog.hh => preprocess.hh} | 38 ++--- .../demo/viewer/{option_widget.cc => process.cc} | 22 ++- .../{xml2doc/image_crop.hh => viewer/process.hh} | 48 +++---- scribo/demo/viewer/runner.cc | 150 ++++++++++++++++++ scribo/demo/viewer/runner.hh | 61 ++++++++ scribo/demo/viewer/step_widget.cc | 108 ++++++++------ scribo/demo/viewer/step_widget.hh | 19 +-- scribo/demo/viewer/viewer.cc | 160 +++++++++++++++---- scribo/demo/viewer/viewer.hh | 34 +++-- scribo/demo/viewer/viewer.hxx | 4 - 14 files changed, 565 insertions(+), 189 deletions(-) copy scribo/demo/viewer/{option_widget.cc => preprocess.cc} (78%) copy scribo/demo/viewer/{preferences_dialog.hh => preprocess.hh} (53%) copy scribo/demo/viewer/{option_widget.cc => process.cc} (66%) copy scribo/demo/{xml2doc/image_crop.hh => viewer/process.hh} (50%) create mode 100644 scribo/demo/viewer/runner.cc create mode 100644 scribo/demo/viewer/runner.hh diff --git a/scribo/ChangeLog b/scribo/ChangeLog index f12eb4f..04bf771 100644 --- a/scribo/ChangeLog +++ b/scribo/ChangeLog @@ -1,5 +1,27 @@ 2010-12-10 Guillaume Lazzara <z@lrde.epita.fr> + Integrate the DIA toolchain in Scribo viewer. + + * demo/viewer/Makefile.am: Add new files. + + * demo/viewer/main.cc: Initialize libMagick++. + + * demo/viewer/step_widget.cc, + * demo/viewer/step_widget.hh: Improve interface. + + * demo/viewer/viewer.cc, + * demo/viewer/viewer.hh, + * demo/viewer/viewer.hxx: Handle calls to the DIA toolchain. + + * demo/viewer/preprocess.cc, + * demo/viewer/preprocess.hh, + * demo/viewer/process.cc, + * demo/viewer/process.hh, + * demo/viewer/runner.cc, + * demo/viewer/runner.hh: New. + +2010-12-10 Guillaume Lazzara <z@lrde.epita.fr> + Fix guards and license. * demo/viewer/README, diff --git a/scribo/demo/viewer/Makefile.am b/scribo/demo/viewer/Makefile.am index 851bf30..2e0afec 100644 --- a/scribo/demo/viewer/Makefile.am +++ b/scribo/demo/viewer/Makefile.am @@ -1,16 +1,19 @@ -## -## Document layout viewer. -## -## Copyright (C) 2009 Florent D'Halluin. -## -## This program is free software; you can redistribute it and/or -## modify it under the terms of the GNU General Public License -## as published by the Free Software Foundation; either version 2 -## of the License, or (at your option) any later version. -## -## The complete GNU General Public Licence Notice can be found as the -## `COPYING' file in the root directory. -## +# Copyright (C) 2009, 2010 EPITA Research and Development Laboratory +# (LRDE). +# +# This file is part of Olena. +# +# Olena is free software: you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation, version 2 of the License. +# +# Olena is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Olena. If not, see <http://www.gnu.org/licenses/>. include $(top_srcdir)/build-aux/autotroll.mk @@ -27,11 +30,26 @@ scribo_viewer_SOURCES = $(BUILT_SOURCES) \ image_view.cc \ image_region.cc \ help_dialog.cc \ - step_widget.cc + step_widget.cc \ + toolchain_options.cc \ + runner.cc \ + preprocess.cc \ + process.cc \ + general_options.cc \ + preferences_dialog.cc \ + option_widget.cc \ + config.cc -scribo_viewer_CPPFLAGS = $(QT_CPPFLAGS) $(AM_CPPFLAGS) -I$(srcdir) +scribo_viewer_CPPFLAGS = $(QT_CPPFLAGS) $(AM_CPPFLAGS) -I$(srcdir) \ + -I$(top_srcdir)/milena \ + -I$(top_srcdir)/scribo \ + $(MAGICKXX_CPPFLAGS) \ + $(TESSERACT_CPPFLAGS) \ + -DNDEBUG -DMLN_WO_GLOBAL_VARS scribo_viewer_CXXFLAGS = $(QT_CXXFLAGS) $(AM_CXXFLAGS) -O3 -scribo_viewer_LDFLAGS = $(QT_LDFLAGS) $(LDFLAGS) +scribo_viewer_LDFLAGS = $(QT_LDFLAGS) $(LDFLAGS) \ + $(MAGICKXX_LDFLAGS) \ + $(TESSERACT_LDFLAGS) scribo_viewer_LDADD = $(QT_LIBS) $(LDADD) BUILT_SOURCES = viewer.moc.cc \ @@ -43,7 +61,16 @@ BUILT_SOURCES = viewer.moc.cc \ image_view.moc.cc \ image_region.moc.cc \ help_dialog.moc.cc \ - step_widget.moc.cc + step_widget.moc.cc \ + toolchain_options.moc.cc \ + toolchain_options.ui.h \ + runner.moc.cc \ + preprocess.moc.cc \ + process.moc.cc \ + preferences_dialog.moc.cc \ + preferences_dialog.ui.h \ + general_options.moc.cc \ + general_options.ui.h noinst_HEADERS = viewer.hh \ @@ -58,6 +85,16 @@ noinst_HEADERS = viewer.hh \ image_region.hxx \ common.hh \ help_dialog.hh \ - step_widget.hh + step_widget.hh \ + toolchain_options.hh \ + runner.hh \ + preprocess.hh \ + process.hh \ + general_options.hh \ + preferences_dialog.hh \ + option_widget.hh \ + config.hh EXTRA_DIST = README + +CLEANFILES = $(BUILT_SOURCES) \ No newline at end of file diff --git a/scribo/demo/viewer/main.cc b/scribo/demo/viewer/main.cc index 76d4494..6d1cb18 100644 --- a/scribo/demo/viewer/main.cc +++ b/scribo/demo/viewer/main.cc @@ -35,6 +35,8 @@ int main(int argc, char** argv) return 0; } + Magick::InitializeMagick(*argv); + Viewer* viewer = Viewer::Instance(argc, argv); if (!viewer) diff --git a/scribo/demo/viewer/option_widget.cc b/scribo/demo/viewer/preprocess.cc similarity index 78% copy from scribo/demo/viewer/option_widget.cc copy to scribo/demo/viewer/preprocess.cc index 4557749..fd9a48b 100644 --- a/scribo/demo/viewer/option_widget.cc +++ b/scribo/demo/viewer/preprocess.cc @@ -14,17 +14,16 @@ // You should have received a copy of the GNU General Public License // along with Olena. If not, see <http://www.gnu.org/licenses/>. -# include "option_widget.hh" +#include "preprocess.hh" -OptionWidget::OptionWidget(QWidget * parent) - : QWidget(parent) +void preprocess::on_progress() { + emit progress(); } -void OptionWidget::save_config() -{ -} -void OptionWidget::load_config() +void preprocess::on_new_progress_label(const char *label) { + QString lbl(label); + emit new_progress_label(label); } diff --git a/scribo/demo/viewer/preferences_dialog.hh b/scribo/demo/viewer/preprocess.hh similarity index 53% copy from scribo/demo/viewer/preferences_dialog.hh copy to scribo/demo/viewer/preprocess.hh index 0368bbe..4562cfb 100644 --- a/scribo/demo/viewer/preferences_dialog.hh +++ b/scribo/demo/viewer/preprocess.hh @@ -14,32 +14,28 @@ // You should have received a copy of the GNU General Public License // along with Olena. If not, see <http://www.gnu.org/licenses/>. -#ifndef SCRIBO_DEMO_VIEWER_PREFERENCES_DIALOG_HH -# define SCRIBO_DEMO_VIEWER_PREFERENCES_DIALOG_HH +#ifndef SCRIBO_DEMO_VIEWER_PREPROCESS_HH +# define SCRIBO_DEMO_VIEWER_PREPROCESS_HH -# include <QtGui> -# include <preferences_dialog.ui.h> +# include <QtCore/QObject> +# include <mln/core/image/image2d.hh> +# include <mln/value/rgb8.hh> +# include <scribo/toolchain/internal/text_in_doc_preprocess_functor.hh> -class preferences_dialog : public QDialog, private Ui::PreferencesDialog +using namespace scribo::toolchain::internal; + +struct preprocess + : public QObject, + public text_in_doc_preprocess_functor<mln::image2d<mln::value::rgb8> > { Q_OBJECT; -public: - preferences_dialog(QWidget *parent = 0); - ~preferences_dialog(); - -private slots: - void on_optionList_currentRowChanged(int row); - virtual void accept(); - virtual void reject(); - -private: // Methods - void load_option_list(); - void select_option_widget(int row); - -private: // Attributes - QVector<QWidget *> widgets_; + virtual void on_progress(); + virtual void on_new_progress_label(const char *label); +signals: + void new_progress_label(const QString& label); + void progress(); }; -#endif // ! SCRIBO_DEMO_VIEWER_PREFERENCES_DIALOG_HH +#endif // ! SCRIBO_DEMO_VIEWER_PREPROCESS_HH diff --git a/scribo/demo/viewer/option_widget.cc b/scribo/demo/viewer/process.cc similarity index 66% copy from scribo/demo/viewer/option_widget.cc copy to scribo/demo/viewer/process.cc index 4557749..8fa5b9f 100644 --- a/scribo/demo/viewer/option_widget.cc +++ b/scribo/demo/viewer/process.cc @@ -14,17 +14,29 @@ // You should have received a copy of the GNU General Public License // along with Olena. If not, see <http://www.gnu.org/licenses/>. -# include "option_widget.hh" +#include "process.hh" -OptionWidget::OptionWidget(QWidget * parent) - : QWidget(parent) +process::process(const char *doc_filename) + : super_t(doc_filename) { + +} + +void process::on_progress() +{ + emit progress(); } -void OptionWidget::save_config() + +void process::on_new_progress_label(const char *label) { + QString lbl(label); + emit new_progress_label(label); } -void OptionWidget::load_config() + +void process::on_xml_saved() { + QString filename(output_file.c_str()); + emit xml_saved(filename); } diff --git a/scribo/demo/xml2doc/image_crop.hh b/scribo/demo/viewer/process.hh similarity index 50% copy from scribo/demo/xml2doc/image_crop.hh copy to scribo/demo/viewer/process.hh index 2856c35..09ace43 100644 --- a/scribo/demo/xml2doc/image_crop.hh +++ b/scribo/demo/viewer/process.hh @@ -14,41 +14,33 @@ // You should have received a copy of the GNU General Public License // along with Olena. If not, see <http://www.gnu.org/licenses/>. -#ifndef SCRIBO_DEMO_XML2DOC_IMAGE_CROP_HH -# define SCRIBO_DEMO_XML2DOC_IMAGE_CROP_HH +#ifndef SCRIBO_DEMO_VIEWER_PROCESS_HH +# define SCRIBO_DEMO_VIEWER_PROCESS_HH -# include <QDomDocument> -# include <QtCore> - -# include <mln/value/rgb8.hh> +# include <QtCore/QObject> # include <mln/core/image/image2d.hh> +# include <scribo/toolchain/internal/content_in_doc_functor.hh> +using namespace scribo::toolchain::internal; -class DomModel; - -class ImageCrop : public QObject +struct process + : public QObject, + public content_in_doc_functor<mln::image2d<bool> > { - Q_OBJECT - public: - - ImageCrop(const QString&, const QString&, const QString&); - ~ImageCrop(); - - void save_image(const QString&); - bool crop_regions(bool temp = false); + Q_OBJECT; + typedef content_in_doc_functor<mln::image2d<bool> > super_t; - QString img_to_base64(); - bool img_from_base64(const QString&, const QString&); - void to_base64(const QString&, bool); +public: + process(const char *doc_filename); - void from_base64(); + virtual void on_progress(); + virtual void on_new_progress_label(const char *label); + virtual void on_xml_saved(); -private: - QString xml_; - QString image_; - QString output_dir_; - QMap<QString, QString> region_map_; - mln::image2d<mln::value::rgb8> ima_; +signals: + void new_progress_label(const QString& label); + void progress(); + void xml_saved(const QString& filename); }; -#endif // ! SCRIBO_DEMO_XML2DOC_IMAGE_CROP_HH +#endif // ! SCRIBO_DEMO_VIEWER_PROCESS_HH diff --git a/scribo/demo/viewer/runner.cc b/scribo/demo/viewer/runner.cc new file mode 100644 index 0000000..1d0f4bb --- /dev/null +++ b/scribo/demo/viewer/runner.cc @@ -0,0 +1,150 @@ +// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE) +// +// This file is part of Olena. +// +// Olena is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, version 2 of the License. +// +// Olena is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Olena. If not, see <http://www.gnu.org/licenses/>. + +#include "runner.hh" + +#include <mln/core/image/image2d.hh> +#include <mln/value/rgb8.hh> +#include <mln/io/magick/load.hh> + +#include "process.hh" +#include "preprocess.hh" +#include "config.hh" +#include "defs.hh" + + +using namespace mln; +using namespace scribo::toolchain::internal; + +runner::runner(QObject *parent) + : QThread(parent) +{ + moveToThread(this); +} + + +void runner::start(const QString& filename) +{ + filename_ = filename; + + QThread::start(); +} + + +void runner::run() +{ + QThread::setTerminationEnabled(); + + image2d<value::rgb8> ima; + io::magick::load(ima, filename_.toUtf8().constData()); + + image2d<bool> bin_ima = preprocess(ima); + process(ima, bin_ima); + + emit finished(); + qDebug() << "Done."; +} + + +image2d<bool> +runner::preprocess(const image2d<value::rgb8>& ima) +{ + emit new_step("Preprocessing"); + + ::preprocess f; + + // Load config. + config * const conf = config::get_instance(); + + connect(&f, SIGNAL(progress()), this, SIGNAL(progress())); + connect(&f, SIGNAL(new_progress_label(const QString&)), + this, SIGNAL(new_progress_label(const QString&))); + + f.enable_subsample = conf->preprocessing_subsample(); + f.enable_fg_extraction = conf->preprocessing_remove_bg(); + f.enable_deskew = conf->preprocessing_deskew(); + f.enable_denoising = conf->preprocessing_remove_noise(); + + f.binarization_algo = static_cast<Binarization_Algo>(conf->preprocessing_bin_algo()); + + emit new_progress_max_value(f.nsteps()); + + // Perform preprocessing. + f(ima); + + qDebug() << "Preprocess Done."; + return f.output; +} + + +void runner::process(const image2d<value::rgb8>& original_ima, + const image2d<bool>& processed_ima) +{ + emit new_step("Page segmentation"); + + ::process f(filename_.toUtf8().constData()); + + connect(&f, SIGNAL(progress()), this, SIGNAL(progress())); + connect(&f, SIGNAL(new_progress_label(const QString&)), + this, SIGNAL(new_progress_label(const QString&))); + connect(&f, SIGNAL(xml_saved(const QString&)), + this, SIGNAL(xml_saved(const QString&))); + + // Load config. + config * const conf = config::get_instance(); + + defs::FindSeparators + find_seps = static_cast<defs::FindSeparators>(conf->segmentation_find_seps()); + f.enable_line_seps = (find_seps == defs::Lines + || find_seps == defs::LinesAndWhitespaces); + f.enable_whitespace_seps = (find_seps == defs::Whitespaces + || find_seps == defs::LinesAndWhitespaces); + + f.allow_xml_extensions = true; + + + f.save_doc_as_xml = true; + QFileInfo file(filename_); + QString output_dir = QDir::tempPath(); + if (conf->general_save_xml_enabled()) + { + if (conf->general_save_xml_same_dir()) + output_dir = file.absolutePath(); + else if (conf->general_save_xml_custom_dir()) + output_dir = conf->general_save_xml_custom_dir_path(); + else + qDebug() << "runner::progress - Invalid xml saving option!"; + + QDir dir(output_dir); + if (!dir.exists() && !dir.mkpath(output_dir)) + output_dir = QDir::tempPath(); + } + f.output_file = (output_dir + "/" + file.baseName() + "_gui.xml").toUtf8().constData(); + qDebug() << "Saving to " << f.output_file.c_str(); + + emit new_progress_max_value(f.nsteps()); + + // Perform text detection. + f(original_ima, processed_ima); + + qDebug() << "Process Done."; +} + + +void runner::stop() +{ + terminate(); +} diff --git a/scribo/demo/viewer/runner.hh b/scribo/demo/viewer/runner.hh new file mode 100644 index 0000000..ed243ea --- /dev/null +++ b/scribo/demo/viewer/runner.hh @@ -0,0 +1,61 @@ +// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE) +// +// This file is part of Olena. +// +// Olena is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, version 2 of the License. +// +// Olena is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Olena. If not, see <http://www.gnu.org/licenses/>. + +#ifndef SCRIBO_DEMO_VIEWER_RUNNER_HH +# define SCRIBO_DEMO_VIEWER_RUNNER_HH + +# include <QtGui> + +# include <mln/core/image/image2d.hh> +# include <mln/value/rgb8.hh> + +using namespace mln; + +class runner : public QThread +{ + Q_OBJECT; + +public: + runner(QObject *parent = 0); + + void start(const QString& filename); + +public slots: + void stop(); + +signals: + void new_step(const QString& step_name); + void new_progress_max_value(int i); + void new_progress_label(const QString& msg); + void xml_saved(const QString& filename); + void progress(); + void finished(); + +private: // members + image2d<bool> preprocess(const image2d<value::rgb8>& ima); + void process(const image2d<value::rgb8>& original_ima, + const image2d<bool>& processed_ima); + virtual void run(); + + template <typename V> + unsigned find_best_scale(const mln::image2d<V>& ima); + +private: // attributes + QString filename_; +}; + + +#endif // ! SCRIBO_DEMO_VIEWER_RUNNER_HH diff --git a/scribo/demo/viewer/step_widget.cc b/scribo/demo/viewer/step_widget.cc index 010b270..342b654 100644 --- a/scribo/demo/viewer/step_widget.cc +++ b/scribo/demo/viewer/step_widget.cc @@ -13,17 +13,9 @@ // // You should have received a copy of the GNU General Public License // along with Olena. If not, see <http://www.gnu.org/licenses/>. -// -// As a special exception, you may use this file as part of a free -// software project without restriction. Specifically, if other files -// instantiate templates or use macros or inline functions from this -// file, or you compile this file and link it with other files to produce -// an executable, this file does not by itself cause the resulting -// executable to be covered by the GNU General Public License. This -// exception does not however invalidate any other reasons why the -// executable file might be covered by the GNU General Public License. # include "step_widget.hh" +# include "config.hh" StepWidget::StepWidget() : view_(new QListWidget()), @@ -48,26 +40,31 @@ StepWidget::StepWidget() this, SLOT(activate(QListWidgetItem*))); } +StepWidget::~StepWidget() +{ +} + + void StepWidget::activate(QListWidgetItem* item) { QString key, value; StepQMap::iterator iter = map_.find(item->text()); - view_->setCurrentItem(item); if (iter != map_.end()) - { - step_ = item->text(); - key = iter.key(); - value = iter.value(); - - emit load_xml(value); - } + { + view_->setCurrentItem(item); + step_ = item->text(); + key = iter.key(); + value = iter.value(); + + emit load_xml(value); + } else qDebug() << "Step not found!"; - } + void StepWidget::fill_steps(QString file, bool step, bool container) { view_->clear(); @@ -85,38 +82,31 @@ void StepWidget::fill_steps(QString file, bool step, bool container) // image is loaded once emit load_image(file, false); - int cut = file.lastIndexOf(QChar('/')); - QString path = file.left(cut+1); - QString filename = file.mid(cut+1); - cut = filename.lastIndexOf(QChar('.')); + QFileInfo f(file); + file_with_no_ext_ = f.baseName(); + + QStringList dirlist; + dirlist << f.absolutePath() << QDir::tempPath(); - QString file_with_no_ext = filename.left(cut); - // view_->addItem(file_with_no_ext); + // Set directories to look at according to settings. + config * const conf = config::get_instance(); + if (conf->general_save_xml_custom_dir()) + dirlist << conf->general_save_xml_custom_dir_path(); - QDir dir(path); + foreach(QString path, dirlist) + { + QDir dir(path); - if (dir.isReadable()) + if (dir.isReadable()) { QStringList filter; filter << "*.xml"; - QStringList xml_list = dir.entryList(filter); + QFileInfoList xml_list = dir.entryInfoList(filter); for (int i = 0; i < xml_list.size(); ++i) - { - if (xml_list.at(i).startsWith(file_with_no_ext)) - { - cut = xml_list.at(i).lastIndexOf(QChar('.')); - QString key = xml_list.at(i).left(cut); - key.replace(file_with_no_ext + QString("_"), QString("")); - key.replace(QRegExp("^step([0-9])"), "Step \\1"); - key.replace(QRegExp("^Step ([0-9])_"), "Step \\1 : "); - key.replace("_", " "); - QString value = path; - map_.insertMulti(key, value.append(xml_list.at(i))); - view_->addItem(key); - } - } + insert_new_entry(xml_list.at(i)); } + } if ( (step && step_ != QString::Null())) { @@ -130,15 +120,43 @@ void StepWidget::fill_steps(QString file, bool step, bool container) } } -void StepWidget::add_element(const QString& element) + +QListWidgetItem* StepWidget::insert_new_entry(const QFileInfo& file) { - view_->addItem(element); + QListWidgetItem *item = 0; + + if (file.fileName().startsWith(file_with_no_ext_)) + { + QString key = file.baseName(); + key.replace(file_with_no_ext_ + QString("_"), QString("")); + key.replace(QRegExp("^step([0-9])"), "Step \\1"); + key.replace(QRegExp("^Step ([0-9])_"), "Step \\1 : "); + key.replace("_", " "); + + bool exists = (map_.find(key) != map_.end()); + + map_.insertMulti(key, file.absoluteFilePath()); + + if (!exists) + { + item = new QListWidgetItem(key); + view_->addItem(item); + } + else + item = view_->findItems(key, Qt::MatchCaseSensitive).at(0); + } + + return item; } -StepWidget::~StepWidget() + +QListWidgetItem* StepWidget::add_element(const QString& element) { -} + QListWidgetItem *item = new QListWidgetItem(element); + view_->addItem(item); + return item; +} diff --git a/scribo/demo/viewer/step_widget.hh b/scribo/demo/viewer/step_widget.hh index c5d77df..b323167 100644 --- a/scribo/demo/viewer/step_widget.hh +++ b/scribo/demo/viewer/step_widget.hh @@ -13,19 +13,10 @@ // // You should have received a copy of the GNU General Public License // along with Olena. If not, see <http://www.gnu.org/licenses/>. -// -// As a special exception, you may use this file as part of a free -// software project without restriction. Specifically, if other files -// instantiate templates or use macros or inline functions from this -// file, or you compile this file and link it with other files to produce -// an executable, this file does not by itself cause the resulting -// executable to be covered by the GNU General Public License. This -// exception does not however invalidate any other reasons why the -// executable file might be covered by the GNU General Public License. -#ifndef STEP_WIDGET_HH_ -# define STEP_WIDGET_HH_ +#ifndef SCRIBO_DEMO_VIEWER_STEP_WIDGET_HH_ +# define SCRIBO_DEMO_VIEWER_STEP_WIDGET_HH_ # include <QtGui> @@ -39,7 +30,7 @@ class StepWidget public: StepWidget(); ~StepWidget(); - void add_element(const QString& element); + QListWidgetItem* add_element(const QString& element); signals: void load_image(QString, bool); @@ -50,11 +41,13 @@ signals: public slots: void fill_steps(QString file, bool step = false, bool container = false); void activate(QListWidgetItem* item); + QListWidgetItem* insert_new_entry(const QFileInfo& file); private: QListWidget* view_; StepQMap map_; QString step_; + QString file_with_no_ext_; }; -#endif /* !STEP_WIDGET_HH_ */ +#endif // ! SCRIBO_DEMO_VIEWER_STEP_WIDGET_HH_ diff --git a/scribo/demo/viewer/viewer.cc b/scribo/demo/viewer/viewer.cc index 41434ba..dd0fbe4 100644 --- a/scribo/demo/viewer/viewer.cc +++ b/scribo/demo/viewer/viewer.cc @@ -13,15 +13,10 @@ // // You should have received a copy of the GNU General Public License // along with Olena. If not, see <http://www.gnu.org/licenses/>. -// -// As a special exception, you may use this file as part of a free -// software project without restriction. Specifically, if other files -// instantiate templates or use macros or inline functions from this -// file, or you compile this file and link it with other files to produce -// an executable, this file does not by itself cause the resulting -// executable to be covered by the GNU General Public License. This -// exception does not however invalidate any other reasons why the -// executable file might be covered by the GNU General Public License. + + +#include <iostream> +#include <limits.h> #include "viewer.hh" #include "key_widget.hh" @@ -32,7 +27,9 @@ #include "image_scene.hh" #include "image_region.hh" #include "help_dialog.hh" -#include <limits.h> +#include "preferences_dialog.hh" +#include "runner.hh" +#include "config.hh" #include "common.hh" @@ -49,7 +46,8 @@ Viewer::Viewer(int &argc, char** argv) xml_file_(QString::Null()), base64_(false), text_(true), - use_image_(true) + use_image_(true), + pdialog_(win_) { // Key map @@ -81,30 +79,53 @@ Viewer::Viewer(int &argc, char** argv) region_ids_["chart_region"] = region::Chart; region_ids_["maths_region"] = region::Maths; - // Layout win_->resize(1152, 864); win_->statusBar(); QMenu* file_menu = win_->menuBar()->addMenu(tr("File")); QMenu* option_menu = win_->menuBar()->addMenu(tr("Options")); + QMenu* view_menu = win_->menuBar()->addMenu(tr("View")); QMenu* help_menu = win_->menuBar()->addMenu(tr("Help")); + + // File menu + + QAction *doc_seg_action = create_action("Segment document", file_menu, + "Segment document", "Ctrl+S"); + connect(doc_seg_action, SIGNAL(triggered()), + this, SLOT(run_process())); + file_menu->addAction(doc_seg_action); + + file_menu->addSeparator(); + QAction* quit_action = create_action("Quit", file_menu, "Exit the program.", "Ctrl+q"); connect(quit_action, SIGNAL(triggered()), app_, SLOT(quit())); file_menu->addAction(quit_action); - outline_action_ = create_action("Draw outline", option_menu, + // Option menu + + QAction* preferences_action_ = create_action("Preferences", option_menu, + "Preferences", "Ctrl+Alt+P"); + preferences_action_->setCheckable(false); + connect(preferences_action_, SIGNAL(triggered(bool)), + this, SLOT(on_preferences())); + option_menu->addAction(preferences_action_); + + + // View menu + + outline_action_ = create_action("Draw outline", view_menu, "Draw region outlines.", "Ctrl+o"); outline_action_->setCheckable(true); outline_action_->setChecked(true); connect(outline_action_, SIGNAL(toggled(bool)), this, SIGNAL(setOutline(bool))); - option_menu->addAction(outline_action_); + view_menu->addAction(outline_action_); - precise_action_ = create_action("Precise outline", option_menu, + precise_action_ = create_action("Precise outline", view_menu, "1px outline relative to the image " "(1px relative to the view if off).", "Ctrl+p"); @@ -112,27 +133,27 @@ Viewer::Viewer(int &argc, char** argv) precise_action_->setChecked(false); connect(precise_action_, SIGNAL(toggled(bool)), this, SIGNAL(setPrecise(bool))); - option_menu->addAction(precise_action_); + view_menu->addAction(precise_action_); - fill_action_ = create_action("Fill regions", option_menu, + fill_action_ = create_action("Fill regions", view_menu, "Color the inside of regions.", "Ctrl+f"); fill_action_->setCheckable(true); fill_action_->setChecked(true); connect(fill_action_, SIGNAL(toggled(bool)), this, SIGNAL(setFill(bool))); - option_menu->addAction(fill_action_); + view_menu->addAction(fill_action_); - QAction* cache_action = create_action("Disable cache", option_menu, + QAction* cache_action = create_action("Disable cache", view_menu, "Disable the image cache (useful for" " large images).", "Ctrl+c"); cache_action->setCheckable(true); cache_action->setChecked(false); connect(cache_action, SIGNAL(toggled(bool)), this, SLOT(useCache(bool))); - option_menu->addAction(cache_action); + view_menu->addAction(cache_action); - QAction* extended_action = create_action("Extended mode", option_menu, + QAction* extended_action = create_action("Extended mode", view_menu, "If enabled, some features " "not supported by ICDAR" " are added such as text regions" @@ -141,28 +162,28 @@ Viewer::Viewer(int &argc, char** argv) extended_action->setChecked(false); connect(extended_action, SIGNAL(toggled(bool)), this, SLOT(useExtended(bool))); - option_menu->addAction(extended_action); + view_menu->addAction(extended_action); - QAction* show_image_action = create_action("Show pictures", option_menu, + QAction* show_image_action = create_action("Show pictures", view_menu, "Display pictures on the scene or not", "Ctrl+i"); show_image_action->setCheckable(true); show_image_action->setChecked(true); connect(show_image_action, SIGNAL(toggled(bool)), this, SLOT(useImage(bool))); - option_menu->addAction(show_image_action); + view_menu->addAction(show_image_action); - QAction* show_text_action = create_action("Show text", option_menu, + QAction* show_text_action = create_action("Show text", view_menu, "Show detected text inside boxes.", "Ctrl+t"); show_text_action->setCheckable(true); show_text_action->setChecked(true); connect(show_text_action, SIGNAL(toggled(bool)), this, SLOT(useText(bool))); - option_menu->addAction(show_text_action); + view_menu->addAction(show_text_action); key_wgt_ = new KeyWidget(key_map_); - QAction *show_region_action = create_action("Show regions", option_menu, + QAction *show_region_action = create_action("Show regions", view_menu, "Display regions that are present in" " the XML file.", "Ctrl+r"); @@ -170,7 +191,9 @@ Viewer::Viewer(int &argc, char** argv) show_region_action->setChecked(true); connect(show_region_action, SIGNAL(toggled(bool)), key_wgt_, SLOT(setAll(bool))); - option_menu->addAction(show_region_action); + view_menu->addAction(show_region_action); + + // Help menu QAction* about_action = create_action("About", help_menu, "About this program", @@ -179,11 +202,13 @@ Viewer::Viewer(int &argc, char** argv) this, SLOT(help())); help_menu->addAction(about_action); + // Layout + QSplitter* h_splitter = new QSplitter(); QSplitter* v_splitter = new QSplitter(Qt::Vertical); QSplitter* v_splitter2 = new QSplitter(Qt::Vertical); - StepWidget* step_widget = new StepWidget(); + step_widget_ = new StepWidget(); XmlWidget* xml_wgt = new XmlWidget(); BrowserWidget* browser_wgt = new BrowserWidget(files_, argc != 2 ? QString() : argv[1]); @@ -191,7 +216,7 @@ Viewer::Viewer(int &argc, char** argv) scene_->setBackgroundBrush(scene_->palette().window()); - v_splitter->addWidget(step_widget); + v_splitter->addWidget(step_widget_); v_splitter->addWidget(key_wgt_); v_splitter->addWidget(browser_wgt); @@ -216,13 +241,13 @@ Viewer::Viewer(int &argc, char** argv) h_splitter->setSizes(h_sizes); connect(browser_wgt, SIGNAL(activated(QString, bool, bool)), - step_widget, SLOT(fill_steps(QString, bool, bool))); + step_widget_, SLOT(fill_steps(QString, bool, bool))); - connect(step_widget, SIGNAL(change_base(bool)), + connect(step_widget_, SIGNAL(change_base(bool)), this, SLOT(change_base(bool))); - connect(step_widget, SIGNAL(load_image(QString, bool)), + connect(step_widget_, SIGNAL(load_image(QString, bool)), this, SLOT(load(QString, bool))); - connect(step_widget, SIGNAL(load_xml(QString)), + connect(step_widget_, SIGNAL(load_xml(QString)), this, SLOT(load_xml(QString))); connect(this, SIGNAL(mode_changed(bool)), @@ -242,9 +267,34 @@ Viewer::Viewer(int &argc, char** argv) connect(image_wgt, SIGNAL(scaleUpdated(qreal)), this, SLOT(maybeChangeCacheMode(qreal))); + + + // Progress dialog and process runner. + pdialog_.setModal(true); + pdialog_.setAutoClose(false); + pdialog_.setCancelButton(0); + connect(&runner_, SIGNAL(finished()), &pdialog_, SLOT(close())); + + connect(&runner_, SIGNAL(new_step(const QString&)), + &pdialog_, SLOT(setWindowTitle(const QString&))); + connect(&runner_, SIGNAL(new_progress_max_value(int)), + &pdialog_, SLOT(setMaximum(int))); + connect(&runner_, SIGNAL(new_progress_label(const QString&)), + &pdialog_, SLOT(setLabelText(const QString&))); + connect(&runner_, SIGNAL(progress()), + this, SLOT(run_progress())); + connect(&runner_, SIGNAL(xml_saved(const QString&)), + this, SLOT(on_xml_saved(const QString&))); } +Viewer::~Viewer() +{ + // Remove temporary xml files. + foreach(QString file, tmp_files_to_remove_) + QFile::remove(file); +} + void Viewer::add_text(QDomNode line, QDomNode region) { @@ -518,6 +568,8 @@ Viewer::load(QString filename, bool b) else image_ = new QGraphicsPixmapItem(QPixmap(filename)); + current_image_ = filename; + image_->setShapeMode(QGraphicsPixmapItem::BoundingRectShape); image_->setZValue(0); if (use_image_) @@ -687,3 +739,43 @@ QAction return (action); } + +void +Viewer::on_preferences() +{ + preferences_dialog *win = new preferences_dialog(win_); + win->show(); +} + + +void +Viewer::run_process() +{ + if (!current_image_.isEmpty()) + { + pdialog_.setValue(0); + pdialog_.setLabelText(""); + pdialog_.show(); + runner_.start(current_image_); + } +} + + +void +Viewer::run_progress() +{ + pdialog_.setValue(pdialog_.value() + 1); +} + + +void +Viewer::on_xml_saved(const QString& filename) +{ + config * const conf = config::get_instance(); + + if (!conf->general_save_xml_enabled()) + tmp_files_to_remove_.insert(filename); + + QListWidgetItem *item = step_widget_->insert_new_entry(filename); + step_widget_->activate(item); +} diff --git a/scribo/demo/viewer/viewer.hh b/scribo/demo/viewer/viewer.hh index 30e01bb..93fc840 100644 --- a/scribo/demo/viewer/viewer.hh +++ b/scribo/demo/viewer/viewer.hh @@ -13,27 +13,20 @@ // // You should have received a copy of the GNU General Public License // along with Olena. If not, see <http://www.gnu.org/licenses/>. -// -// As a special exception, you may use this file as part of a free -// software project without restriction. Specifically, if other files -// instantiate templates or use macros or inline functions from this -// file, or you compile this file and link it with other files to produce -// an executable, this file does not by itself cause the resulting -// executable to be covered by the GNU General Public License. This -// exception does not however invalidate any other reasons why the -// executable file might be covered by the GNU General Public License. - -#ifndef VIEWER_HH_ -# define VIEWER_HH_ + +#ifndef SCRIBO_DEMO_VIEWER_VIEWER_HH +# define SCRIBO_DEMO_VIEWER_VIEWER_HH # include <QtGui> -# include "common.hh" # include <QDomNode> +# include "common.hh" +# include "runner.hh" class ImageScene; class DomModel; class KeyWidget; class ImageRegion; +class StepWidget; class Viewer : public QObject @@ -60,6 +53,12 @@ public slots: void useImage(bool b); void change_base(bool b); +private slots: + void on_preferences(); + void run_process(); + void run_progress(); + void on_xml_saved(const QString& filename); + signals: void updated(); void key_updated(int key, bool checked); @@ -81,6 +80,7 @@ private: QApplication* app_; QMainWindow* win_; + StepWidget* step_widget_; QGraphicsPixmapItem* image_; @@ -105,8 +105,14 @@ private: bool use_image_; QVector<QGraphicsTextItem *> text_vector_; QVector<QGraphicsPixmapItem*> image_vector_; + QString current_image_; + + QProgressDialog pdialog_; + runner runner_; + + QSet<QString> tmp_files_to_remove_; }; #include "viewer.hxx" -#endif /* !VIEWER_HH_ */ +#endif // ! SCRIBO_DEMO_VIEWER_VIEWER_HH diff --git a/scribo/demo/viewer/viewer.hxx b/scribo/demo/viewer/viewer.hxx index b72eaff..cba59f3 100644 --- a/scribo/demo/viewer/viewer.hxx +++ b/scribo/demo/viewer/viewer.hxx @@ -35,8 +35,4 @@ inline Viewer* Viewer::Instance(int &argc, char** argv) return &viewer; } -inline Viewer::~Viewer() -{ -} - #endif /* !VIEWER_HXX_ */ -- 1.5.6.5
participants (1)
-
Guillaume Lazzara