123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629 |
- #include "mainwindow.h"
- #include "annotationxml.h"
- #include "ui_mainwindow.h"
- #include <QImage>
- #include <QDebug>
- #include <QLabel>
- #include <QWidget>
- #include <QPainter>
- #include <QFileDialog>
- #include <QToolButton>
- #include <QGridLayout>
- #include <QMessageBox>
- #include <QStatusBar>
- #include <QTreeView>
- #include <QMenu>
- #include <QCursor>
- #include <QInputDialog>
- #include <QDateTime>
- #include <CSVReader.h>
- #include "changemask.h"
- #include "changepacket.h"
- #include "tinyxml2.h"
- #include "classoptions.h"
- #include "requestfromserver.h"
- #include "setids.h"
- QString toolTitel[] = { "Objekte Verstecken", "Verschieben", "Neues Objekt", "Kopieren", "Einfügen", "Löschen", "Zerschneiden", "Vergrößern", "Allgemeine Information" };
- QString toolBeschreibung[] {"Klicken sie mit der Linken Maustaste auf ein Objekt um es zu verstecken, oder wieder sichtbar zu machen.\nVersteckte Objekte werden von anderen Werkzeugen ignoriert.",
- "Halten sie die linke Maustaste gedrückt, um die Ecke eines Objektes zu verschieben, wenn sich die Maus in der Nähe befindet.\nBefindet sich keine Ecke in der Nähe der Maus, so wird eine neue Ecke erzeugt.",
- "Klicken sie mit der Linken Maustaste an die Stellen, wo die Ecken des neuen Objektes sind.\nUm den Vorgang abzuschließen klicken sie erneut auf die erste Ecke.\nMit Rechtsklick kann die vorherige Ecke wieder entfernt werden.",
- "Klicken sie mit der linken Maustaste auf das Objekt, welches sie kopieren möchten.",
- "Klicken sie mit der linken Maustaste auf ein Objekt, um die ID und die Klasse des kopierten Objektes auf dieses zu übertragen.\nKlicken sie an eine freie Stelle um eine Kopie des kopierten Objektes einzufügen.\nHalten sie die rechte Maustaste gedrückt, um das kopierte Objekt zu drehen.",
- "Halten sie die linke Maustaste gedrückt, um einen Bereich festzulegen, in dem alle Eckpunkte gelöscht werden sollen.",
- "Klicken sie auf zwei Eckpunkte eines Objektes, um es in zwei verschiedene Objekte zu zerschneiden.",
- "Halte die linke Maustaste gedrückt um ein Gebiet zu makieren, an welches herangezoomt werden soll.",
- "Klicken sie auf Öffnen und wählen sie einen Ordner aus, um eine annotierte Sequenz zu laden oder eine neue Sequenz zu erstellen."};
- MainWindow::MainWindow( QApplication *app, QWidget *parent ) :
- QMainWindow(parent),
- app( app ),
- ui(new Ui::MainWindow),
- contextMenu( 0 ),
- seq( 0 ),
- m( 0 ),
- serverAddress( "tcp://ob:55556" )
- {
- ui->setupUi(this);
- setWindowTitle( "Annotation GUI v. 1.0" );
- status = new QLabel( "fertig" );
- ui->statusBar->layout()->setSizeConstraint(QLayout::SetMinimumSize);
- status->setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum );
- ui->statusBar->layout()->addWidget( status );
- ui->statusBar->addWidget( status );
- workModel = new ArbeitsModel( this );
- ArbeitsController::initStaticController( workModel );
- v = new ArbeitsView( workModel, ui->viewWidget );
- v->setController( ArbeitsController::getController( MOVE ) );
- workModel->addView( v );
- ui->toolTitel->setText( toolTitel[ USERMODE_COUNT ] );
- ui->toolBeschreibung->setText( toolBeschreibung[ USERMODE_COUNT ] );
- ui->framesTree->setContextMenuPolicy( Qt::CustomContextMenu );
- ui->viewWidget->setContextMenuPolicy( Qt::CustomContextMenu );
- QList<QToolButton *> btnList = ui->buttons->findChildren<QToolButton*>();
- for( auto i = btnList.begin(); i != btnList.end(); i++ )
- {
- (*i)->setIconSize( (*i)->size() );
- }
- }
- MainWindow::~MainWindow()
- {
- if( seq )
- {
- QMessageBox::StandardButton reply = QMessageBox::question(this, "Achtung", "Möchten sie die Annotationen speichern?",
- QMessageBox::Yes|QMessageBox::No);
- if (reply == QMessageBox::Yes) {
- seq->saveToPath( status );
- }
- seq->refRelease();
- }
- delete status;
- delete ui;
- delete m;
- delete contextMenu;
- }
- void MainWindow::setupFrameTree()
- {
- ui->framesTree->setUpdatesEnabled(false);
- if( !seq )
- return;
- if( !m )
- {
- m = new FrameTreeModel();
- seq->refNew();
- m->setSequenz( seq );
- ui->framesTree->setModel( m );
- ui->framesTree->setSelectionMode( ui->framesTree->MultiSelection );
- }
- ui->framesTree->collapseAll();
- setFrameTreeSelection();
- repaintFrameTree();
- ui->framesTree->setUpdatesEnabled(true);
- }
- void MainWindow::setFrameTreeSelection()
- {
- ui->framesTree->expand( m->getCameraSelectionIndex() );
- ui->framesTree->expand( m->getFrameSelectionIndex() );
- ui->framesTree->selectionModel()->select( m->getCameraSelectionIndex(), QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows );
- ui->framesTree->selectionModel()->select( m->getFrameSelectionIndex(), QItemSelectionModel::Select | QItemSelectionModel::Rows );
- QList<QModelIndex> indices = m->getSelectedPackages();
- for( auto index = indices.begin(); index != indices.end(); index++ )
- ui->framesTree->selectionModel()->select( *index, QItemSelectionModel::Select | QItemSelectionModel::Rows );
- ui->framesTree->scrollTo(m->getFrameSelectionIndex());
- ui->framesTree->repaint();
- }
- void MainWindow::repaintFrameTree()
- {
- m->update();
- ui->framesTree->repaint();
- }
- void MainWindow::setMode( UserMode m )
- {
- if( workModel->getMode() == m )
- ArbeitsController::getController( m )->restartController();
- workModel->setMode( m );
- v->setController( ArbeitsController::getController( m ) );
- ui->toolTitel->setText( toolTitel[ workModel->getMode() ] );
- ui->toolBeschreibung->setText( toolBeschreibung[ workModel->getMode() ] );
- }
- Sequenz *MainWindow::getSequenz()
- {
- return seq;
- }
- void MainWindow::unselectButttons()
- {
- QList<QToolButton *> btnList = ui->buttons->findChildren<QToolButton*>();
- for( auto i = btnList.begin(); i != btnList.end(); i++ )
- {
- (*i)->setChecked( false );
- }
- }
- void MainWindow::requestFromServer()
- {
- if( serverAddress != "" )
- {
- Frame *f = seq->getFrame();
- RequestFromServer rfs( serverAddress, f );
- rfs.exec();
- f->setObjects( rfs.getObjects() );
- f->applyMask(*((Kamera*)f->getParent())->getMask());
- if( !seq->hasAnnotatedObjects() )
- {
- int id = 0;
- for( auto obj = f->getObjects().begin(); obj != f->getObjects().end(); obj++ )
- {
- (*obj)->setId( QString::number( id ) );
- seq->addObjectName( QString::number( id ) );
- id++;
- }
- }
- }
- else
- seq->getFrame()->setObjects( std::vector< std::vector< cv::Point > >());
- setupFrameTree();
- v->repaint();
- }
- void MainWindow::on_actionOpen_triggered()
- {
- QString path = QFileDialog::getExistingDirectory(this,
- tr("Open Image Directory"),
- "/studi-tmp/kstrohm",
- QFileDialog::ShowDirsOnly |
- QFileDialog::DontResolveSymlinks);
- if( path == "" )
- return;
- status->setText( "Lade Annotation ..." );
- AnnotationLoader loader( path, status );
- if( seq )
- seq->refRelease();
- seq = loader.getSequenz();
- if( !seq )
- {
- QMessageBox::StandardButton reply = QMessageBox::question(this, "Achtung", "In dem ausgewählten Ordner wurde keine Annotierte Sequenz gefunden. Möchten sie eine neue Sequenz erstellen?",
- QMessageBox::Yes|QMessageBox::No);
- if (reply == QMessageBox::Yes) {
- AnnotationCreator creator( path, status );
- seq = creator.getSequenz();
- if( !seq )
- {
- QMessageBox::critical( this, "Fehler", "Es ist ein Fehler beim erstellen der Sequenz aufgetreten." );
- }
- }
- }
- status->setText( "fertig" );
- if( seq )
- {
- ui->framesTree->setModel( 0 );
- delete m;
- m = 0;
- Frame *f = seq->getFrame();
- workModel->setFrame( f );
- workModel->setMask( seq->getCameras().at( seq->getSelectedCamera() )->getMask()->getDrawableImage() );
- workModel->notifyViews();
- if( f->isNotAnnotated() )
- requestFromServer();
- else
- setupFrameTree();
- setMode( MOVE );
- }
- }
- void MainWindow::on_actionNext_triggered()
- {
- ui->framesTree->selectionModel()->clear();
- int oldCam = seq->getSelectedCamera();
- QModelIndex camIndex = m->getCameraSelectionIndex();
- ui->framesTree->collapse( m->getFrameSelectionIndex() );
- seq->nextFrame();
- if(oldCam != seq->getSelectedCamera())
- ui->framesTree->collapse( camIndex );
- Frame *f = seq->getFrame();
- workModel->setFrame( f );
- workModel->setMask( seq->getCameras().at( seq->getSelectedCamera() )->getMask()->getDrawableImage() );
- workModel->notifyViews();
- if( f->isNotAnnotated() )
- requestFromServer();
- else
- setFrameTreeSelection();
- }
- void MainWindow::on_actionBefore_triggered()
- {
- ui->framesTree->selectionModel()->clear();
- int oldCam = seq->getSelectedCamera();
- QModelIndex camIndex = m->getCameraSelectionIndex();
- ui->framesTree->collapse( m->getFrameSelectionIndex() );
- seq->previousFrame();
- if(oldCam != seq->getSelectedCamera())
- ui->framesTree->collapse( camIndex );
- Frame *f = seq->getFrame();
- workModel->setFrame( f );
- workModel->setMask( seq->getCameras().at( seq->getSelectedCamera() )->getMask()->getDrawableImage() );
- workModel->notifyViews();
- if( f->isNotAnnotated() )
- requestFromServer();
- else
- setFrameTreeSelection();
- }
- void MainWindow::on_next_clicked()
- {
- on_actionNext_triggered();
- }
- void MainWindow::on_before_clicked()
- {
- on_actionBefore_triggered();
- }
- void MainWindow::on_zoom_out_clicked()
- {
- workModel->resetZoom();
- workModel->notifyViews();
- }
- void MainWindow::on_zoom_in_clicked()
- {
- unselectButttons();
- ui->zoom_in->setChecked( true );
- setMode( ZOOM_IN );
- v->repaint();
- }
- void MainWindow::on_remove_clicked()
- {
- unselectButttons();
- ui->remove->setChecked( true );
- setMode( DELETE );
- v->repaint();
- }
- void MainWindow::on_polygon_clicked()
- {
- unselectButttons();
- ui->polygon->setChecked( true );
- setMode( NEW );
- }
- void MainWindow::on_move_clicked()
- {
- unselectButttons();
- ui->move->setChecked( true );
- setMode( MOVE );
- }
- void MainWindow::on_framesTree_clicked(const QModelIndex &index)
- {
- if( ((FrameTreeNode*)index.internalPointer())->getDepth() == 2 )
- ((_ObjectPolygon*)index.internalPointer())->setSelected( ui->framesTree->selectionModel()->isSelected( index ) );
- ui->framesTree->selectionModel()->clear();
- int cam, fr;
- if( m && m->clickedOnFrame( index, cam, fr ) )
- {
- if( cam != seq->getSelectedCamera() || fr != seq->getSelectedFrame() )
- {
- if(cam != seq->getSelectedCamera())
- ui->framesTree->collapse( m->getCameraSelectionIndex() );
- ui->framesTree->collapse( m->getFrameSelectionIndex() );
- seq->selectFrame( cam, fr );
- Frame *f = seq->getFrame();
- workModel->setFrame( f );
- workModel->setMask( seq->getCameras().at( seq->getSelectedCamera() )->getMask()->getDrawableImage() );
- workModel->notifyViews();
- if( f->isNotAnnotated() )
- requestFromServer();
- }
- }
- if( ((FrameTreeNode*)index.internalPointer())->getDepth() == 0 )
- {
- if( ((FrameTreeNode*)index.internalPointer())->getIndex() != seq->getSelectedCamera() )
- {
- ui->framesTree->collapse( m->getCameraSelectionIndex() );
- ui->framesTree->collapse( m->getFrameSelectionIndex() );
- seq->selectFrame( ((FrameTreeNode*)index.internalPointer())->getIndex(), 0 );
- Frame *f = seq->getFrame();
- workModel->setFrame( f );
- workModel->setMask( seq->getCameras().at( seq->getSelectedCamera() )->getMask()->getDrawableImage() );
- workModel->notifyViews();
- if( f->isNotAnnotated() )
- requestFromServer();
- }
- }
- if( ((FrameTreeNode*)index.internalPointer())->getDepth() == 2 )
- {
- if( ((FrameTreeNode*)index.internalPointer())->getParent()->getParent()->getIndex() != seq->getSelectedCamera() )
- ui->framesTree->collapse( m->getCameraSelectionIndex() );
- if( ((FrameTreeNode*)index.internalPointer())->getParent()->getIndex() != seq->getSelectedFrame() )
- ui->framesTree->collapse( m->getFrameSelectionIndex() );
- seq->selectFrame( ((FrameTreeNode*)index.internalPointer())->getParent()->getParent()->getIndex(),
- ((FrameTreeNode*)index.internalPointer())->getParent()->getIndex() );
- Frame *f = seq->getFrame();
- workModel->setFrame( f );
- workModel->setMask( seq->getCameras().at( seq->getSelectedCamera() )->getMask()->getDrawableImage() );
- workModel->notifyViews();
- if( f->isNotAnnotated() )
- requestFromServer();
- }
- setFrameTreeSelection();
- v->repaint();
- }
- void MainWindow::on_select_clicked()
- {
- unselectButttons();
- ui->select->setChecked( true );
- setMode( SELECT );
- }
- void MainWindow::on_framesTree_customContextMenuRequested(const QPoint &pos)
- {
- QModelIndex index = ui->framesTree->indexAt( pos );
- ui->framesTree->selectionModel()->select( index, QItemSelectionModel::Select | QItemSelectionModel::Rows );
- on_framesTree_clicked( index );
- QAction *trunc = 0;
- if( contextMenu )
- delete contextMenu;
- contextMenu = new QMenu( ui->framesTree );
- switch( ((FrameTreeNode*)index.internalPointer())->getDepth() )
- {
- case 0:
- contextMenu->addAction( "Maske Bearbeiten ..." );
- break;
- case 1:
- contextMenu->addAction( "Vom Server abfragen ..." );
- break;
- case 2:
- contextMenu->addAction( "Objekt ID bearbeiten ..." );
- contextMenu->addAction( "Objekt Klasse bearbeiten ..." );
- contextMenu->addAction( "Objekt löschen" );
- if( ((_ObjectPolygon*)index.internalPointer())->getPolygonList().size() > 1 )
- contextMenu->addAction( "Objekt nach Polygonen aufteilen" );
- trunc = contextMenu->addAction( "Abgeschnitten" );
- trunc->setCheckable( true );
- trunc->setText( "Abgeschnitten" );
- trunc->setChecked( ((_ObjectPolygon*)index.internalPointer())->isTruncated() );
- break;
- }
- QAction *action = contextMenu->exec( QCursor::pos() );
- if( !action )
- return;
- if( action->text() == "Maske Bearbeiten ..." )
- {
- ChangeMask chm( ((Kamera*)index.internalPointer())->getMask(), (Kamera*)index.internalPointer() );
- chm.exec();
- ((Kamera*)index.internalPointer())->getMask()->unloadMask();
- setupFrameTree();
- }
- if( action->text() == "Vom Server abfragen ..." )
- requestFromServer();
- if( action->text() == "Objekt ID bearbeiten ..." )
- {
- ChangePacket chp( ObjectPolygon( (_ObjectPolygon*)index.internalPointer() ), seq );
- chp.exec();
- workModel->notifyViews();
- setupFrameTree();
- }
- if( action->text() == "Objekt Klasse bearbeiten ..." )
- {
- QList< Sequenz::SegmentationClass > classes = seq->getClasses();
- QList< QString > classNames;
- QString packetId = ((_ObjectPolygon*)index.internalPointer())->getId();
- int currentClass = seq->getClassOfObject( packetId );
- int classId = -1;
- foreach( auto c, classes )
- {
- if( currentClass == c.id )
- classId = classNames.size();
- classNames.append( c.name );
- }
- QString className = QInputDialog::getItem( this, "Klasse Bearbeiten", "Klasse von Objekt " + packetId, classNames, classId, false );
- seq->setClassOfObject( packetId, seq->getClassId( className ) );
- setupFrameTree();
- }
- if( action->text() == "Objekt Löschen" )
- {
- Frame *f = seq->getFrame();
- f->removeObject( ObjectPolygon( (_ObjectPolygon*)index.internalPointer() ) );
- setupFrameTree();
- v->repaint();
- }
- if( action->text() == "Objekt nach Polygonen aufteilen" )
- {
- seq->getFrame()->disconnectObject( ObjectPolygon( ((_ObjectPolygon*)index.internalPointer()) ) );
- setupFrameTree();
- v->repaint();
- }
- if( action == trunc )
- ((_ObjectPolygon*)index.internalPointer())->setTruncated( !((_ObjectPolygon*)index.internalPointer())->isTruncated() );
- }
- void MainWindow::on_actionSave_triggered()
- {
- if( !seq )
- return;
- status->setText( "speichere Annotation ..." );
- seq->saveToPath( status );
- status->setText( "fertig" );
- }
- void MainWindow::on_pipette_clicked()
- {
- unselectButttons();
- ui->pipette->setChecked( true );
- setMode( PIPETTE_SELECT );
- }
- void MainWindow::on_cut_clicked()
- {
- unselectButttons();
- ui->cut->setChecked( true );
- setMode( CUT );
- }
- void MainWindow::on_actionServer_address_triggered()
- {
- serverAddress = QInputDialog::getText( this, "Server Adresse ändern", "Server Adresse:", QLineEdit::Normal, serverAddress );
- }
- void MainWindow::on_actionKlassen_verwalten_triggered()
- {
- if( seq )
- {
- ClassOptions cop( seq, this );
- cop.exec();
- }
- else
- QMessageBox::critical( this, "Fehler", "Sie müssen zunächst eine Sequenz geöffnet haben, bevor sie die Klassen verwalten können." );
- }
- void MainWindow::on_viewWidget_customContextMenuRequested(const QPoint &pos)
- {
- QPoint rPos = pos - v->pos();
- if( !seq || !seq->getFrame() )
- {
- v->mouseReleaseEvent( 0 );
- return;
- }
- QPoint tPos = workModel->inverseTranslate( rPos );
- int pIndex;
- ObjectPolygon obj = seq->getFrame()->getObjectAt( tPos, pIndex );
- if( obj.isNull() )
- return;
- v->mouseReleaseEvent( 0 );
- if( contextMenu )
- delete contextMenu;
- contextMenu = new QMenu( ui->viewWidget );
- contextMenu->addAction( "Objekt ID bearbeiten ..." );
- contextMenu->addAction( "Objekt Klasse bearbeiten ..." );
- contextMenu->addAction( "Objekt Loeschen" );
- if( obj->getPolygonList().size() > 1 )
- contextMenu->addAction( "Objekt nach Polygonen aufteilen" );
- QAction *trunc = contextMenu->addAction( "Abgeschnitten" );
- trunc->setCheckable( true );
- trunc->setText( "Abgeschnitten" );
- trunc->setChecked( obj->isTruncated() );
- QAction *action = contextMenu->exec( QCursor::pos() );
- if( !action )
- return;
- if( action->text() == "Objekt ID bearbeiten ..." )
- {
- ChangePacket chp( obj, seq );
- chp.exec();
- workModel->notifyViews();
- setupFrameTree();
- }
- if( action->text() == "Objekt Klasse bearbeiten ..." )
- {
- QList< Sequenz::SegmentationClass > classes = seq->getClasses();
- QList< QString > classNames;
- QString packetId = obj->getId();
- int currentClass = seq->getClassOfObject( packetId );
- int classId = -1;
- foreach( auto c, classes )
- {
- if( currentClass == c.id )
- classId = classNames.size();
- classNames.append( c.name );
- }
- QString className = QInputDialog::getItem( this, "Klasse Bearbeiten", "Klasse von Objekt " + packetId, classNames, classId, false );
- seq->setClassOfObject( packetId, seq->getClassId( className ) );
- setupFrameTree();
- }
- if( action->text() == "Objekt Loeschen" )
- {
- Frame *f = seq->getFrame();
- f->removeObject( obj );
- setupFrameTree();
- v->repaint();
- }
- if( action->text() == "Objekt nach Polygonen aufteilen" )
- {
- seq->getFrame()->disconnectObject( obj );
- setupFrameTree();
- v->repaint();
- }
- if( action == trunc )
- obj->setTruncated( !obj->isTruncated() );
- }
- void MainWindow::on_actionMake_anzeigen_toggled(bool checked)
- {
- workModel->setShowMask( checked );
- workModel->notifyViews();
- }
- void MainWindow::on_actionObjekte_faerben_triggered(bool checked)
- {
- workModel->setShowColors( checked );
- workModel->notifyViews();
- }
- void MainWindow::on_actionIDs_anzeigen_triggered(bool checked)
- {
- workModel->setShowId( checked );
- workModel->notifyViews();
- }
- void MainWindow::on_actionMaske_bearbeiten_triggered()
- {
- if( !seq )
- return;
- ChangeMask chm( seq->getCameras().at( seq->getSelectedCamera() )->getMask(), seq->getCameras().at( seq->getSelectedCamera() ) );
- chm.exec();
- setupFrameTree();
- }
- void MainWindow::on_actionIDs_bearbeiten_triggered()
- {
- if( !seq )
- return;
- SetIds ids( seq, this );
- ids.exec();
- }
|