Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
abreheret committed May 9, 2018
2 parents 159a92d + a7106b4 commit ca1e6c4
Showing 7 changed files with 325 additions and 57 deletions.
6 changes: 6 additions & 0 deletions scripts_to_build/make.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
cd build
cd x64
cmake --build . --config Release
cmake --build . --config Release --target make_zip

PAUSE
8 changes: 8 additions & 0 deletions scripts_to_build/win_make_vc14_x64_abreheret_qt5.10.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
mkdir build
cd build
mkdir x64
cd x64
cmake -DQT5_DIR=D:/dev/Qt/5.10.0/msvc2015_64/lib/cmake -DCMAKE_PREFIX_PATH="D:/DEV/git/pl_all/pl_3rdparty/package" -G "Visual Studio 14 Win64" ../../..
REM cmake --build . --config Release

PAUSE
36 changes: 26 additions & 10 deletions src/image_canvas.cpp
Original file line number Diff line number Diff line change
@@ -5,12 +5,14 @@
#include <QtDebug>
#include <QtWidgets>

ImageCanvas::ImageCanvas(QWidget * parent, MainWindow *ui) :
QLabel(parent) ,
ImageCanvas::ImageCanvas(MainWindow *ui) :
QLabel() ,
_ui(ui),
_alpha(0.5),
_pen_size(30) {

_scroll_parent = new QScrollArea(ui);
setParent(_scroll_parent);
resize(800,600);
_scale = 1.0;
_initPixmap();
@@ -21,6 +23,14 @@ ImageCanvas::ImageCanvas(QWidget * parent, MainWindow *ui) :
_undo_list.clear();
_undo_index = 0;
_undo = false;

_scroll_parent->setBackgroundRole(QPalette::Dark);
_scroll_parent->setWidget(this);

}

ImageCanvas::~ImageCanvas() {
_scroll_parent->deleteLater();
}

