* demo/demat/demat.pro,
* demo/demat/demat.qrc,
* demo/demat/src/doc_type.hh,
* demo/demat/src/main.cc,
* demo/demat/src/main_window.cc,
* demo/demat/src/main_window.hh,
* demo/demat/src/mln_widgets.cc,
* demo/demat/src/preprocessing_task.hh,
* demo/demat/src/process_args.hh,
* demo/demat/src/runner.cc,
* demo/demat/src/runner.hh,
* demo/demat/ui/main_window.ui: New.
* demo/shared/src/crop_item.cc,
* demo/shared/src/crop_item.hh,
* demo/shared/src/image_viewer.cc,
* demo/shared/src/image_viewer.hh,
* demo/shared/ui/image_viewer.ui: Update according the needs of
this new demo.
---
scribo/ChangeLog | 24 ++
scribo/demo/demat/demat.pro | 37 ++
scribo/demo/demat/demat.qrc | 4 +
scribo/demo/{wizard => demat}/src/doc_type.hh | 0
scribo/demo/demat/src/main.cc | 27 ++
scribo/demo/demat/src/main_window.cc | 240 +++++++++++++
scribo/demo/demat/src/main_window.hh | 91 +++++
scribo/demo/demat/src/mln_widgets.cc | 11 +
.../{wizard => demat}/src/preprocessing_task.hh | 0
scribo/demo/demat/src/process_args.hh | 47 +++
scribo/demo/demat/src/runner.cc | 316 +++++++++++++++++
scribo/demo/demat/src/runner.hh | 93 +++++
scribo/demo/demat/ui/main_window.ui | 366 ++++++++++++++++++++
scribo/demo/shared/src/crop_item.cc | 45 ++-
scribo/demo/shared/src/crop_item.hh | 12 +-
scribo/demo/shared/src/image_viewer.cc | 65 +++-
scribo/demo/shared/src/image_viewer.hh | 14 +-
scribo/demo/shared/ui/image_viewer.ui | 34 ++-
18 files changed, 1398 insertions(+), 28 deletions(-)
create mode 100644 scribo/demo/demat/demat.pro
create mode 100644 scribo/demo/demat/demat.qrc
copy scribo/demo/{wizard => demat}/src/doc_type.hh (100%)
create mode 100644 scribo/demo/demat/src/main.cc
create mode 100644 scribo/demo/demat/src/main_window.cc
create mode 100644 scribo/demo/demat/src/main_window.hh
create mode 100644 scribo/demo/demat/src/mln_widgets.cc
copy scribo/demo/{wizard => demat}/src/preprocessing_task.hh (100%)
create mode 100644 scribo/demo/demat/src/process_args.hh
create mode 100644 scribo/demo/demat/src/runner.cc
create mode 100644 scribo/demo/demat/src/runner.hh
create mode 100644 scribo/demo/demat/ui/main_window.ui
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index 40a5fb4..68ec602 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,29 @@
2010-03-19 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Add a new demo in Scribo.
+
+ * demo/demat/demat.pro,
+ * demo/demat/demat.qrc,
+ * demo/demat/src/doc_type.hh,
+ * demo/demat/src/main.cc,
+ * demo/demat/src/main_window.cc,
+ * demo/demat/src/main_window.hh,
+ * demo/demat/src/mln_widgets.cc,
+ * demo/demat/src/preprocessing_task.hh,
+ * demo/demat/src/process_args.hh,
+ * demo/demat/src/runner.cc,
+ * demo/demat/src/runner.hh,
+ * demo/demat/ui/main_window.ui: New.
+
+ * demo/shared/src/crop_item.cc,
+ * demo/shared/src/crop_item.hh,
+ * demo/shared/src/image_viewer.cc,
+ * demo/shared/src/image_viewer.hh,
+ * demo/shared/ui/image_viewer.ui: Update according the needs of
+ this new demo.
+
+2010-03-19 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Small fixes in Scribo.
* binarization/sauvola_ms.hh: Fix compilation issues on MacOS X.
diff --git a/scribo/demo/demat/demat.pro b/scribo/demo/demat/demat.pro
new file mode 100644
index 0000000..4f4af23
--- /dev/null
+++ b/scribo/demo/demat/demat.pro
@@ -0,0 +1,37 @@
+# -*- c++ -*-
+######################################################################
+# Automatically generated by qmake (2.01a) Tue Feb 9 12:02:10 2010
+######################################################################
+
+TEMPLATE = app
+TARGET =
+DEPENDPATH += . src
+INCLUDEPATH += . ../ ../shared $(OLN)/milena $(OLN)
+
+QMAKE_CXXFLAGS += -g
+
+LIBS += `Magick++-config --ldflags --libs`
+
+DEFINES += NDEBUG MLN_INCLUDE_ONLY
+
+# Input
+ HEADERS += \
+ ../shared/src/image_viewer.hh \
+ ../shared/src/internal/interactive_scene.hh \
+ ../shared/src/crop_item.hh \
+ ../shared/src/browse_widget.hh \
+ src/runner.hh \
+ src/main_window.hh
+
+SOURCES += \
+ ../shared/src/crop_item.cc \
+ ../shared/src/internal/interactive_scene.cc \
+ ../shared/src/browse_widget.cc \
+ src/mln_widgets.cc
+
+FORMS += \
+ ../shared/ui/image_viewer.ui \
+ ui/main_window.ui
+
+
+RESOURCES += ../shared/shared.qrc demat.qrc
diff --git a/scribo/demo/demat/demat.qrc b/scribo/demo/demat/demat.qrc
new file mode 100644
index 0000000..68031c7
--- /dev/null
+++ b/scribo/demo/demat/demat.qrc
@@ -0,0 +1,4 @@
+<RCC>
+ <qresource prefix="images" >
+ </qresource>
+</RCC>
diff --git a/scribo/demo/wizard/src/doc_type.hh b/scribo/demo/demat/src/doc_type.hh
similarity index 100%
copy from scribo/demo/wizard/src/doc_type.hh
copy to scribo/demo/demat/src/doc_type.hh
diff --git a/scribo/demo/demat/src/main.cc b/scribo/demo/demat/src/main.cc
new file mode 100644
index 0000000..ee35a48
--- /dev/null
+++ b/scribo/demo/demat/src/main.cc
@@ -0,0 +1,27 @@
+#include <QtGui>
+#include <src/main_window.hh>
+#include <src/preprocessing_task.hh>
+
+namespace scribo { namespace demo {extern QString basedir_; } }
+
+int main(int argc, char* argv[])
+{
+ QApplication app(argc, argv);
+
+
qRegisterMetaType<preprocessing_task_set_t>("preprocessing_task_set_t");
+
+ if (argc == 2)
+ {
+ scribo::demo::basedir_ = argv[1];
+ }
+ else
+ {
+ qDebug() << "Usage: " << argv[0] << "
<path_to_scribo/src>";
+ return 1;
+ }
+
+ scribo::demo::demat::main_window win;
+ win.show();
+
+ return app.exec();
+}
diff --git a/scribo/demo/demat/src/main_window.cc b/scribo/demo/demat/src/main_window.cc
new file mode 100644
index 0000000..ee82ca1
--- /dev/null
+++ b/scribo/demo/demat/src/main_window.cc
@@ -0,0 +1,240 @@
+// 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/>.
+//
+// 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 <src/main_window.hh>
+
+#include <src/doc_type.hh>
+#include <src/preprocessing_task.hh>
+#include <src/process_args.hh>
+
+#include <mln/data/convert.hh>
+#include <mln/convert/to_qimage_nocopy.hh>
+#include <mln/core/routine/duplicate.hh>
+#include <mln/make/box2d.hh>
+#include <mln/data/paste.hh>
+#include <mln/io/magick/load.hh>
+
+namespace scribo
+{
+
+ namespace demo
+ {
+
+ namespace demat
+ {
+
+ // FIXME: move it as attribute.
+ static mln::image2d<mln::value::rgb8> input_;
+
+
+ main_window::main_window()
+ {
+ setupUi(this);
+
+ text_->hide();
+
+ connect(action_Open, SIGNAL(activated()),
+ this, SLOT(open_file_slot()));
+
+ connect(run_btn, SIGNAL(clicked()), this, SLOT(run()));
+
+
+ // Connections to/from task runner.
+ connect(&runner_, SIGNAL(new_progress_label(const QString&)),
+ this, SLOT(update_progress_label_slot(const QString&)));
+
+ connect(&runner_, SIGNAL(progress(unsigned)),
+ this, SLOT(progress_slot(unsigned)));
+ connect(&runner_, SIGNAL(finished()),
+ this, SLOT(process_finished_slot()));
+
+ // Connections for dock windows.
+ connect(advanced_dock_, SIGNAL(visibilityChanged(bool)),
+ actionAdvanced_options, SLOT(setChecked(bool)));
+ connect(options_dock_, SIGNAL(visibilityChanged(bool)),
+ actionOptions, SLOT(setChecked(bool)));
+
+ connect(actionAdvanced_options, SIGNAL(triggered(bool)),
+ advanced_dock_, SLOT(setVisible(bool)));
+ connect(actionOptions, SIGNAL(triggered(bool)),
+ options_dock_, SLOT(setVisible(bool)));
+
+ progress_ = new QProgressDialog();
+ progress_->setLabelText("Processing...");
+ progress_->setCancelButton(0);
+ progress_->setAutoClose(true);
+
+ // Setup crop tool.
+ viewer_->set_selection_enabled(true);
+ connect(viewer_, SIGNAL(ready_for_crop()), this, SLOT(crop_slot()));
+ }
+
+
+ void main_window::open_file_slot()
+ {
+ QFileDialog dialog;
+ QStringList filters;
+ filters << tr("Image (*.ppm *.pbm *.pgm *.png *.jpg)");
+ dialog.setNameFilters(filters);
+
+ dialog.setFileMode(QFileDialog::ExistingFile);
+ dialog.setLabelText(QFileDialog::LookIn,
+ tr("Choose an existing file"));
+
+ if (dialog.exec() && current_image_ != dialog.selectedFiles().at(0))
+ {
+ current_image_ = dialog.selectedFiles().at(0);
+ load();
+ }
+
+ }
+
+
+ void main_window::load()
+ {
+ text_->hide();
+
+ mln::io::magick::load(input_, current_image_.toStdString());
+
+ input_dsp_ = QPixmap::fromImage(mln::convert::to_qimage_nocopy(input_));
+
+ viewer_->draw_image(input_dsp_);
+ }
+
+
+ void main_window::run()
+ {
+ preprocessing_task_set_t tasks = get_tasks();
+
+ prepare_progress_bar(tasks.size());
+
+ process_args args; // Nothing for now.
+
+ runner_.start(current_image_, input_, Text_Doc, tasks, args);
+ }
+
+
+ preprocessing_task_set_t main_window::get_tasks()
+ {
+ preprocessing_task_set_t tasks;
+
+ if (removeBg->isChecked())
+ tasks.insert(RemoveBg);
+
+ if (unskew->isChecked())
+ tasks.insert(Unskew);
+
+ if (removeNoise->isChecked())
+ tasks.insert(RemoveNoise);
+
+ if (improveContrast->isChecked())
+ tasks.insert(ImproveContrast);
+
+ if (reduceSize->isChecked())
+ tasks.insert(ReduceSize);
+
+ if (binarizationCBox->currentIndex() == 0)
+ tasks.insert(BinarizationSimple);
+ else if (binarizationCBox->currentIndex() == 1)
+ tasks.insert(BinarizationSauvola);
+ else if (binarizationCBox->currentIndex() == 2)
+ tasks.insert(BinarizationSauvolaMs);
+
+ return tasks;
+ }
+
+
+ void main_window::prepare_progress_bar(unsigned max)
+ {
+ progress_->show();
+ progress_->setValue(0);
+ progress_->setMaximum(max + 3);
+ }
+
+
+ void main_window::progress_slot(unsigned i)
+ {
+ progress_->setValue(progress_->value() + i);
+ }
+
+
+ void main_window::update_progress_label_slot(const QString& msg)
+ {
+ progress_->setLabelText(msg);
+ }
+
+
+ void main_window::process_finished_slot()
+ {
+ text_->clear();
+
+ QFile file("/tmp/out.txt");
+ if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
+ return;
+
+ QTextStream in(&file);
+ in.setCodec("UTF-8");
+ while (!in.atEnd())
+ {
+ QString line = in.readLine();
+ text_->append(line);
+ }
+
+
+ text_->show();
+ }
+
+
+ void main_window::crop_slot()
+ {
+ mln::box2d b = input_.domain();
+ QRectF selection = viewer_->selection();
+
+ mln::box2d sbox = mln::make::box2d(selection.topLeft().y(),
+ selection.topLeft().x(),
+ selection.bottomRight().y(),
+ selection.bottomRight().x());
+
+ sbox.crop_wrt(b);
+
+ if (sbox.is_valid())
+ {
+ // Update underlying data.
+ mln::image2d<mln::value::rgb8> output(sbox);
+ mln::data::fill(output, input_);
+ input_ = output;
+
+ // Update display
+ viewer_->draw_image(input_);
+ }
+
+ viewer_->enable_crop_tool(false); // Disable crop tool
+ }
+
+ } // end of namespace scribo::demo::demat
+
+ } // end of namespace scribo::demo
+
+} // end of namespace scribo
diff --git a/scribo/demo/demat/src/main_window.hh b/scribo/demo/demat/src/main_window.hh
new file mode 100644
index 0000000..f52f171
--- /dev/null
+++ b/scribo/demo/demat/src/main_window.hh
@@ -0,0 +1,91 @@
+// 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/>.
+//
+// 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 SCRIBO_DEMO_DEMAT_SRC_MAIN_WINDOW_HH
+# define SCRIBO_DEMO_DEMAT_SRC_MAIN_WINDOW_HH
+
+# include <QtGui/QMainWindow>
+# include <ui_main_window.h>
+# include <src/doc_type.hh>
+# include <src/preprocessing_task.hh>
+# include <src/runner.hh>
+
+# include <mln/core/image/image2d.hh>
+# include <mln/core/image/dmorph/image_if.hh>
+# include <mln/pw/all.hh>
+# include <mln/value/rgb8.hh>
+
+
+namespace scribo
+{
+
+ namespace demo
+ {
+
+ namespace demat
+ {
+
+
+ class main_window : public QMainWindow, private Ui::MainWindow
+ {
+ Q_OBJECT;
+
+ public:
+ main_window();
+
+ private slots:
+ void run();
+ void open_file_slot();
+ void progress_slot(unsigned i);
+ void update_progress_label_slot(const QString&);
+ void process_finished_slot();
+
+ void crop_slot();
+
+ private: // members
+ void load();
+
+ void prepare_progress_bar(unsigned max);
+ Doc_Type get_doc_type();
+ preprocessing_task_set_t get_tasks();
+
+ private: // attributes
+ QPixmap input_dsp_;
+
+ QString current_image_;
+
+ QProgressDialog* progress_;
+ runner runner_;
+ };
+
+
+ } // end of namespace scribo::demo::demat
+
+ } // end of namespace scribo::demo
+
+} // end of namespace scribo
+
+
+#endif // ! SCRIBO_DEMO_DEMAT_SRC_MAIN_WINDOW_HH
diff --git a/scribo/demo/demat/src/mln_widgets.cc b/scribo/demo/demat/src/mln_widgets.cc
new file mode 100644
index 0000000..079fc7f
--- /dev/null
+++ b/scribo/demo/demat/src/mln_widgets.cc
@@ -0,0 +1,11 @@
+#undef MLN_INCLUDE_ONLY
+
+// Windows
+#include <src/main_window.cc>
+
+// Widgets
+#include <shared/src/image_viewer.cc>
+
+// Misc
+#include <src/main.cc>
+#include <src/runner.cc>
diff --git a/scribo/demo/wizard/src/preprocessing_task.hh
b/scribo/demo/demat/src/preprocessing_task.hh
similarity index 100%
copy from scribo/demo/wizard/src/preprocessing_task.hh
copy to scribo/demo/demat/src/preprocessing_task.hh
diff --git a/scribo/demo/demat/src/process_args.hh
b/scribo/demo/demat/src/process_args.hh
new file mode 100644
index 0000000..5ca72cf
--- /dev/null
+++ b/scribo/demo/demat/src/process_args.hh
@@ -0,0 +1,47 @@
+// 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/>.
+//
+// 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 SCRIBO_DEMO_SHARED_SRC_PROCESS_ARGS_HH
+# define SCRIBO_DEMO_SHARED_SRC_PROCESS_ARGS_HH
+
+
+namespace scribo
+{
+
+ namespace demo
+ {
+
+ struct process_args
+ {
+ unsigned scale;
+ };
+
+
+ } // end of namespace scribo::demo
+
+} // end of namespace scribo
+
+
+#endif // !SCRIBO_DEMO_SHARED_SRC_PROCESS_ARGS_HH
diff --git a/scribo/demo/demat/src/runner.cc b/scribo/demo/demat/src/runner.cc
new file mode 100644
index 0000000..6972902
--- /dev/null
+++ b/scribo/demo/demat/src/runner.cc
@@ -0,0 +1,316 @@
+#include <src/runner.hh>
+
+#include <shared/src/to_mln_image.hh>
+#include <src/preprocessing_task.hh>
+#include <src/doc_type.hh>
+
+#include <mln/convert/to_qimage.hh>
+#include <mln/convert/to_qimage_nocopy.hh>
+#include <mln/fun/v2v/rgb_to_int_u.hh>
+#include <mln/value/int_u8.hh>
+#include <mln/value/rgb8.hh>
+#include <mln/data/convert.hh>
+#include <mln/data/paste_without_localization.hh>
+#include <mln/io/pbm/save.hh>
+#include <mln/io/magick/load.hh>
+#include <mln/subsampling/antialiased.hh>
+
+#include <scribo/preprocessing/split_bg_fg.hh>
+#include <scribo/preprocessing/denoise.hh>
+#include <scribo/preprocessing/homogeneous_contrast.hh>
+#include <scribo/preprocessing/unskew.hh>
+#include <scribo/binarization/sauvola.hh>
+#include <scribo/binarization/sauvola_ms.hh>
+#include <scribo/binarization/simple.hh>
+
+#include <mln/logical/not.hh>
+
+namespace scribo
+{
+
+ namespace demo
+ {
+
+ QString basedir_ = "";
+
+ // FIXME: move as attribute.
+ mln::image2d<mln::value::rgb8> input_;
+
+
+ runner::runner(QObject *parent)
+ : QThread(parent)
+ {
+ process_.moveToThread(this);
+ }
+
+
+ void runner::start(const QString& filename,
+ const mln::image2d<mln::value::rgb8>& input,
+ const Doc_Type& doc_type,
+ const preprocessing_task_set_t& tasks,
+ const process_args& args)
+ {
+ filename_ = filename;
+ doc_type_ = doc_type;
+ tasks_ = tasks;
+ args_ = args;
+ input_ = input;
+
+ QThread::start();
+ }
+
+
+ void runner::run()
+ {
+ // Notification of the number of tasks.
+ emit new_progress_max_value(tasks_.size() + 2);
+
+ qDebug() << "progress steps : " << tasks_.size() + 2;
+
+ image2d<value::rgb8> ima = load();
+
+ preprocess(ima);
+
+ process();
+ }
+
+
+ image2d<value::rgb8> runner::load()
+ {
+ emit new_progress_label("Loading image");
+
+ image2d<value::rgb8> output(input_.nrows(), input_.ncols(),
+ input_.border());
+ data::paste_without_localization(input_, output);
+
+// io::magick::load(output, filename_.toStdString());
+
+ emit progress(1);
+
+ return output;
+ }
+
+
+ void runner::preprocess(const image2d<value::rgb8>& ima)
+ {
+
+ image2d<value::rgb8> tmp_color = duplicate(ima);
+
+
+ //==================
+ // Remove background
+ //==================
+ if (tasks_.contains(RemoveBg))
+ {
+ std::cout << "Foreground extraction" << std::endl;
+ emit new_progress_label("Foreground Extraction");
+
+ tmp_color = scribo::preprocessing::split_bg_fg(tmp_color, 10000, 32).second();
+
+ emit progress(1);
+ }
+
+
+ //=============================================
+ // Convert to grayscale image (always happens).
+ //=============================================
+ emit new_progress_label("Convert to gray-scale image");
+ image2d<value::int_u8>
+ intensity_ima = data::transform(tmp_color,
+ mln::fun::v2v::rgb_to_int_u<8>());
+ emit progress(1);
+
+
+ // FIXME: SUbsampling should be done at the very beginning!!!!
+ //
+ //==========
+ // Subsample
+ //==========
+ if (tasks_.contains(ReduceSize))
+ {
+ emit new_progress_label("Subsampling input image");
+ intensity_ima = mln::subsampling::antialiased(intensity_ima,
+ find_best_scale(intensity_ima));
+ emit progress(1);
+ }
+
+
+ //=============================
+ // Improve contrast homogeneity
+ //=============================
+ if (tasks_.contains(ImproveContrast))
+ {
+ std::cout << "Improve contrast homogeneity" << std::endl;
+ emit new_progress_label("Improve contrast homogeneity");
+
+ intensity_ima = arith::revert(preprocessing::homogeneous_contrast(intensity_ima, 75));
+
+ emit progress(1);
+ }
+
+
+ std::cout << intensity_ima.domain() << std::endl;
+ io::pgm::save(intensity_ima, "intensity_ima.pgm");
+
+ //==============================
+ // Binarization (always happens)
+ //==============================
+ image2d<bool> out_bool;
+ emit new_progress_label("Binarization");
+
+ if (tasks_.contains(BinarizationSauvola))
+ {
+ // FIXME: sauvola should not negate the image.
+ std::cout << "Binarization Sauvola" << std::endl;
+ out_bool = binarization::sauvola(intensity_ima);
+ }
+ else if (tasks_.contains(BinarizationSauvolaMs))
+ {
+ // FIXME: sauvola should not negate the image.
+ std::cout << "Binarization Sauvola_ms" << std::endl;
+ out_bool = binarization::sauvola_ms(intensity_ima, 51, 2, 67);
+ }
+ else if (tasks_.contains(BinarizationSimple))
+ {
+ std::cout << "Binarization Simple" << std::endl;
+ out_bool = scribo::binarization::simple(intensity_ima);
+ }
+ else
+ {
+ std::cout << "Binary image conversion" << std::endl;
+ out_bool = data::convert(bool(), intensity_ima);
+ }
+
+ emit progress(1);
+
+
+ // FIXME: remove!
+// logical::not_inplace(out_bool);
+
+ //========
+ // Denoise
+ //========
+// if (tasks_.contains(RemoveNoise))
+// {
+// std::cout << "Remove noise" << std::endl;
+// emit new_progress_label("Remove noise");
+
+// out_bool = preprocessing::denoise(out_bool, c8(), 2, 2);
+
+// emit progress(1);
+// }
+
+ //=======
+ // Unskew
+ //=======
+ if (tasks_.contains(Unskew))
+ {
+ std::cout << "Unskew" << std::endl;
+ emit new_progress_label("Unskew");
+
+ out_bool = scribo::preprocessing::unskew(out_bool).first();
+
+ emit progress(1);
+ }
+
+
+ //=========================
+ // Save preprocessed image.
+ //=========================
+ io::pbm::save(out_bool, "/tmp/tmp.pbm");
+ }
+
+
+ void runner::process()
+ {
+ QStringList args;
+
+
+ // FIXME: require binaries to ask for a filename for bboxes
+ // output files.
+ switch(doc_type_)
+ {
+ case Text_Doc:
+ emit new_progress_label("Finding text in document...");
+ qDebug() << "Running text_in_article_pbm";
+ args << "/tmp/tmp.pbm" << "/tmp/out.txt";
+
+ // Denoise.
+ if (! tasks_.contains(RemoveNoise))
+ args << "0";
+ else
+ {
+ args << "1";
+ emit progress(1); // Consider denoising as done even though it is performed later.
+ }
+
+ args << "/tmp/";
+
+ if (process_.execute(basedir_ + "/text_in_article_pbm", args))
+ {
+ qDebug() << "Error while running text_in_article_pbm.";
+ return;
+ }
+ break;
+
+ case Picture:
+ emit new_progress_label("Finding text in picture...");
+ qDebug() << "Running text_in_photo_pbm_fast";
+ args << "/tmp/tmp.pbm" << "/tmp/out.ppm" <<
"1" << "1" << "1";
+ if (process_.execute(basedir_ + "/text_in_photo_pbm_fast", args))
+ {
+ qDebug() << "Error while running text_in_photo_pbm_fast.";
+ return;
+ }
+ break;
+
+ case Mixed_Doc:
+ qDebug() << "Running pbm_text_in_mixed_doc";
+ if (process_.execute(basedir_ + "/pbm_text_in_mixed_doc", args))
+ {
+ qDebug() << "Error while running pbm_text_in_mixed_doc.";
+ return;
+ }
+ break;
+
+ default:
+ case Invalid_Doc:
+ qDebug() << "runner - Invalid doc type...";
+ return;
+ }
+
+ process_.waitForFinished(-1);
+
+ emit progress(1);
+
+ emit finished();
+ qDebug() << "Done";
+ }
+
+
+ void runner::stop()
+ {
+ process_.kill();
+ terminate();
+ }
+
+
+ template <typename V>
+ unsigned runner::find_best_scale(const image2d<V>& ima)
+ {
+ if (ima.nrows() > 2500
+ && ima.nrows() < 5000
+ && ima.ncols() > 2500
+ && ima.ncols() < 5000)
+ return 2;
+
+ if (ima.nrows() > 5000
+ && ima.ncols() > 5000)
+ return 3;
+
+ return 1;
+ }
+
+ } // end of namespace scribo::demo
+
+} // end of namespace scribo
diff --git a/scribo/demo/demat/src/runner.hh b/scribo/demo/demat/src/runner.hh
new file mode 100644
index 0000000..93e91bc
--- /dev/null
+++ b/scribo/demo/demat/src/runner.hh
@@ -0,0 +1,93 @@
+// 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/>.
+//
+// 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 SCRIBO_DEMO_SHARED_SRC_RUNNER_HH
+# define SCRIBO_DEMO_SHARED_SRC_RUNNER_HH
+
+# include <QtGui>
+# include <QProcess>
+
+# include <src/preprocessing_task.hh>
+# include <src/doc_type.hh>
+
+# include <mln/core/image/image2d.hh>
+# include <mln/value/qt/rgb32.hh>
+
+#include <src/process_args.hh>
+
+namespace scribo
+{
+
+ namespace demo
+ {
+
+
+ class runner : public QThread
+ {
+ Q_OBJECT;
+
+ public:
+ runner(QObject *parent = 0);
+
+ void start(const QString& filename,
+ const mln::image2d<mln::value::rgb8>& input,
+ const Doc_Type& doc_type,
+ const preprocessing_task_set_t& tasks,
+ const process_args& args);
+
+ void stop();
+
+ signals:
+ void new_intermediate_result(const QImage& ima);
+ void new_progress_max_value(unsigned i);
+ void new_progress_label(const QString& msg);
+ void progress(unsigned i);
+ void finished();
+
+ private: // members
+ mln::image2d<mln::value::rgb8> load();
+ void preprocess(const mln::image2d<mln::value::rgb8>& ima);
+ void process();
+ virtual void run();
+
+ template <typename V>
+ unsigned find_best_scale(const mln::image2d<V>& ima);
+
+ private: // attributes
+ QProcess process_;
+ Doc_Type doc_type_;
+ QSet<Preprocessing_Task> tasks_;
+ QString filename_;
+ process_args args_;
+ };
+
+
+
+ } // end of namespace scribo::demo
+
+} // end of namespace scribo
+
+
+#endif // ! SCRIBO_DEMO_SHARED_SRC_RUNNER_HH
diff --git a/scribo/demo/demat/ui/main_window.ui b/scribo/demo/demat/ui/main_window.ui
new file mode 100644
index 0000000..a552500
--- /dev/null
+++ b/scribo/demo/demat/ui/main_window.ui
@@ -0,0 +1,366 @@
+<ui version="4.0" >
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>666</width>
+ <height>647</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>MainWindow</string>
+ </property>
+ <widget class="QWidget" name="centralwidget" >
+ <layout class="QVBoxLayout" name="verticalLayout" >
+ <item>
+ <widget class="QSplitter" name="splitter" >
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <widget class="scribo::demo::shared::image_viewer"
name="viewer_" />
+ <widget class="QTextEdit" name="text_" />
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout" >
+ <item>
+ <spacer name="horizontalSpacer" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="run_btn" >
+ <property name="text" >
+ <string>&Run</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QMenuBar" name="menubar" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>666</width>
+ <height>24</height>
+ </rect>
+ </property>
+ <widget class="QMenu" name="menu_File" >
+ <property name="title" >
+ <string>&File</string>
+ </property>
+ <addaction name="action_Open" />
+ <addaction name="separator" />
+ <addaction name="action_Quit" />
+ </widget>
+ <widget class="QMenu" name="menuWindow" >
+ <property name="title" >
+ <string>&Dialogs</string>
+ </property>
+ <addaction name="actionOptions" />
+ <addaction name="actionAdvanced_options" />
+ </widget>
+ <addaction name="menu_File" />
+ <addaction name="menuWindow" />
+ </widget>
+ <widget class="QStatusBar" name="statusbar" />
+ <widget class="QDockWidget" name="options_dock_" >
+ <property name="font" >
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="floating" >
+ <bool>false</bool>
+ </property>
+ <property name="features" >
+ <set>QDockWidget::AllDockWidgetFeatures</set>
+ </property>
+ <property name="allowedAreas" >
+ <set>Qt::AllDockWidgetAreas</set>
+ </property>
+ <property name="windowTitle" >
+ <string>Options</string>
+ </property>
+ <attribute name="dockWidgetArea" >
+ <number>1</number>
+ </attribute>
+ <widget class="QWidget" name="dockWidgetContents" >
+ <layout class="QVBoxLayout" name="verticalLayout_7" >
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_4" >
+ <item>
+ <widget class="QCheckBox" name="removeBg" >
+ <property name="font" >
+ <font>
+ <weight>50</weight>
+ <bold>false</bold>
+ </font>
+ </property>
+ <property name="text" >
+ <string>Remove background (slow)</string>
+ </property>
+ <property name="checked" >
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="unskew" >
+ <property name="font" >
+ <font>
+ <weight>50</weight>
+ <bold>false</bold>
+ </font>
+ </property>
+ <property name="text" >
+ <string>Unskew</string>
+ </property>
+ <property name="checked" >
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="removeNoise" >
+ <property name="enabled" >
+ <bool>true</bool>
+ </property>
+ <property name="font" >
+ <font>
+ <weight>50</weight>
+ <bold>false</bold>
+ </font>
+ </property>
+ <property name="text" >
+ <string>Remove noise</string>
+ </property>
+ <property name="checked" >
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="improveContrast" >
+ <property name="enabled" >
+ <bool>true</bool>
+ </property>
+ <property name="font" >
+ <font>
+ <weight>50</weight>
+ <bold>false</bold>
+ </font>
+ </property>
+ <property name="text" >
+ <string>Improve brightness/contrast</string>
+ </property>
+ <property name="checked" >
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_3" >
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ <widget class="QDockWidget" name="advanced_dock_" >
+ <property name="font" >
+ <font>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="windowTitle" >
+ <string>Advanced options</string>
+ </property>
+ <attribute name="dockWidgetArea" >
+ <number>1</number>
+ </attribute>
+ <widget class="QWidget" name="dockWidgetContents_3" >
+ <layout class="QVBoxLayout" name="verticalLayout_8" >
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2" >
+ <item>
+ <widget class="QCheckBox" name="reduceSize" >
+ <property name="font" >
+ <font>
+ <weight>50</weight>
+ <bold>false</bold>
+ </font>
+ </property>
+ <property name="text" >
+ <string>Run on subsampled image</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_6" >
+ <item>
+ <widget class="QLabel" name="binarizeLbl" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Preferred"
>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="font" >
+ <font>
+ <weight>50</weight>
+ <bold>false</bold>
+ </font>
+ </property>
+ <property name="text" >
+ <string>Binarization method:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="binarizationCBox" >
+ <property name="font" >
+ <font>
+ <weight>50</weight>
+ <bold>false</bold>
+ </font>
+ </property>
+ <property name="currentIndex" >
+ <number>2</number>
+ </property>
+ <item>
+ <property name="text" >
+ <string>Global threshold</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Local threshold</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Local threshold multi-scale</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_2" >
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0" >
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ <action name="action_Open" >
+ <property name="text" >
+ <string>&Open</string>
+ </property>
+ <property name="shortcut" >
+ <string>Ctrl+O</string>
+ </property>
+ </action>
+ <action name="action_Quit" >
+ <property name="text" >
+ <string>&Quit</string>
+ </property>
+ </action>
+ <action name="actionDocument_Type" >
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ <property name="checked" >
+ <bool>true</bool>
+ </property>
+ <property name="text" >
+ <string>Document Type</string>
+ </property>
+ </action>
+ <action name="actionOptions" >
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ <property name="checked" >
+ <bool>true</bool>
+ </property>
+ <property name="text" >
+ <string>Options</string>
+ </property>
+ </action>
+ <action name="actionAdvanced_options" >
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ <property name="checked" >
+ <bool>true</bool>
+ </property>
+ <property name="text" >
+ <string>Advanced options</string>
+ </property>
+ </action>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>scribo::demo::shared::image_viewer</class>
+ <extends>QGraphicsView</extends>
+ <header location="global" >shared/src/image_viewer.hh</header>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>action_Quit</sender>
+ <signal>activated()</signal>
+ <receiver>MainWindow</receiver>
+ <slot>close()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>-1</x>
+ <y>-1</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>332</x>
+ <y>298</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/scribo/demo/shared/src/crop_item.cc b/scribo/demo/shared/src/crop_item.cc
index 100ac7d..70598fa 100644
--- a/scribo/demo/shared/src/crop_item.cc
+++ b/scribo/demo/shared/src/crop_item.cc
@@ -46,6 +46,11 @@ namespace scribo
grabMouse();
}
+ crop_item::~crop_item()
+ {
+
+ }
+
void crop_item::reset()
{
if (parentItem())
@@ -54,15 +59,15 @@ namespace scribo
cropRect_ = QRectF(20, 20, 100, 70);
}
- const QRectF& crop_item::cropRect() const
+ QRectF crop_item::cropRect() const
{
- return cropRect_;
+ return mapToScene(cropRect_).boundingRect();
}
QRectF crop_item::boundingRect() const
{
- return parentItem()->boundingRect();
+ return scene()->sceneRect();
}
void crop_item::paint(QPainter *painter,
@@ -84,15 +89,16 @@ namespace scribo
painter->fillPath(windowPath, QColor(0x33, 0x33, 0x33, 0xcc));
// Draw Crop Rect
- painter->setPen(QPen(QColor(0xdd, 0xdd, 0xdd), 1));
+ // QColor(0xdd, 0xdd, 0xdd)
+ painter->setPen(QPen(Qt::magenta, 3));
painter->drawPath(cropPath);
int topRightX = cropRect_.x() + cropRect_.width();
int bottomY = cropRect_.y() + cropRect_.height();
QPainterPath borderPath;
- int corner_width = cropRect_.width() / 6.f;
- int corner_height = cropRect_.height() / 6.f;
+ int corner_width = std::min(int(cropRect_.width() / 6.f), 80);
+ int corner_height = std::min(int(cropRect_.height() / 6.f), 80);
// Top-Left Corner
painter->drawRect(QRectF(cropRect_.x(), cropRect_.y(),
@@ -128,8 +134,8 @@ namespace scribo
cropResize_ = CropItemResizeNone;
if (event->buttons() & Qt::LeftButton)
{
- int wsize = cropRect_.width() / 6.f;
- int hsize = cropRect_.height() / 6.f;
+ int wsize = std::min(int(cropRect_.width() / 6.f), 80);
+ int hsize = std::min(int(cropRect_.height() / 6.f), 80);
int rightX = cropRect_.x() + cropRect_.width() - wsize;
int leftX = cropRect_.x();
@@ -305,6 +311,29 @@ namespace scribo
}
+ void crop_item::mouseDoubleClickEvent(QGraphicsSceneMouseEvent * event)
+ {
+ QGraphicsItem::mouseDoubleClickEvent(event);
+
+ switch (cropResize_)
+ {
+ case CropItemResizeNone:
+ if (!cropRect_.contains(event->pos()))
+ return;
+
+ setCursor(Qt::SizeAllCursor);
+
+ if (!(event->buttons() & Qt::LeftButton))
+ return;
+
+ emit ready_for_crop();
+ break;
+
+ default:
+ break;
+ }
+ }
+
} // end of namespace scribo::demo::shared
} // end of namespace scribo::demo
diff --git a/scribo/demo/shared/src/crop_item.hh b/scribo/demo/shared/src/crop_item.hh
index c0b1394..d342f23 100644
--- a/scribo/demo/shared/src/crop_item.hh
+++ b/scribo/demo/shared/src/crop_item.hh
@@ -50,11 +50,15 @@ namespace scribo
namespace shared
{
- class crop_item : public QGraphicsItem
+ class crop_item : public QObject, public QGraphicsItem
{
+ Q_OBJECT;
+
public:
crop_item(QGraphicsItem *parent);
- const QRectF& cropRect() const;
+ virtual ~crop_item();
+
+ QRectF cropRect() const;
QRectF boundingRect() const;
void paint (QPainter *painter,
@@ -67,9 +71,13 @@ namespace scribo
void mousePressEvent (QGraphicsSceneMouseEvent *event);
void mouseReleaseEvent (QGraphicsSceneMouseEvent *event);
void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
+ void mouseDoubleClickEvent(QGraphicsSceneMouseEvent * event);
// void updateCursor(QGraphicsSceneMouseEvent *event);
+ signals:
+ void ready_for_crop();
+
private:
enum CropItemResize
{
diff --git a/scribo/demo/shared/src/image_viewer.cc
b/scribo/demo/shared/src/image_viewer.cc
index b61f86b..f9467dc 100644
--- a/scribo/demo/shared/src/image_viewer.cc
+++ b/scribo/demo/shared/src/image_viewer.cc
@@ -38,7 +38,8 @@ namespace scribo
{
image_viewer::image_viewer(QWidget *parent)
- : QWidget(parent), image_(0), selection_(0), angle_(0)
+ : QWidget(parent), image_(0), selection_(0), angle_(0),
+ zoom_fixed_(false)
{
setupUi(this);
@@ -87,7 +88,8 @@ namespace scribo
viewer_->show();
}
- void image_viewer::draw_image(const mln::image2d<dsp_data_t>& ima)
+ template <typename V>
+ void image_viewer::draw_image(const mln::image2d<V>& ima)
{
QImage
qima = mln::convert::to_qimage_nocopy(ima);
@@ -127,18 +129,15 @@ namespace scribo
if (pixmap.width() > viewer_->maximumViewportSize().width())
viewer_->fitInView(image_->boundingRect(), Qt::KeepAspectRatio);
- zoomLabel->setEnabled(true);
- zoomIn->setEnabled(true);
- zoomOut->setEnabled(true);
- zoomFixed->setEnabled(true);
- zoomOriginal->setEnabled(true);
+ enable_widgets(true);
image_->translate(origin.x(), origin.y());
+
viewer_->setSceneRect(image_->sceneBoundingRect());
// Restore selection mode if needed
- set_selection_enabled(restore_selection);
+ on_crop_btn_toggled(restore_selection);
}
@@ -150,8 +149,11 @@ namespace scribo
void image_viewer::resizeEvent(QResizeEvent * event)
{
- if (image_ != 0)
- resize_image(image_->boundingRect());
+ if (zoom_fixed_)
+ on_zoomFixed_clicked();
+ else
+ on_zoomOriginal_clicked();
+
event->ignore();
}
@@ -238,12 +240,14 @@ namespace scribo
void image_viewer::on_zoomFixed_clicked()
{
+ zoom_fixed_ = true;
if (image_ != 0)
resize_image(image_->boundingRect());
}
void image_viewer::on_zoomOriginal_clicked()
{
+ zoom_fixed_ = false;
if (image_ != 0)
resize_image(viewer_->viewport()->geometry());
}
@@ -259,12 +263,17 @@ namespace scribo
}
}
- void image_viewer::set_selection_enabled(bool b)
+ void image_viewer::on_crop_btn_toggled(bool b)
{
if (b)
{
if (selection_ == 0)
+ {
selection_ = new crop_item(image_);
+ connect(selection_, SIGNAL(ready_for_crop()),
+ this, SIGNAL(ready_for_crop()));
+
+ }
}
else
{
@@ -274,6 +283,18 @@ namespace scribo
}
+ void image_viewer::enable_crop_tool(bool b)
+ {
+ crop_btn->setChecked(b);
+ }
+
+
+ void image_viewer::set_selection_enabled(bool b)
+ {
+ crop_btn->setVisible(b);
+ }
+
+
void image_viewer::set_rotation_enabled(bool b)
{
angle_ = 0;
@@ -290,12 +311,11 @@ namespace scribo
}
- const QRectF& image_viewer::selection() const
+ QRectF image_viewer::selection() const
{
static QRectF invalid_selection;
- mln_assertion(has_selection());
- if (selection_)
+ if (has_selection())
return selection_->cropRect();
return invalid_selection;
@@ -337,6 +357,23 @@ namespace scribo
on_slider_valueChanged(sli);
}
+
+ void image_viewer::enable_widgets(bool b)
+ {
+ zoomLabel->setEnabled(b);
+ zoomIn->setEnabled(b);
+ zoomOut->setEnabled(b);
+ zoomFixed->setEnabled(b);
+ zoomOriginal->setEnabled(b);
+
+ rotate_ccw_btn->setEnabled(b);
+ rotate_cw_btn->setEnabled(b);
+ rotate_lbl->setEnabled(b);
+
+ crop_btn->setEnabled(b);
+ }
+
+
} // end of namespace scribo::demo::shared
} // end of namespace scribo::demo
diff --git a/scribo/demo/shared/src/image_viewer.hh
b/scribo/demo/shared/src/image_viewer.hh
index 628f5d4..3fe23ab 100644
--- a/scribo/demo/shared/src/image_viewer.hh
+++ b/scribo/demo/shared/src/image_viewer.hh
@@ -60,7 +60,8 @@ namespace scribo
image_viewer(QWidget *parent = 0);
~image_viewer();
- void draw_image(const mln::image2d<dsp_data_t>& ima);
+ template <typename V>
+ void draw_image(const mln::image2d<V>& ima);
void draw_image(const QPixmap& pixmap);
void draw_image(const QPixmap& pixmap, const QPoint& origin);
@@ -76,7 +77,7 @@ namespace scribo
bool has_selection() const;
- const QRectF& selection() const;
+ QRectF selection() const;
bool has_rotation() const;
qreal rotation() const;
@@ -91,12 +92,16 @@ namespace scribo
void keyPressEvent(QKeyEvent *event);
void resizeEvent(QResizeEvent * event);
+ void enable_widgets(bool b);
+
private slots:
void visible_slider(bool b);
void move_vertical_sliders(int value);
void move_horizontal_sliders(int value);
+ void on_crop_btn_toggled(bool b);
+
void on_slider_valueChanged(int sli);
void on_rotate_cw_btn_clicked();
@@ -111,10 +116,11 @@ namespace scribo
public slots:
void set_image_layer_count(unsigned nslis);
void update_image(const mln::image2d<dsp_data_t>& ima);
-
+ void enable_crop_tool(bool b);
signals:
void slider_valueChanged(int sli);
+ void ready_for_crop();
private: // attributes
QGraphicsPixmapItem* image_;
@@ -122,6 +128,8 @@ namespace scribo
bool mouse_moving_;
QPoint p_start_;
qreal angle_;
+
+ bool zoom_fixed_;
};
diff --git a/scribo/demo/shared/ui/image_viewer.ui
b/scribo/demo/shared/ui/image_viewer.ui
index d6f80cb..c129b97 100644
--- a/scribo/demo/shared/ui/image_viewer.ui
+++ b/scribo/demo/shared/ui/image_viewer.ui
@@ -5,7 +5,7 @@
<rect>
<x>0</x>
<y>0</y>
- <width>464</width>
+ <width>529</width>
<height>350</height>
</rect>
</property>
@@ -37,7 +37,33 @@
</spacer>
</item>
<item>
+ <widget class="QPushButton" name="crop_btn" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ <property name="maximumSize" >
+ <size>
+ <width>16777215</width>
+ <height>20</height>
+ </size>
+ </property>
+ <property name="text" >
+ <string>Crop</string>
+ </property>
+ <property name="icon" >
+ <iconset resource="../shared.qrc" >
+
<normaloff>:/icons/icons/crop-icon.png</normaloff>:/icons/icons/crop-icon.png</iconset>
+ </property>
+ <property name="checkable" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
<widget class="QLabel" name="rotate_lbl" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
<property name="text" >
<string>Rotate:</string>
</property>
@@ -45,6 +71,9 @@
</item>
<item>
<widget class="QPushButton" name="rotate_cw_btn" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
<property name="toolTip" >
<string>Rotate clock-wise</string>
</property>
@@ -59,6 +88,9 @@
</item>
<item>
<widget class="QPushButton" name="rotate_ccw_btn" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
<property name="toolTip" >
<string>Rotate counter-clock-wise</string>
</property>
--
1.5.6.5