void ImageCanvas::_initPixmap() {
@@ -52,7 +62,7 @@ void ImageCanvas::loadImage(const QString &filename) {
_undo_index = 0;
if (QFile(_mask_file).exists()) {
_mask = ImageMask(_mask_file,_ui->id_labels);
emit(_ui->button_watershed->released());
_ui->runWatershed(this);// button_watershed->released());
_ui->checkbox_manuel_mask->setChecked(true);
_undo_list.push_back(_mask);
_undo_index++;
@@ -72,12 +82,18 @@ void ImageCanvas::saveMask() {

_mask.id.save(_mask_file);
if (!_watershed.id.isNull()) {
QImage watershed_without_border = removeBorder(_watershed.id, _ui->id_labels);
watershed_without_border.save(_watershed_file);
QImage watershed = _watershed.id;
if (!_ui->checkbox_border_ws->isChecked()) {
watershed = removeBorder(_watershed.id, _ui->id_labels);
}
watershed.save(_watershed_file);
QFileInfo file(_img_file);
QString color_file = file.dir().absolutePath() + "/" + file.baseName() + "_color_mask.png";
idToColor(watershed_without_border, _ui->id_labels).save(color_file);
idToColor(watershed, _ui->id_labels).save(color_file);
}
_undo_list.clear();
_undo_index = 0;
_ui->setStarAtNameOfTab(false);
}

void ImageCanvas::scaleChanged(double scale) {
@@ -154,6 +170,7 @@ void ImageCanvas::mouseReleaseEvent(QMouseEvent * e) {
}
_undo_list.push_back(_mask);
_undo_index++;
_ui->setStarAtNameOfTab(true);
_ui->undo_action->setEnabled(true);
}

@@ -208,15 +225,14 @@ void ImageCanvas::clearMask() {
void ImageCanvas::wheelEvent(QWheelEvent * event) {
int delta = event->delta() > 0 ? 1 : -1;
if (Qt::ShiftModifier == event->modifiers()) {
_ui->scroll_area->verticalScrollBar()->setEnabled(false);
_scroll_parent->verticalScrollBar()->setEnabled(false);
int value = _ui->spinbox_pen_size->value() + delta * _ui->spinbox_pen_size->singleStep();
_ui->spinbox_pen_size->setValue(value);
emit(_ui->spinbox_pen_size->valueChanged(value));
setSizePen(value);
repaint();
} else if (Qt::ControlModifier == event->modifiers()) {
QScrollArea * sc = _ui->scroll_area;
sc->verticalScrollBar()->setEnabled(false);
_scroll_parent->verticalScrollBar()->setEnabled(false);
double value = _ui->spinbox_scale->value() + delta * _ui->spinbox_scale->singleStep();
value = std::min<double>(_ui->spinbox_scale->maximum(),value);
value = std::max<double>(_ui->spinbox_scale->minimum(), value);
@@ -225,7 +241,7 @@ void ImageCanvas::wheelEvent(QWheelEvent * event) {
scaleChanged(value);
repaint();
} else {
_ui->scroll_area->verticalScrollBar()->setEnabled(true);
_scroll_parent->verticalScrollBar()->setEnabled(true);
}
}

8 changes: 7 additions & 1 deletion src/image_canvas.h
Original file line number Diff line number Diff line change
@@ -6,6 +6,7 @@

#include <QLabel>
#include <QPen>
#include <QScrollArea>

class MainWindow;

@@ -14,7 +15,8 @@ class ImageCanvas : public QLabel {

public:

ImageCanvas(QWidget * parent, MainWindow *ui);
ImageCanvas(MainWindow *ui);
~ImageCanvas();

void setId(int id);
void setMask(const ImageMask & mask);
@@ -26,6 +28,8 @@ class ImageCanvas : public QLabel {
void refresh();
void updateMaskColor(const Id2Labels & labels) { _mask.updateColor(labels); }
void loadImage(const QString &file);
QScrollArea * getScrollParent() const { return _scroll_parent; }
bool isNotSaved() const { return _undo_list.size() > 1; }

protected:
void mouseMoveEvent(QMouseEvent * event) override;
@@ -46,9 +50,11 @@ public slots :

private:
MainWindow *_ui;

void _initPixmap();
void _drawFillCircle(QMouseEvent * e);

QScrollArea *_scroll_parent ;
double _scale ;
double _alpha ;
QImage _image ;
186 changes: 147 additions & 39 deletions src/main_window.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include "main_window.h"
#include "utils.h"

#include <QException>
#include <QDebug>
#include <QFileDialog>
#include <QMessageBox>
@@ -24,54 +24,67 @@ MainWindow::MainWindow(QWidget *parent, Qt::WindowFlags flags)
setupUi(this);
setWindowTitle(QApplication::translate("MainWindow", "PixelAnnotationTool " PIXEL_ANNOTATION_TOOL_GIT_TAG, Q_NULLPTR));
list_label->setSpacing(1);

scroll_area = new QScrollArea;
image_canvas = new ImageCanvas(scroll_area, this);
image_canvas = NULL;
save_action = new QAction(tr("&Save current image"), this);
close_tab_action = new QAction(tr("&Close current tab"), this);
undo_action = new QAction(tr("&Undo"), this);
redo_action = new QAction(tr("&Redo"), this);
undo_action->setShortcuts(QKeySequence::Undo);
redo_action->setShortcuts(QKeySequence::Redo);
save_action->setShortcut(Qt::CTRL+Qt::Key_S);
close_tab_action->setShortcut(Qt::CTRL + Qt::Key_W);
undo_action->setEnabled(false);
redo_action->setEnabled(false);

menuFile->addAction(save_action);
menuEdit->addAction(close_tab_action);
menuEdit->addAction(undo_action);
menuEdit->addAction(redo_action);

image_canvas->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
image_canvas->setScaledContents(true);

scroll_area->setBackgroundRole(QPalette::Dark);
scroll_area->setWidget(image_canvas);

setCentralWidget(scroll_area);

connect(spinbox_scale, SIGNAL(valueChanged(double)), image_canvas, SLOT(scaleChanged(double)));
connect(spinbox_alpha, SIGNAL(valueChanged(double)), image_canvas, SLOT(alphaChanged(double)));
connect(spinbox_pen_size, SIGNAL(valueChanged(int)), image_canvas, SLOT(setSizePen(int)));
connect(button_watershed, SIGNAL(released()), this, SLOT(runWatershed()));
connect(checkbox_watershed_mask, SIGNAL(clicked()), image_canvas, SLOT(update()));
connect(checkbox_manuel_mask, SIGNAL(clicked()), image_canvas, SLOT(update()));
connect(actionClear, SIGNAL(triggered()), image_canvas, SLOT(clearMask()));

connect(actionOpen_config_file, SIGNAL(triggered()), this, SLOT(loadConfigFile()));
connect(actionSave_config_file, SIGNAL(triggered()), this, SLOT(saveConfigFile()));

connect(undo_action, SIGNAL(triggered()), image_canvas, SLOT(undo()));
connect(redo_action, SIGNAL(triggered()), image_canvas, SLOT(redo()));
connect(save_action, SIGNAL(triggered()), image_canvas, SLOT(saveMask()));

tabWidget->clear();

connect(button_watershed , SIGNAL(released()) , this, SLOT(runWatershed() ));
connect(actionOpen_config_file, SIGNAL(triggered()) , this, SLOT(loadConfigFile()));
connect(actionSave_config_file, SIGNAL(triggered()) , this, SLOT(saveConfigFile()));
connect(close_tab_action , SIGNAL(triggered()) , this, SLOT(closeCurrentTab()));
connect(tabWidget , SIGNAL(tabCloseRequested(int)) , this, SLOT(closeTab(int) ));
connect(tabWidget , SIGNAL(currentChanged(int)) , this, SLOT(updateConnect(int)));
connect(tree_widget_img , SIGNAL(itemClicked(QTreeWidgetItem *,int)), this, SLOT(treeWidgetClicked()));

labels = defaulfLabels();

loadConfigLabels();

connect(list_label, SIGNAL(currentItemChanged(QListWidgetItem*, QListWidgetItem*)), this, SLOT(changeLabel(QListWidgetItem*, QListWidgetItem*)));
connect(list_label, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(changeColor(QListWidgetItem*)));
}


void MainWindow::closeCurrentTab() {
int index = tabWidget->currentIndex();
if(index>=0)
closeTab(index);
}

void MainWindow::closeTab(int index) {
ImageCanvas * ic = getImageCanvas(index);
if (ic == NULL)
throw std::logic_error("error index");

if (ic->isNotSaved()) {
QMessageBox::StandardButton reply = QMessageBox::question(this, "Current image is not saved",
"You will close the current image, Would you like saved image before ?", QMessageBox::Yes | QMessageBox::No);
if (reply == QMessageBox::Yes) {
ic->saveMask();
}
}

tabWidget->removeTab(index);
delete ic;
if (tabWidget->count() == 0 ) {
image_canvas = NULL;
}
}

void MainWindow::loadConfigLabels() {
list_label->clear();
QMapIterator<QString, LabelInfo> it(labels);
@@ -131,11 +144,98 @@ void MainWindow::changeLabel(QListWidgetItem* current, QListWidgetItem* previous
image_canvas->setId(labels[key].id);
}

void MainWindow::runWatershed() {
image_canvas->setWatershedMask(watershed(image_canvas->getImage(), image_canvas->getMask().id));
void MainWindow::runWatershed(ImageCanvas * ic) {
ic->setWatershedMask(watershed(ic->getImage(), ic->getMask().id));
checkbox_watershed_mask->setCheckState(Qt::CheckState::Checked);
//checkbox_manuel_mask->setCheckState(Qt::CheckState::Unchecked);
image_canvas->update();
ic->update();
}

void MainWindow::runWatershed() {
ImageCanvas * ic = image_canvas;
if( ic != NULL)
runWatershed(ic);
}

void MainWindow::setStarAtNameOfTab(bool star) {
if (tabWidget->count() > 0) {
int index = tabWidget->currentIndex();
QString name = tabWidget->tabText(index);
if (star && !name.endsWith("*")) { //add star
name += "*";
tabWidget->setTabText(index, name);
} else if (!star && name.endsWith("*")) { //remove star
int pos = name.lastIndexOf('*');
name = name.left(pos);
tabWidget->setTabText(index, name);
}
}
}

void MainWindow::updateConnect(const ImageCanvas * ic) {
if (ic == NULL) return;
connect(spinbox_scale, SIGNAL(valueChanged(double)), ic, SLOT(scaleChanged(double)));
connect(spinbox_alpha, SIGNAL(valueChanged(double)), ic, SLOT(alphaChanged(double)));
connect(spinbox_pen_size, SIGNAL(valueChanged(int)), ic, SLOT(setSizePen(int)));
connect(checkbox_watershed_mask, SIGNAL(clicked()), ic, SLOT(update()));
connect(checkbox_manuel_mask, SIGNAL(clicked()), ic, SLOT(update()));
connect(actionClear, SIGNAL(triggered()), ic, SLOT(clearMask()));
connect(undo_action, SIGNAL(triggered()), ic, SLOT(undo()));
connect(redo_action, SIGNAL(triggered()), ic, SLOT(redo()));
connect(save_action, SIGNAL(triggered()), ic, SLOT(saveMask()));
connect(checkbox_border_ws, SIGNAL(clicked()), ic, SLOT(update()));

}

void MainWindow::allDisconnnect(const ImageCanvas * ic) {
if (ic == NULL) return;
disconnect(spinbox_scale, SIGNAL(valueChanged(double)), ic, SLOT(scaleChanged(double)));
disconnect(spinbox_alpha, SIGNAL(valueChanged(double)), ic, SLOT(alphaChanged(double)));
disconnect(spinbox_pen_size, SIGNAL(valueChanged(int)), ic, SLOT(setSizePen(int)));
disconnect(checkbox_watershed_mask, SIGNAL(clicked()), ic, SLOT(update()));
disconnect(checkbox_manuel_mask, SIGNAL(clicked()), ic, SLOT(update()));
disconnect(actionClear, SIGNAL(triggered()), ic, SLOT(clearMask()));
disconnect(undo_action, SIGNAL(triggered()), ic, SLOT(undo()));
disconnect(redo_action, SIGNAL(triggered()), ic, SLOT(redo()));
disconnect(save_action, SIGNAL(triggered()), ic, SLOT(saveMask()));
disconnect(checkbox_border_ws, SIGNAL(clicked()), ic, SLOT(update()));
}

ImageCanvas * MainWindow::newImageCanvas() {
ImageCanvas * ic = new ImageCanvas( this);
ic->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
ic->setScaledContents(true);
updateConnect(ic);
return ic;
}

void MainWindow::updateConnect(int index) {
if (index < 0 || index >= tabWidget->count())
return;
allDisconnnect(image_canvas);
image_canvas = getImageCanvas(index);
updateConnect(image_canvas);
}

ImageCanvas * MainWindow::getImageCanvas(int index) {
QScrollArea * scroll_area = static_cast<QScrollArea *>(tabWidget->widget(index));
ImageCanvas * ic = static_cast<ImageCanvas*>(scroll_area->widget());
return ic;
}

int MainWindow::getImageCanvas(QString name, ImageCanvas * ic) {
for (int i = 0; i < tabWidget->count(); i++) {
if (tabWidget->tabText(i).startsWith(name) ) {
ic = getImageCanvas(i);
return i;
}
}
ic = newImageCanvas();
QString iDir = currentDir();
QString filepath(iDir + "/" + name);
ic->loadImage(filepath);
int index = tabWidget->addTab(ic->getScrollParent(), name);

return index;
}

QString MainWindow::currentDir() const {
@@ -154,14 +254,22 @@ QString MainWindow::currentFile() const {
return current->text(0);
}

void MainWindow::on_tree_widget_img_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous) {
QString iFile = currentFile();
QString iDir = currentDir();
if (iFile.isEmpty() || iDir.isEmpty())
return;

QString filepath(iDir + "/" + iFile);
image_canvas->loadImage(filepath);

void MainWindow::treeWidgetClicked() {
QString iFile = currentFile();
QString iDir = currentDir();
if (iFile.isEmpty() || iDir.isEmpty())
return;
allDisconnnect(image_canvas);
int index = getImageCanvas(iFile, image_canvas);
updateConnect(image_canvas);
tabWidget->setCurrentIndex(index);

}

void MainWindow::on_tree_widget_img_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous) {
treeWidgetClicked();
}

void MainWindow::on_actionOpenDir_triggered() {
Loading

0 comments on commit ca1e6c4

Please sign in to comment.