Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
QmitkLabelSetWidget.cpp
Go to the documentation of this file.
1 /*===================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 
17 #include "QmitkLabelSetWidget.h"
18 
19 // mitk
21 #include <mitkCoreObjectFactory.h>
22 #include <mitkIOUtil.h>
23 #include <mitkLabelSetImage.h>
25 #include <mitkRenderingManager.h>
28 #include <mitkStatusBar.h>
31 
32 // Qmitk
35 
36 #include <QmitkSearchLabelDialog.h>
37 
38 // Qt
39 #include <QColorDialog>
40 #include <QCompleter>
41 #include <QDateTime>
42 #include <QFileDialog>
43 #include <QMenu>
44 #include <QMessageBox>
45 #include <QPushButton>
46 #include <QStringListModel>
47 #include <QWidgetAction>
48 
49 // itk
50 #include <itksys/SystemTools.hxx>
51 
52 // todo:
53 // berry
54 //#include <berryIPreferencesService.h>
55 
57  : QWidget(parent), m_ToolManager(NULL), m_DataStorage(NULL), m_Completer(NULL)
58 {
59  m_Controls.setupUi(this);
60 
61  m_ColorSequenceRainbow.GoToBegin();
62 
64  assert(m_ToolManager);
65 
66  m_Controls.m_LabelSearchBox->setAlwaysShowClearIcon(true);
67  m_Controls.m_LabelSearchBox->setShowSearchIcon(true);
68 
69  QStringList completionList;
70  completionList << "";
71  m_Completer = new QCompleter(completionList, this);
72  m_Completer->setCaseSensitivity(Qt::CaseInsensitive);
73  m_Controls.m_LabelSearchBox->setCompleter(m_Completer);
74 
75  connect(m_Controls.m_LabelSearchBox, SIGNAL(returnPressed()), this, SLOT(OnSearchLabel()));
76  // connect( m_Controls.m_LabelSetTableWidget, SIGNAL(labelListModified(const QStringList&)), this, SLOT(
77  // OnLabelListModified(const QStringList&)) );
78  // connect( m_Controls.m_LabelSetTableWidget, SIGNAL(mergeLabel(int)), this, SLOT( OnMergeLabel(int)) );
79 
80  QStringListModel *completeModel = static_cast<QStringListModel *>(m_Completer->model());
81  completeModel->setStringList(GetLabelStringList());
82 
83  m_Controls.m_LabelSearchBox->setEnabled(false);
84 
85  m_Controls.m_lblCaption->setText("");
86 
87  InitializeTableWidget();
88 }
89 
91 {
92 }
93 
94 void QmitkLabelSetWidget::OnTableViewContextMenuRequested(const QPoint &pos)
95 {
96  QTableWidgetItem *itemAt = m_Controls.m_LabelSetTableWidget->itemAt(pos);
97 
98  // OnItemClicked(itemAt);
99 
100  if (!itemAt)
101  return;
102  int pixelValue = itemAt->data(Qt::UserRole).toInt();
103  QMenu *menu = new QMenu(m_Controls.m_LabelSetTableWidget);
104 
105  if (m_Controls.m_LabelSetTableWidget->selectedItems().size() > 1)
106  {
107  QAction *mergeAction = new QAction(QIcon(":/Qmitk/MergeLabels.png"), "Merge selection on current label", this);
108  mergeAction->setEnabled(true);
109  QObject::connect(mergeAction, SIGNAL(triggered(bool)), this, SLOT(OnMergeLabels(bool)));
110  menu->addAction(mergeAction);
111 
112  QAction *removeLabelsAction = new QAction(QIcon(":/Qmitk/RemoveLabel.png"), "Remove selected labels", this);
113  removeLabelsAction->setEnabled(true);
114  QObject::connect(removeLabelsAction, SIGNAL(triggered(bool)), this, SLOT(OnRemoveLabels(bool)));
115  menu->addAction(removeLabelsAction);
116 
117  QAction *eraseLabelsAction = new QAction(QIcon(":/Qmitk/EraseLabel.png"), "Erase selected labels", this);
118  eraseLabelsAction->setEnabled(true);
119  QObject::connect(eraseLabelsAction, SIGNAL(triggered(bool)), this, SLOT(OnEraseLabels(bool)));
120  menu->addAction(eraseLabelsAction);
121 
122  QAction *combineAndCreateSurfaceAction =
123  new QAction(QIcon(":/Qmitk/CreateSurface.png"), "Combine and create a surface", this);
124  combineAndCreateSurfaceAction->setEnabled(true);
125  QObject::connect(
126  combineAndCreateSurfaceAction, SIGNAL(triggered(bool)), this, SLOT(OnCombineAndCreateSurface(bool)));
127  // menu->addAction(combineAndCreateSurfaceAction); Not implemented
128 
129  QAction *createMasksAction =
130  new QAction(QIcon(":/Qmitk/CreateMask.png"), "Create a mask for each selected label", this);
131  createMasksAction->setEnabled(true);
132  QObject::connect(createMasksAction, SIGNAL(triggered(bool)), this, SLOT(OnCreateMasks(bool)));
133  // menu->addAction(createMasksAction); Not implemented
134 
135  QAction *combineAndCreateMaskAction =
136  new QAction(QIcon(":/Qmitk/CreateMask.png"), "Combine and create a mask", this);
137  combineAndCreateMaskAction->setEnabled(true);
138  QObject::connect(combineAndCreateMaskAction, SIGNAL(triggered(bool)), this, SLOT(OnCombineAndCreateMask(bool)));
139  // menu->addAction(combineAndCreateMaskAction); Not implemented
140  }
141  else
142  {
143  QAction *renameAction = new QAction(QIcon(":/Qmitk/RenameLabel.png"), "Rename...", this);
144  renameAction->setEnabled(true);
145  QObject::connect(renameAction, SIGNAL(triggered(bool)), this, SLOT(OnRenameLabel(bool)));
146  menu->addAction(renameAction);
147 
148  QAction *removeAction = new QAction(QIcon(":/Qmitk/RemoveLabel.png"), "Remove...", this);
149  removeAction->setEnabled(true);
150  QObject::connect(removeAction, SIGNAL(triggered(bool)), this, SLOT(OnRemoveLabel(bool)));
151  menu->addAction(removeAction);
152 
153  QAction *eraseAction = new QAction(QIcon(":/Qmitk/EraseLabel.png"), "Erase...", this);
154  eraseAction->setEnabled(true);
155  QObject::connect(eraseAction, SIGNAL(triggered(bool)), this, SLOT(OnEraseLabel(bool)));
156  menu->addAction(eraseAction);
157 
158  QAction *mergeAction = new QAction(QIcon(":/Qmitk/MergeLabels.png"), "Merge...", this);
159  mergeAction->setEnabled(true);
160  QObject::connect(mergeAction, SIGNAL(triggered(bool)), this, SLOT(OnMergeLabel(bool)));
161  menu->addAction(mergeAction);
162 
163  QAction *randomColorAction = new QAction(QIcon(":/Qmitk/RandomColor.png"), "Random color", this);
164  randomColorAction->setEnabled(true);
165  QObject::connect(randomColorAction, SIGNAL(triggered(bool)), this, SLOT(OnRandomColor(bool)));
166  menu->addAction(randomColorAction);
167 
168  QAction *viewOnlyAction = new QAction(QIcon(":/Qmitk/visible.png"), "View only", this);
169  viewOnlyAction->setEnabled(true);
170  QObject::connect(viewOnlyAction, SIGNAL(triggered(bool)), this, SLOT(OnSetOnlyActiveLabelVisible(bool)));
171  menu->addAction(viewOnlyAction);
172 
173  QAction *viewAllAction = new QAction(QIcon(":/Qmitk/visible.png"), "View all", this);
174  viewAllAction->setEnabled(true);
175  QObject::connect(viewAllAction, SIGNAL(triggered(bool)), this, SLOT(OnSetAllLabelsVisible(bool)));
176  menu->addAction(viewAllAction);
177 
178  QAction *hideAllAction = new QAction(QIcon(":/Qmitk/invisible.png"), "Hide all", this);
179  hideAllAction->setEnabled(true);
180  QObject::connect(hideAllAction, SIGNAL(triggered(bool)), this, SLOT(OnSetAllLabelsInvisible(bool)));
181  menu->addAction(hideAllAction);
182 
183  QAction *lockAllAction = new QAction(QIcon(":/Qmitk/lock.png"), "Lock all", this);
184  lockAllAction->setEnabled(true);
185  QObject::connect(lockAllAction, SIGNAL(triggered(bool)), this, SLOT(OnLockAllLabels(bool)));
186  menu->addAction(lockAllAction);
187 
188  QAction *unlockAllAction = new QAction(QIcon(":/Qmitk/unlock.png"), "Unlock all", this);
189  unlockAllAction->setEnabled(true);
190  QObject::connect(unlockAllAction, SIGNAL(triggered(bool)), this, SLOT(OnUnlockAllLabels(bool)));
191  menu->addAction(unlockAllAction);
192 
193  QAction *createSurfaceAction = new QAction(QIcon(":/Qmitk/CreateSurface.png"), "Create surface", this);
194  createSurfaceAction->setEnabled(true);
195  createSurfaceAction->setMenu(new QMenu());
196 
197  QAction *tmp1 = createSurfaceAction->menu()->addAction(QString("Detailed"));
198  QAction *tmp2 = createSurfaceAction->menu()->addAction(QString("Smoothed"));
199 
200  QObject::connect(tmp1, SIGNAL(triggered(bool)), this, SLOT(OnCreateDetailedSurface(bool)));
201  QObject::connect(tmp2, SIGNAL(triggered(bool)), this, SLOT(OnCreateSmoothedSurface(bool)));
202 
203  menu->addAction(createSurfaceAction);
204 
205  QAction *createMaskAction = new QAction(QIcon(":/Qmitk/CreateMask.png"), "Create mask", this);
206  createMaskAction->setEnabled(true);
207  QObject::connect(createMaskAction, SIGNAL(triggered(bool)), this, SLOT(OnCreateMask(bool)));
208 
209  menu->addAction(createMaskAction);
210 
211  QAction *createCroppedMaskAction = new QAction(QIcon(":/Qmitk/CreateMask.png"), "Create cropped mask", this);
212  createCroppedMaskAction->setEnabled(true);
213  QObject::connect(createCroppedMaskAction, SIGNAL(triggered(bool)), this, SLOT(OnCreateCroppedMask(bool)));
214 
215  // QAction* importAction = new QAction(QIcon(":/Qmitk/RenameLabel.png"), "Import...", this );
216  // importAction->setEnabled(true);
217  // QObject::connect( importAction, SIGNAL( triggered(bool) ), this, SLOT( OnImportSegmentationSession(bool) ) );
218  // menu->addAction(importAction);
219 
220  menu->addAction(createCroppedMaskAction);
221 
222  QSlider *opacitySlider = new QSlider;
223  opacitySlider->setMinimum(0);
224  opacitySlider->setMaximum(100);
225  opacitySlider->setOrientation(Qt::Horizontal);
226  QObject::connect(opacitySlider, SIGNAL(valueChanged(int)), this, SLOT(OnOpacityChanged(int)));
227 
228  QLabel *_OpacityLabel = new QLabel("Opacity: ");
229  QVBoxLayout *_OpacityWidgetLayout = new QVBoxLayout;
230  _OpacityWidgetLayout->setContentsMargins(4, 4, 4, 4);
231  _OpacityWidgetLayout->addWidget(_OpacityLabel);
232  _OpacityWidgetLayout->addWidget(opacitySlider);
233  QWidget *_OpacityWidget = new QWidget;
234  _OpacityWidget->setLayout(_OpacityWidgetLayout);
235 
236  QWidgetAction *OpacityAction = new QWidgetAction(this);
237  OpacityAction->setDefaultWidget(_OpacityWidget);
238  // QObject::connect( m_OpacityAction, SIGNAL( changed() ), this, SLOT( OpacityActionChanged() ) );
239  opacitySlider->setValue(static_cast<int>(GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->GetOpacity() * 100));
240 
241  menu->addAction(OpacityAction);
242  }
243  menu->popup(QCursor::pos());
244 }
245 
246 void QmitkLabelSetWidget::OnUnlockAllLabels(bool /*value*/)
247 {
248  GetWorkingImage()->GetActiveLabelSet()->SetAllLabelsLocked(false);
250 }
251 
252 void QmitkLabelSetWidget::OnLockAllLabels(bool /*value*/)
253 {
254  GetWorkingImage()->GetActiveLabelSet()->SetAllLabelsLocked(true);
256 }
257 
258 void QmitkLabelSetWidget::OnSetAllLabelsVisible(bool /*value*/)
259 {
260  GetWorkingImage()->GetActiveLabelSet()->SetAllLabelsVisible(true);
263 }
264 
265 void QmitkLabelSetWidget::OnSetAllLabelsInvisible(bool /*value*/)
266 {
267  GetWorkingImage()->GetActiveLabelSet()->SetAllLabelsVisible(false);
270 }
271 
272 void QmitkLabelSetWidget::OnSetOnlyActiveLabelVisible(bool /*value*/)
273 {
274  mitk::LabelSetImage* workingImage = GetWorkingImage();
275  int pixelValue = GetPixelValueOfSelectedItem();
276 
277  workingImage->GetActiveLabelSet()->SetAllLabelsVisible(false);
278  workingImage->GetLabel(pixelValue, workingImage->GetActiveLayer())->SetVisible(true);
279 
280  workingImage->GetActiveLabelSet()->UpdateLookupTable(pixelValue);
281 
282  this->WaitCursorOn();
283 
284  const mitk::Point3D &pos = workingImage->GetLabel(pixelValue, workingImage->GetActiveLayer())->GetCenterOfMassCoordinates();
285  this->WaitCursorOff();
286  if (pos.GetVnlVector().max_value() > 0.0)
287  {
288  emit goToLabel(pos);
289  }
290 
292 }
293 
294 void QmitkLabelSetWidget::OnMergeLabel(bool /*value*/)
295 {
296  QmitkSearchLabelDialog dialog(this);
297  dialog.setWindowTitle("Select a second label..");
298  dialog.SetLabelSuggestionList(GetLabelStringList());
299  int dialogReturnValue = dialog.exec();
300  if (dialogReturnValue == QDialog::Rejected)
301  return;
302 
303  int pixelValue = -1;
304  for (int i = 0; i < m_Controls.m_LabelSetTableWidget->rowCount(); i++)
305  {
306  if (dialog.GetLabelSetWidgetTableCompleteWord() == QString(m_Controls.m_LabelSetTableWidget->item(i, 0)->text()))
307  pixelValue = m_Controls.m_LabelSetTableWidget->item(i, 0)->data(Qt::UserRole).toInt();
308  }
309 
310  if (pixelValue == -1)
311  {
312  MITK_INFO << "unknown label";
313  ;
314  return;
315  }
316 
317  GetWorkingImage()->MergeLabel(pixelValue, GetWorkingImage()->GetActiveLayer());
318 
321 }
322 
323 void QmitkLabelSetWidget::OnEraseLabel(bool /*value*/)
324 {
325  int pixelValue = GetPixelValueOfSelectedItem();
326  QString question = "Do you really want to erase the contents of label \"";
327  question.append(QString::fromStdString(GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->GetName()));
328  question.append("\"?");
329 
330  QMessageBox::StandardButton answerButton =
331  QMessageBox::question(this, "Erase label", question, QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes);
332 
333  if (answerButton == QMessageBox::Yes)
334  {
335  this->WaitCursorOn();
336  GetWorkingImage()->EraseLabel(pixelValue);
337  this->WaitCursorOff();
339  }
340 }
341 
342 void QmitkLabelSetWidget::OnRemoveLabel(bool /*value*/)
343 {
344  int pixelValue = GetPixelValueOfSelectedItem();
345  QString question = "Do you really want to remove label \"";
346  question.append(QString::fromStdString(GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->GetName()));
347  question.append("\"?");
348 
349  QMessageBox::StandardButton answerButton =
350  QMessageBox::question(this, "Remove label", question, QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes);
351 
352  if (answerButton == QMessageBox::Yes)
353  {
354  this->WaitCursorOn();
355  GetWorkingImage()->GetActiveLabelSet()->RemoveLabel(pixelValue);
356  GetWorkingImage()->EraseLabel(pixelValue);
357  this->WaitCursorOff();
358  }
359 
360  this->ResetAllTableWidgetItems();
362 }
363 
364 void QmitkLabelSetWidget::OnRenameLabel(bool /*value*/)
365 {
366  QmitkNewSegmentationDialog dialog(this);
367  dialog.setWindowTitle("Rename Label");
368  dialog.SetSuggestionList(m_OrganColors);
369  // MLI TODO
370  // dialog.SetColor(GetWorkingImage()->GetActiveLabel()->GetColor());
371  // dialog.SetSegmentationName(GetWorkingImage()->GetActiveLabel()->GetName());
372 
373  if (dialog.exec() == QDialog::Rejected)
374  return;
375  int pixelValue = GetWorkingImage()->GetActiveLabel(GetWorkingImage()->GetActiveLayer())->GetValue();
376 
377  GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->SetColor(dialog.GetColor());
378  GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->SetName(dialog.GetSegmentationName().toStdString());
379  GetWorkingImage()->GetActiveLabelSet()->UpdateLookupTable(pixelValue);
380 
381  this->ResetAllTableWidgetItems();
383 }
384 
385 void QmitkLabelSetWidget::OnCombineAndCreateMask(bool /*value*/)
386 {
387  m_Controls.m_LabelSetTableWidget->selectedRanges();
388  // ...to do... //
389 }
390 
391 void QmitkLabelSetWidget::OnCreateMasks(bool /*value*/)
392 {
393  m_Controls.m_LabelSetTableWidget->selectedRanges();
394  // ..to do.. //
395 }
396 
397 void QmitkLabelSetWidget::OnCombineAndCreateSurface(bool /*value*/)
398 {
399  m_Controls.m_LabelSetTableWidget->selectedRanges();
400  // ..to do.. //
401 }
402 
403 void QmitkLabelSetWidget::OnEraseLabels(bool /*value*/)
404 {
405  QString question = "Do you really want to erase the selected labels?";
406 
407  QMessageBox::StandardButton answerButton = QMessageBox::question(
408  this, "Erase selected labels", question, QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes);
409 
410  if (answerButton == QMessageBox::Yes)
411  {
412  QList<QTableWidgetSelectionRange> ranges = m_Controls.m_LabelSetTableWidget->selectedRanges();
413  if (ranges.isEmpty())
414  return;
415 
416  std::vector<mitk::Label::PixelType> VectorOfLablePixelValues;
417  foreach (QTableWidgetSelectionRange a, ranges)
418  for (int i = a.topRow(); i <= a.bottomRow(); i++)
419  VectorOfLablePixelValues.push_back(m_Controls.m_LabelSetTableWidget->item(i, 0)->data(Qt::UserRole).toInt());
420 
421  this->WaitCursorOn();
422  GetWorkingImage()->EraseLabels(VectorOfLablePixelValues, GetWorkingImage()->GetActiveLayer());
423  this->WaitCursorOff();
425  }
426 }
427 
428 void QmitkLabelSetWidget::OnRemoveLabels(bool /*value*/)
429 {
430  QString question = "Do you really want to remove selected labels?";
431  QMessageBox::StandardButton answerButton = QMessageBox::question(
432  this, "Remove selected labels", question, QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes);
433 
434  if (answerButton == QMessageBox::Yes)
435  {
436  QList<QTableWidgetSelectionRange> ranges = m_Controls.m_LabelSetTableWidget->selectedRanges();
437  if (ranges.isEmpty())
438  {
439  return;
440  }
441 
442  std::vector<mitk::Label::PixelType> VectorOfLablePixelValues;
443  foreach(QTableWidgetSelectionRange a, ranges)
444  {
445  for (int i = a.topRow(); i <= a.bottomRow(); ++i)
446  {
447  VectorOfLablePixelValues.push_back(m_Controls.m_LabelSetTableWidget->item(i, 0)->data(Qt::UserRole).toInt());
448  }
449  }
450 
451  this->WaitCursorOn();
452  GetWorkingImage()->RemoveLabels(VectorOfLablePixelValues, GetWorkingImage()->GetActiveLayer());
453  this->WaitCursorOff();
454  }
455 
458 }
459 
460 void QmitkLabelSetWidget::OnMergeLabels(bool /*value*/)
461 {
462  int pixelValue = GetPixelValueOfSelectedItem();
463  QString question = "Do you really want to merge selected labels into \"";
464  question.append(QString::fromStdString(GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->GetName()));
465  question.append("\"?");
466 
467  QMessageBox::StandardButton answerButton = QMessageBox::question(
468  this, "Merge selected label", question, QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Yes);
469 
470  if (answerButton == QMessageBox::Yes)
471  {
472  QList<QTableWidgetSelectionRange> ranges = m_Controls.m_LabelSetTableWidget->selectedRanges();
473  if (ranges.isEmpty())
474  {
475  return;
476  }
477 
478  std::vector<mitk::Label::PixelType> VectorOfLablePixelValues;
479  foreach(QTableWidgetSelectionRange a, ranges)
480  {
481  for (int i = a.topRow(); i <= a.bottomRow(); ++i)
482  {
483  VectorOfLablePixelValues.push_back(m_Controls.m_LabelSetTableWidget->item(i, 0)->data(Qt::UserRole).toInt());
484  }
485  }
486 
487  this->WaitCursorOn();
488  int pixelValue = m_Controls.m_LabelSetTableWidget->item(m_Controls.m_LabelSetTableWidget->currentRow(), 0)
489  ->data(Qt::UserRole)
490  .toInt();
491 
492  GetWorkingImage()->MergeLabels(VectorOfLablePixelValues, pixelValue, GetWorkingImage()->GetActiveLayer());
493  this->WaitCursorOff();
494 
496  }
497 }
498 
499 void QmitkLabelSetWidget::OnLockedButtonClicked()
500 {
501  int row;
502  for(int i = 0; i < m_Controls.m_LabelSetTableWidget->rowCount(); ++i)
503  {
504  if (sender() == m_Controls.m_LabelSetTableWidget->cellWidget(i, LOCKED_COL))
505  {
506  row = i;
507  }
508  }
509  if (row >= 0 && row < m_Controls.m_LabelSetTableWidget->rowCount())
510  {
511  int pixelValue = m_Controls.m_LabelSetTableWidget->item(row, 0)->data(Qt::UserRole).toInt();
512  GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->SetLocked(!GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->GetLocked());
513  }
514 }
515 
516 void QmitkLabelSetWidget::OnVisibleButtonClicked()
517 {
518  int row;
519  for(int i = 0; i < m_Controls.m_LabelSetTableWidget->rowCount(); ++i)
520  {
521  if (sender() == m_Controls.m_LabelSetTableWidget->cellWidget(i, VISIBLE_COL))
522  {
523  row = i;
524  break;
525  }
526  }
527 
528  if (row >= 0 && row < m_Controls.m_LabelSetTableWidget->rowCount())
529  {
530  QTableWidgetItem *item = m_Controls.m_LabelSetTableWidget->item(row, 0);
531  OnItemClicked(item);
532  int pixelValue = item->data(Qt::UserRole).toInt();
533  GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->SetVisible(!GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->GetVisible());
534  GetWorkingImage()->GetActiveLabelSet()->UpdateLookupTable(pixelValue);
536  }
537 }
538 
539 void QmitkLabelSetWidget::OnColorButtonClicked()
540 {
541  int row;
542  for(int i = 0; i < m_Controls.m_LabelSetTableWidget->rowCount(); ++i)
543  {
544  if (sender() == m_Controls.m_LabelSetTableWidget->cellWidget(i, COLOR_COL))
545  {
546  row = i;
547  }
548  }
549 
550  if (row >= 0 && row < m_Controls.m_LabelSetTableWidget->rowCount())
551  {
552  int pixelValue = m_Controls.m_LabelSetTableWidget->item(row, 0)->data(Qt::UserRole).toInt();
553  const mitk::Color &color = GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->GetColor();
554  QColor initial(color.GetRed() * 255, color.GetGreen() * 255, color.GetBlue() * 255);
555  QColor qcolor = QColorDialog::getColor(initial, 0, QString("Change color"));
556  if (!qcolor.isValid())
557  {
558  return;
559  }
560 
561  QPushButton *button = static_cast<QPushButton*>(m_Controls.m_LabelSetTableWidget->cellWidget(row, COLOR_COL));
562  if (!button)
563  {
564  return;
565  }
566 
567  button->setAutoFillBackground(true);
568 
569  QString styleSheet = "background-color:rgb(";
570  styleSheet.append(QString::number(qcolor.red()));
571  styleSheet.append(",");
572  styleSheet.append(QString::number(qcolor.green()));
573  styleSheet.append(",");
574  styleSheet.append(QString::number(qcolor.blue()));
575  styleSheet.append(")");
576  button->setStyleSheet(styleSheet);
577 
578  mitk::Color newColor;
579  newColor.SetRed(qcolor.red() / 255.0);
580  newColor.SetGreen(qcolor.green() / 255.0);
581  newColor.SetBlue(qcolor.blue() / 255.0);
582 
583  GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->SetColor(newColor);
584 
585  GetWorkingImage()->GetActiveLabelSet()->UpdateLookupTable(pixelValue);
586  }
587 }
588 
589 void QmitkLabelSetWidget::OnRandomColor(bool /*value*/)
590 {
591  int pixelValue = GetPixelValueOfSelectedItem();
592  GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->SetColor(m_ColorSequenceRainbow.GetNextColor());
593  GetWorkingImage()->GetActiveLabelSet()->UpdateLookupTable(pixelValue);
595 }
596 
597 void QmitkLabelSetWidget::SetOrganColors(const QStringList &organColors)
598 {
599  m_OrganColors = organColors;
600 }
601 
602 void QmitkLabelSetWidget::OnActiveLabelChanged(int pixelValue)
603 {
604  mitk::LabelSetImage *workingImage = GetWorkingImage();
605  assert(workingImage);
606  workingImage->GetActiveLabelSet()->SetActiveLabel(pixelValue);
607  // MITK_INFO << "Active Label set to << " << pixelValue;
608 
610  if (interpolator)
611  {
612  interpolator->SetActiveLabel(pixelValue);
613  }
614 
615  workingImage->Modified();
617 }
618 
619 void QmitkLabelSetWidget::OnItemClicked(QTableWidgetItem *item)
620 {
621  if (!item)
622  return;
623 
624  int pixelValue = item->data(Qt::UserRole).toInt();
625 
626  QList<QTableWidgetSelectionRange> ranges = m_Controls.m_LabelSetTableWidget->selectedRanges();
627  if (!ranges.empty() && ranges.back().rowCount() == 1)
628  {
629  SelectLabelByPixelValue(pixelValue);
630  OnActiveLabelChanged(pixelValue);
632  }
633 }
634 
635 void QmitkLabelSetWidget::OnItemDoubleClicked(QTableWidgetItem *item)
636 {
637  if (!item)
638  return;
639 
640  int pixelValue = item->data(Qt::UserRole).toInt();
641  // OnItemClicked(item); <<-- Double click first call OnItemClicked
642  WaitCursorOn();
643  mitk::LabelSetImage* workingImage = GetWorkingImage();
644  workingImage->UpdateCenterOfMass(pixelValue, workingImage->GetActiveLayer());
645  const mitk::Point3D &pos = workingImage->GetLabel(pixelValue, workingImage->GetActiveLayer())->GetCenterOfMassCoordinates();
646  WaitCursorOff();
647  if (pos.GetVnlVector().max_value() > 0.0)
648  {
649  emit goToLabel(pos);
650  }
651 
652  workingImage->Modified();
654 }
655 
657 {
658  // MITK_INFO << "QmitkLabelSetWidget::SelectLabelByPixelValue " << pixelValue;
659 
660  if (!GetWorkingImage()->ExistLabel(pixelValue))
661  return;
662  for (int row = 0; row < m_Controls.m_LabelSetTableWidget->rowCount(); row++)
663  {
664  if (m_Controls.m_LabelSetTableWidget->item(row, 0)->data(Qt::UserRole).toInt() == pixelValue)
665  {
666  m_Controls.m_LabelSetTableWidget->clearSelection();
667  m_Controls.m_LabelSetTableWidget->setSelectionMode(QAbstractItemView::SingleSelection);
668  m_Controls.m_LabelSetTableWidget->selectRow(row);
669  m_Controls.m_LabelSetTableWidget->scrollToItem(m_Controls.m_LabelSetTableWidget->item(row, 0));
670  m_Controls.m_LabelSetTableWidget->setSelectionMode(QAbstractItemView::ExtendedSelection);
671  // SelectTableWidgetItem(m_Controls.m_LabelSetTableWidget->item(i,0));
672  // emit resetView();
673  // GetWorkingImage()->Modified();
674  return;
675  }
676  }
677 }
678 
679 void QmitkLabelSetWidget::InsertTableWidgetItem(mitk::Label *label)
680 {
681  const mitk::Color &color = label->GetColor();
682 
683  QString styleSheet = "background-color:rgb(";
684  styleSheet.append(QString::number(color[0] * 255));
685  styleSheet.append(",");
686  styleSheet.append(QString::number(color[1] * 255));
687  styleSheet.append(",");
688  styleSheet.append(QString::number(color[2] * 255));
689  styleSheet.append(")");
690 
691  QTableWidget* tableWidget = m_Controls.m_LabelSetTableWidget;
692  int colWidth = (tableWidget->columnWidth(NAME_COL) < 180) ? 180 : tableWidget->columnWidth(NAME_COL) - 2;
693  QString text = fontMetrics().elidedText(label->GetName().c_str(), Qt::ElideMiddle, colWidth);
694  QTableWidgetItem *nameItem = new QTableWidgetItem(text);
695  nameItem->setTextAlignment(Qt::AlignCenter | Qt::AlignLeft);
696  // ---!---
697  // IMPORTANT: ADD PIXELVALUE TO TABLEWIDGETITEM.DATA
698  nameItem->setData(Qt::UserRole, QVariant(label->GetValue()));
699  // ---!---
700 
701  QPushButton *pbColor = new QPushButton(tableWidget);
702  pbColor->setFixedSize(24, 24);
703  pbColor->setCheckable(false);
704  pbColor->setAutoFillBackground(true);
705  pbColor->setToolTip("Change label color");
706  pbColor->setStyleSheet(styleSheet);
707 
708  connect(pbColor, SIGNAL(clicked()), this, SLOT(OnColorButtonClicked()));
709 
710  QPushButton *pbLocked = new QPushButton(tableWidget);
711  pbLocked->setFixedSize(24, 24);
712  QIcon *iconLocked = new QIcon();
713 
714  iconLocked->addFile(QString::fromUtf8(":/Qmitk/lock.png"), QSize(), QIcon::Normal, QIcon::Off);
715  iconLocked->addFile(QString::fromUtf8(":/Qmitk/unlock.png"), QSize(), QIcon::Normal, QIcon::On);
716  pbLocked->setIcon(*iconLocked);
717  pbLocked->setIconSize(QSize(24, 24));
718  pbLocked->setCheckable(true);
719  pbLocked->setToolTip("Lock/unlock label");
720  pbLocked->setChecked(!label->GetLocked());
721  connect(pbLocked, SIGNAL(clicked()), this, SLOT(OnLockedButtonClicked()));
722 
723  QPushButton *pbVisible = new QPushButton(tableWidget);
724  pbVisible->setFixedSize(24, 24);
725  pbVisible->setAutoRepeat(false);
726  QIcon *iconVisible = new QIcon();
727  iconVisible->addFile(QString::fromUtf8(":/Qmitk/visible.png"), QSize(), QIcon::Normal, QIcon::Off);
728  iconVisible->addFile(QString::fromUtf8(":/Qmitk/invisible.png"), QSize(), QIcon::Normal, QIcon::On);
729  pbVisible->setIcon(*iconVisible);
730  pbVisible->setIconSize(QSize(24, 24));
731  pbVisible->setCheckable(true);
732  pbVisible->setToolTip("Show/hide label");
733  pbVisible->setChecked(!label->GetVisible());
734 
735  connect(pbVisible, SIGNAL(clicked()), this, SLOT(OnVisibleButtonClicked()));
736 
737  int row = tableWidget->rowCount();
738  tableWidget->insertRow(row);
739  tableWidget->setRowHeight(row, 24);
740  tableWidget->setItem(row, 0, nameItem);
741  tableWidget->setCellWidget(row, 1, pbLocked);
742  tableWidget->setCellWidget(row, 2, pbColor);
743  tableWidget->setCellWidget(row, 3, pbVisible);
744  tableWidget->selectRow(row);
745 
746  // m_LabelSetImage->SetActiveLabel(label->GetPixelValue());
747  // m_ToolManager->WorkingDataModified.Send();
748  // emit activeLabelChanged(label->GetPixelValue());
749 
750  if (row == 0)
751  {
752  tableWidget->hideRow(row); // hide exterior label
753  }
754 }
755 
757 {
758  mitk::LabelSetImage *workingImage = GetWorkingImage();
759  if (!workingImage)
760  return;
761 
762  // add all labels
763  QTableWidget* tableWidget = m_Controls.m_LabelSetTableWidget;
764  m_LabelStringList.clear();
765  for(int i = 0 ; i < tableWidget->rowCount(); ++i)
766  {
767  UpdateTableWidgetItem(tableWidget->item(i, 0));
768  m_LabelStringList.append(tableWidget->item(i, 0)->text());
769  }
770 
771  OnLabelListModified(m_LabelStringList);
772 
774 }
775 
776 void QmitkLabelSetWidget::UpdateTableWidgetItem(QTableWidgetItem *item)
777 {
778  mitk::LabelSetImage *workingImage = GetWorkingImage();
779  mitk::Label *label = workingImage->GetLabel(item->data(Qt::UserRole).toInt(), workingImage->GetActiveLayer());
780 
781  const mitk::Color &color = label->GetColor();
782 
783  QTableWidget *tableWidget = m_Controls.m_LabelSetTableWidget;
784 
785  QString styleSheet = "background-color:rgb(";
786  styleSheet.append(QString::number(color[0] * 255));
787  styleSheet.append(",");
788  styleSheet.append(QString::number(color[1] * 255));
789  styleSheet.append(",");
790  styleSheet.append(QString::number(color[2] * 255));
791  styleSheet.append(")");
792 
793  // Update text Label tableWdget->item(row,0)
794  int colWidth = (tableWidget->columnWidth(NAME_COL) < 180) ? 180 : tableWidget->columnWidth(NAME_COL) - 2;
795  QString text = fontMetrics().elidedText(label->GetName().c_str(), Qt::ElideMiddle, colWidth);
796  item->setText(text);
797 
798  QPushButton *pbLocked = dynamic_cast<QPushButton *>(tableWidget->cellWidget(item->row(), 1));
799  pbLocked->setChecked(!label->GetLocked());
800 
801  QPushButton *pbColor = dynamic_cast<QPushButton *>(tableWidget->cellWidget(item->row(), 2));
802  pbColor->setStyleSheet(styleSheet);
803 
804  QPushButton *pbVisible = dynamic_cast<QPushButton *>(tableWidget->cellWidget(item->row(), 3));
805  pbVisible->setChecked(!label->GetVisible());
806 
807  if (item->row() == 0)
808  tableWidget->hideRow(item->row()); // hide exterior label
809 }
810 
812 {
813  QTableWidget *tableWidget = m_Controls.m_LabelSetTableWidget;
814  // remove all rows
815  while (tableWidget->rowCount())
816  {
817  tableWidget->removeRow(0);
818  }
819 
820  mitk::LabelSetImage *workingImage = GetWorkingImage();
821  if (!workingImage)
822  return;
823 
824  // add all labels
825  m_LabelStringList.clear();
826 
829 
830  int pixelValue = -1;
831  while (it != end)
832  {
833  InsertTableWidgetItem(it->second);
834  if (GetWorkingImage()->GetActiveLabel() == it->second) // get active
835  pixelValue = it->first;
836  m_LabelStringList.append(QString(it->second->GetName().c_str()));
837  it++;
838  }
839 
840  SelectLabelByPixelValue(pixelValue);
841 
842  OnLabelListModified(m_LabelStringList);
843 
844  std::stringstream captionText;
845  captionText << "Number of labels: " << workingImage->GetNumberOfLabels() - 1;
846  m_Controls.m_lblCaption->setText(captionText.str().c_str());
847 
849 }
850 
851 int QmitkLabelSetWidget::GetPixelValueOfSelectedItem()
852 {
853  if (m_Controls.m_LabelSetTableWidget->currentItem())
854  {
855  return m_Controls.m_LabelSetTableWidget->currentItem()->data(Qt::UserRole).toInt();
856  }
857  return -1;
858 }
859 
861 {
862  return m_LabelStringList;
863 }
864 
865 void QmitkLabelSetWidget::InitializeTableWidget()
866 {
867  QTableWidget *tableWidged = m_Controls.m_LabelSetTableWidget;
868 
869  tableWidged->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);
870  tableWidged->setTabKeyNavigation(false);
871  tableWidged->setAlternatingRowColors(false);
872  tableWidged->setFocusPolicy(Qt::NoFocus);
873  tableWidged->setColumnCount(4);
874  tableWidged->resizeColumnToContents(NAME_COL);
875  tableWidged->setColumnWidth(LOCKED_COL, 25);
876  tableWidged->setColumnWidth(COLOR_COL, 25);
877  tableWidged->setColumnWidth(VISIBLE_COL, 25);
878 #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
879  tableWidged->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);
880 #else
881  tableWidged->horizontalHeader()->setResizeMode(0, QHeaderView::Stretch);
882 #endif
883  tableWidged->setContextMenuPolicy(Qt::CustomContextMenu);
884  tableWidged->horizontalHeader()->hide();
885  tableWidged->setSortingEnabled(false);
886  tableWidged->verticalHeader()->hide();
887  tableWidged->setEditTriggers(QAbstractItemView::NoEditTriggers);
888  tableWidged->setSelectionMode(QAbstractItemView::ExtendedSelection);
889  tableWidged->setSelectionBehavior(QAbstractItemView::SelectRows);
890 
891  connect(tableWidged, SIGNAL(itemClicked(QTableWidgetItem *)), this, SLOT(OnItemClicked(QTableWidgetItem *)));
892  connect(
893  tableWidged, SIGNAL(itemDoubleClicked(QTableWidgetItem *)), this, SLOT(OnItemDoubleClicked(QTableWidgetItem *)));
894  connect(tableWidged,
895  SIGNAL(customContextMenuRequested(const QPoint &)),
896  this,
897  SLOT(OnTableViewContextMenuRequested(const QPoint &)));
898 
899  // connect( m_Controls.m_LabelSetTableWidget, SIGNAL(activeLabelChanged(int)), this, SLOT(OnActiveLabelChanged(int))
900  // );
901  // connect( m_Controls.m_LabelSetTableWidget, SIGNAL(importSegmentation()), this, SLOT( OnImportSegmentation()) );
902  // connect( m_Controls.m_LabelSetTableWidget, SIGNAL(importLabeledImage()), this, SLOT( OnImportLabeledImage()) );
903  // connect( m_Controls.m_LabelSetTableWidget, SIGNAL(renameLabel(int, const mitk::Color&, const std::string&)), this,
904  // SLOT(OnRenameLabel(int, const mitk::Color&, const std::string&)) );
905  // connect( m_Controls.m_LabelSetTableWidget, SIGNAL(createSurface(int, bool)), this, SLOT(OnCreateSurface(int, bool))
906  // );
907  // connect( m_Controls.m_LabelSetTableWidget, SIGNAL(toggleOutline(bool)), this, SLOT(OnToggleOutline(bool)) );
908  // connect( m_Controls.m_LabelSetTableWidget, SIGNAL(goToLabel(const mitk::Point3D&)), this, SIGNAL(goToLabel(const
909  // mitk::Point3D&)) );
910  // connect( m_Controls.m_LabelSetTableWidget, SIGNAL(combineAndCreateSurface( const QList<QTableWidgetSelectionRange>&
911  // )),
912  // this, SLOT(OnCombineAndCreateSurface( const QList<QTableWidgetSelectionRange>&)) );
913 
914  // connect( m_Controls.m_LabelSetTableWidget, SIGNAL(createMask(int)), this, SLOT(OnCreateMask(int)) );
915  // connect( m_Controls.m_LabelSetTableWidget, SIGNAL(createCroppedMask(int)), this, SLOT(OnCreateCroppedMask(int)) );
916  // connect( m_Controls.m_LabelSetTableWidget, SIGNAL(combineAndCreateMask( const QList<QTableWidgetSelectionRange>&
917  // )),
918  // this, SLOT(OnCombineAndCreateMask( const QList<QTableWidgetSelectionRange>&)) );
919 }
920 
921 void QmitkLabelSetWidget::OnOpacityChanged(int value)
922 {
923  int pixelValue = m_Controls.m_LabelSetTableWidget->currentItem()->data(Qt::UserRole).toInt();
924  float opacity = static_cast<float>(value) / 100.0f;
925  GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->SetOpacity(opacity);
926  GetWorkingImage()->GetActiveLabelSet()->UpdateLookupTable(pixelValue);
927 }
928 
930 {
931  QWidget::setEnabled(enabled);
932  UpdateControls();
933 }
934 
936 {
937  m_DataStorage = storage;
938 }
939 
940 void QmitkLabelSetWidget::OnSearchLabel()
941 {
942  std::string text = m_Controls.m_LabelSearchBox->text().toStdString();
943  int pixelValue = -1;
944  int row = -1;
945  for(int i = 0; i < m_Controls.m_LabelSetTableWidget->rowCount(); ++i)
946  {
947  if( m_Controls.m_LabelSetTableWidget->item(i, 0)->text().toStdString().compare(text) == 0)
948  {
949  pixelValue = m_Controls.m_LabelSetTableWidget->item(i, 0)->data(Qt::UserRole).toInt();
950  row = i;
951  break;
952  }
953  }
954  if (pixelValue == -1)
955  {
956  return;
957  }
958 
959  GetWorkingImage()->GetActiveLabelSet()->SetActiveLabel(pixelValue);
960 
961  QTableWidgetItem *nameItem = m_Controls.m_LabelSetTableWidget->item(row, NAME_COL);
962  if (!nameItem)
963  {
964  return;
965  }
966 
967  m_Controls.m_LabelSetTableWidget->clearSelection();
968  m_Controls.m_LabelSetTableWidget->setSelectionMode(QAbstractItemView::SingleSelection);
969  m_Controls.m_LabelSetTableWidget->selectRow(row);
970  m_Controls.m_LabelSetTableWidget->scrollToItem(nameItem);
971  m_Controls.m_LabelSetTableWidget->setSelectionMode(QAbstractItemView::ExtendedSelection);
972 
973  GetWorkingImage()->GetActiveLabelSet()->SetActiveLabel(pixelValue);
974 
975  this->WaitCursorOn();
976  mitk::Point3D pos = GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->GetCenterOfMassCoordinates();
977 
978  m_ToolManager->WorkingDataChanged();
979 
980  if (pos.GetVnlVector().max_value() > 0.0)
981  {
982  emit goToLabel(pos);
983  }
984  else
985  {
986  GetWorkingImage()->UpdateCenterOfMass(pixelValue, GetWorkingImage()->GetActiveLayer());
987  mitk::Point3D pos = GetWorkingImage()->GetLabel(pixelValue, GetWorkingImage()->GetActiveLayer())->GetCenterOfMassCoordinates();
988  emit goToLabel(pos);
989  }
990 
991  this->WaitCursorOff();
992 }
993 
994 void QmitkLabelSetWidget::OnLabelListModified(const QStringList &list)
995 {
996  QStringListModel *completeModel = static_cast<QStringListModel *>(m_Completer->model());
997  completeModel->setStringList(list);
998 }
999 
1000 mitk::LabelSetImage *QmitkLabelSetWidget::GetWorkingImage()
1001 {
1002  mitk::DataNode *workingNode = GetWorkingNode();
1003  mitk::LabelSetImage *workingImage = dynamic_cast<mitk::LabelSetImage *>(workingNode->GetData());
1004  assert(workingImage);
1005  return workingImage;
1006 }
1007 
1008 mitk::DataNode *QmitkLabelSetWidget::GetWorkingNode()
1009 {
1010  mitk::DataNode *workingNode = m_ToolManager->GetWorkingData(0);
1011  assert(workingNode);
1012  return workingNode;
1013 }
1014 
1016 {
1017  mitk::DataNode *workingNode = m_ToolManager->GetWorkingData(0);
1018  bool hasWorkingData = (workingNode != nullptr);
1019 
1020  m_Controls.m_LabelSetTableWidget->setEnabled(hasWorkingData);
1021  m_Controls.m_LabelSearchBox->setEnabled(hasWorkingData);
1022 
1023  if (!hasWorkingData)
1024  return;
1025 
1026  QStringListModel *completeModel = static_cast<QStringListModel *>(m_Completer->model());
1027  completeModel->setStringList(GetLabelStringList());
1028 }
1029 
1030 void QmitkLabelSetWidget::OnCreateCroppedMask(bool)
1031 {
1032  m_ToolManager->ActivateTool(-1);
1033 
1034  mitk::LabelSetImage *workingImage = GetWorkingImage();
1035  mitk::Image::Pointer maskImage;
1036  int pixelValue = GetPixelValueOfSelectedItem();
1037  try
1038  {
1039  this->WaitCursorOn();
1040 
1042  cropFilter->SetInput(workingImage->CreateLabelMask(pixelValue));
1043  cropFilter->SetBackgroundValue(0);
1044  cropFilter->SetMarginFactor(1.15);
1045  cropFilter->Update();
1046 
1047  maskImage = cropFilter->GetOutput();
1048 
1049  this->WaitCursorOff();
1050  }
1051  catch (mitk::Exception &e)
1052  {
1053  this->WaitCursorOff();
1054  MITK_ERROR << "Exception caught: " << e.GetDescription();
1055  QMessageBox::information(this, "Create Mask", "Could not create a mask out of the selected label.\n");
1056  return;
1057  }
1058 
1059  if (maskImage.IsNull())
1060  {
1061  QMessageBox::information(this, "Create Mask", "Could not create a mask out of the selected label.\n");
1062  return;
1063  }
1064 
1066  std::string name = workingImage->GetLabel(pixelValue, workingImage->GetActiveLayer())->GetName();
1067  name += "-mask";
1068  maskNode->SetName(name);
1069  maskNode->SetData(maskImage);
1070  maskNode->SetBoolProperty("binary", true);
1071  maskNode->SetBoolProperty("outline binary", true);
1072  maskNode->SetBoolProperty("outline binary shadow", true);
1073  maskNode->SetFloatProperty("outline width", 2.0);
1074  maskNode->SetColor(workingImage->GetLabel(pixelValue, workingImage->GetActiveLayer())->GetColor());
1075  maskNode->SetOpacity(1.0);
1076 
1077  m_DataStorage->Add(maskNode, GetWorkingNode());
1078 }
1079 
1080 void QmitkLabelSetWidget::OnCreateMask(bool /*triggered*/)
1081 {
1082  m_ToolManager->ActivateTool(-1);
1083 
1084  mitk::LabelSetImage *workingImage = GetWorkingImage();
1085  mitk::Image::Pointer maskImage;
1086  int pixelValue = GetPixelValueOfSelectedItem();
1087  try
1088  {
1089  this->WaitCursorOn();
1090  maskImage = workingImage->CreateLabelMask(pixelValue);
1091  this->WaitCursorOff();
1092  }
1093  catch (mitk::Exception &e)
1094  {
1095  this->WaitCursorOff();
1096  MITK_ERROR << "Exception caught: " << e.GetDescription();
1097  QMessageBox::information(this, "Create Mask", "Could not create a mask out of the selected label.\n");
1098  return;
1099  }
1100 
1101  if (maskImage.IsNull())
1102  {
1103  QMessageBox::information(this, "Create Mask", "Could not create a mask out of the selected label.\n");
1104  return;
1105  }
1106 
1108  std::string name = workingImage->GetLabel(pixelValue, workingImage->GetActiveLayer())->GetName();
1109  name += "-mask";
1110  maskNode->SetName(name);
1111  maskNode->SetData(maskImage);
1112  maskNode->SetBoolProperty("binary", true);
1113  maskNode->SetBoolProperty("outline binary", true);
1114  maskNode->SetBoolProperty("outline binary shadow", true);
1115  maskNode->SetFloatProperty("outline width", 2.0);
1116  maskNode->SetColor(workingImage->GetLabel(pixelValue, workingImage->GetActiveLayer())->GetColor());
1117  maskNode->SetOpacity(1.0);
1118 
1119  m_DataStorage->Add(maskNode, GetWorkingNode());
1120 }
1121 
1122 void QmitkLabelSetWidget::OnToggleOutline(bool value)
1123 {
1124  mitk::DataNode *workingNode = m_ToolManager->GetWorkingData(0);
1125  assert(workingNode);
1126 
1127  workingNode->SetBoolProperty("labelset.contour.active", value);
1128  workingNode->GetData()->Modified(); // fixme: workaround to force data-type rendering (and not only property-type)
1130 }
1131 
1132 void QmitkLabelSetWidget::OnCreateSmoothedSurface(bool /*triggered*/)
1133 {
1134  m_ToolManager->ActivateTool(-1);
1135 
1136  mitk::DataNode::Pointer workingNode = GetWorkingNode();
1137  mitk::LabelSetImage *workingImage = GetWorkingImage();
1138  int pixelValue = GetPixelValueOfSelectedItem();
1139 
1141 
1144  successCommand->SetCallbackFunction(this, &QmitkLabelSetWidget::OnThreadedCalculationDone);
1145  surfaceFilter->AddObserver(mitk::ResultAvailable(), successCommand);
1146 
1149  errorCommand->SetCallbackFunction(this, &QmitkLabelSetWidget::OnThreadedCalculationDone);
1150  surfaceFilter->AddObserver(mitk::ProcessingError(), errorCommand);
1151 
1152  mitk::DataNode::Pointer groupNode = workingNode;
1153  surfaceFilter->SetPointerParameter("Group node", groupNode);
1154  surfaceFilter->SetPointerParameter("Input", workingImage);
1155  surfaceFilter->SetParameter("RequestedLabel", pixelValue);
1156  surfaceFilter->SetParameter("Smooth", true);
1157  surfaceFilter->SetDataStorage(*m_DataStorage);
1158 
1159  mitk::StatusBar::GetInstance()->DisplayText("Surface creation is running in background...");
1160 
1161  try
1162  {
1163  surfaceFilter->StartAlgorithm();
1164  }
1165  catch (mitk::Exception &e)
1166  {
1167  MITK_ERROR << "Exception caught: " << e.GetDescription();
1168  QMessageBox::information(this,
1169  "Create Surface",
1170  "Could not create a surface mesh out of the selected label. See error log for details.\n");
1171  }
1172 }
1173 
1174 void QmitkLabelSetWidget::OnCreateDetailedSurface(bool /*triggered*/)
1175 {
1176  m_ToolManager->ActivateTool(-1);
1177 
1178  mitk::DataNode::Pointer workingNode = GetWorkingNode();
1179  mitk::LabelSetImage *workingImage = GetWorkingImage();
1180  int pixelValue = GetPixelValueOfSelectedItem();
1181 
1183 
1186  successCommand->SetCallbackFunction(this, &QmitkLabelSetWidget::OnThreadedCalculationDone);
1187  surfaceFilter->AddObserver(mitk::ResultAvailable(), successCommand);
1188 
1191  errorCommand->SetCallbackFunction(this, &QmitkLabelSetWidget::OnThreadedCalculationDone);
1192  surfaceFilter->AddObserver(mitk::ProcessingError(), errorCommand);
1193 
1194  mitk::DataNode::Pointer groupNode = workingNode;
1195  surfaceFilter->SetPointerParameter("Group node", groupNode);
1196  surfaceFilter->SetPointerParameter("Input", workingImage);
1197  surfaceFilter->SetParameter("RequestedLabel", pixelValue);
1198  surfaceFilter->SetParameter("Smooth", false);
1199  surfaceFilter->SetDataStorage(*m_DataStorage);
1200 
1201  mitk::StatusBar::GetInstance()->DisplayText("Surface creation is running in background...");
1202 
1203  try
1204  {
1205  surfaceFilter->StartAlgorithm();
1206  }
1207  catch (mitk::Exception &e)
1208  {
1209  MITK_ERROR << "Exception caught: " << e.GetDescription();
1210  QMessageBox::information(this,
1211  "Create Surface",
1212  "Could not create a surface mesh out of the selected label. See error log for details.\n");
1213  }
1214 }
1215 
1216 void QmitkLabelSetWidget::OnImportLabeledImage()
1217 {
1218  /*
1219  m_ToolManager->ActivateTool(-1);
1220 
1221  mitk::DataNode* referenceNode = m_ToolManager->GetReferenceData(0);
1222  assert(referenceNode);
1223 
1224  // Ask the user for a list of files to open
1225  QStringList fileNames = QFileDialog::getOpenFileNames( this, "Open Image", m_LastFileOpenPath,
1226  mitk::CoreObjectFactory::GetInstance()->GetFileExtensions());
1227 
1228  if (fileNames.empty())
1229  return;
1230 
1231  try
1232  {
1233  this->WaitCursorOn();
1234  mitk::Image::Pointer image = mitk::IOUtil::LoadImage( fileNames.front().toStdString() );
1235  if (image.IsNull())
1236  {
1237  this->WaitCursorOff();
1238  QMessageBox::information(this, "Import Labeled Image", "Could not load the selected segmentation.\n");
1239  return;
1240  }
1241 
1242  mitk::LabelSetImage::Pointer newImage = mitk::LabelSetImage::New();
1243  newImage->InitializeByLabeledImage(image);
1244  this->WaitCursorOff();
1245 
1246  mitk::DataNode::Pointer newNode = mitk::DataNode::New();
1247  std::string newName = referenceNode->GetName();
1248  newName += "-labels";
1249  newNode->SetName(newName);
1250  newNode->SetData(newImage);
1251  m_DataStorage->Add(newNode, referenceNode);
1252  }
1253  catch (mitk::Exception & e)
1254  {
1255  this->WaitCursorOff();
1256  MITK_ERROR << "Exception caught: " << e.GetDescription();
1257  QMessageBox::information(this, "Import Labeled Image", "Could not load the selected segmentation. See error log
1258  for details.\n");
1259  return;
1260  }
1261 
1262  this->UpdateControls();
1263 
1264  mitk::RenderingManager::GetInstance()->RequestUpdateAll();
1265  */
1266 }
1267 
1268 void QmitkLabelSetWidget::OnImportSegmentation()
1269 {
1270  /*
1271  m_ToolManager->ActivateTool(-1);
1272 
1273  mitk::DataNode* workingNode = m_ToolManager->GetWorkingData(0);
1274  assert(workingNode);
1275 
1276  mitk::LabelSetImage* workingImage = dynamic_cast<mitk::LabelSetImage*>( workingNode->GetData() );
1277  assert(workingImage);
1278 
1279  std::string fileExtensions("Segmentation files (*.lset);;");
1280  QString qfileName = QFileDialog::getOpenFileName(this, "Import Segmentation", m_LastFileOpenPath,
1281  fileExtensions.c_str() );
1282  if (qfileName.isEmpty() ) return;
1283 
1284  mitk::NrrdLabelSetImageReader::Pointer reader = mitk::NrrdLabelSetImageReader::New();
1285  reader->SetFileName(qfileName.toLatin1());
1286 
1287  try
1288  {
1289  this->WaitCursorOn();
1290  reader->Update();
1291  mitk::LabelSetImage::Pointer newImage = reader->GetOutput();
1292  workingImage->Concatenate(newImage);
1293  this->WaitCursorOff();
1294  }
1295  catch ( mitk::Exception& e )
1296  {
1297  this->WaitCursorOff();
1298  MITK_ERROR << "Exception caught: " << e.GetDescription();
1299  QMessageBox::information(this, "Import Segmentation", "Could not import the selected segmentation session.\n See
1300  error log for details.\n");
1301  }
1302  */
1304 }
1305 
1306 void QmitkLabelSetWidget::WaitCursorOn()
1307 {
1308  QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
1309 }
1310 
1311 void QmitkLabelSetWidget::WaitCursorOff()
1312 {
1313  this->RestoreOverrideCursor();
1314 }
1315 
1316 void QmitkLabelSetWidget::RestoreOverrideCursor()
1317 {
1318  QApplication::restoreOverrideCursor();
1319 }
1320 
1321 void QmitkLabelSetWidget::OnThreadedCalculationDone()
1322 {
1324 }
virtual void Add(mitk::DataNode *node, const mitk::DataStorage::SetOfObjects *parents=nullptr)=0
Adds a DataNode containing a data object to its internal storage.
Data management class that handles 'was created by' relations.
itk::SmartPointer< Self > Pointer
std::string GetName() const
Definition: mitkLabel.cpp:153
#define MITK_INFO
Definition: mitkLogMacros.h:22
std::string tmp2
void SetOrganColors(const QStringList &organColors)
#define MITK_ERROR
Definition: mitkLogMacros.h:24
virtual Color GetNextColor() override
method to return another color
bool GetVisible() const
Definition: mitkLabel.cpp:123
void SetDataStorage(mitk::DataStorage *storage)
void UpdateLookupTable(PixelType pixelValue)
static SurfaceBasedInterpolationController * GetInstance()
void SetLocked(bool locked)
Definition: mitkLabel.cpp:94
void SetAllLabelsLocked(bool)
mitk::Label * GetLabel(PixelType pixelValue, unsigned int layer=0) const
Returns the mitk::Label with the given pixelValue and for the given layer.
virtual mitk::ToolManager * GetToolManager()
Returns ToolManager object.
void goToLabel(const mitk::Point3D &)
Send a signal when it was requested to go to a label.
A data structure describing a label.
Definition: mitkLabel.h:35
BaseData * GetData() const
Get the data object (instance of BaseData, e.g., an Image) managed by this DataNode.
virtual void setEnabled(bool enabled)
void EraseLabel(PixelType pixelValue, unsigned int layer=0)
Erases the label with the given value in the given layer from the underlying image. The label itself will not be erased from the respective mitk::LabelSet. In order to remove the label itself use mitk::LabelSetImage::RemoveLabels()
void SelectLabelByPixelValue(mitk::Label::PixelType pixelValue)
LabelContainerConstIteratorType IteratorConstEnd() const
Returns a const iterator pointing to the end of the container.
void MergeLabels(std::vector< PixelType > &VectorOfLablePixelValues, PixelType index, unsigned int layer=0)
Merges a list of mitk::Labels with the mitk::Label that has a specific value.
bool ActivateTool(int id)
void SetOpacity(float opacity)
Definition: mitkLabel.cpp:130
void RemoveLabels(std::vector< PixelType > &VectorOfLabelPixelValues, unsigned int layer=0)
Removes labels from the mitk::LabelSet of given layer. Calls mitk::LabelSetImage::EraseLabels() which...
void SetColor(const mitk::Color &)
Definition: mitkLabel.cpp:205
QmitkLabelSetWidget(QWidget *parent=NULL)
mitk::DataStorage::Pointer m_DataStorage
void MergeLabel(PixelType targetPixelValue, unsigned int layer=0)
Merges the mitk::Label with a given target value with the active label.
static Pointer New()
virtual void GoToBegin() override
method to set the color-index to begin again
static Pointer New()
An object of this class represents an exception of MITK. Please don't instantiate exceptions manually...
Definition: mitkException.h:49
static RenderingManager * GetInstance()
void DisplayText(const char *t)
Send a string to the applications StatusBar.
void EraseLabels(std::vector< PixelType > &VectorOfLabelPixelValues, unsigned int layer=0)
Similar to mitk::LabelSetImage::EraseLabel() this funtion erase a list of labels from the image...
The custom viewer plugin implements simple viewer functionality presented in a customized look and feel It was developed to demonstrate extensibility and customizability of the blueberry application framework As an example for the GUI customization capabilities provided by the BlueBerry application the custom viewer plugin was developed It features simple viewer functionality presented in a customized look and feel The custom viewer consists of two i e a viewer perspective and a DICOM perspective As part of the viewer an instance of QmitkDataManagerView allows for data selection Visualization of the selected data is then performed by a simple render window view According data can either be directly loaded from file or be imported as DICOM data DICOM import functionality is accessible from the DICOM perspective incorporating the QmitkDicomExternalDataWidget The customization of Qt Stylesheets is used to give the application a non native look and feel This is further emphasized by a Tab Widget like unification of the perspectives with the according perspective bar In addition to an absence of menu
void SetVisible(bool visible)
Definition: mitkLabel.cpp:112
mitk::LabelSet * GetActiveLabelSet()
Returns the currently active mitk::LabelSet.
bool GetLocked() const
Definition: mitkLabel.cpp:105
QStringList & GetLabelStringList()
mitk::Label * GetActiveLabel(unsigned int layer=0)
Returns the active label of a specific layer.
unsigned int GetNumberOfLabels(unsigned int layer=0) const
Get the number of all existing mitk::Labels for a given layer.
LabelContainerType::const_iterator LabelContainerConstIteratorType
Definition: mitkLabelSet.h:46
itk::RGBPixel< float > Color
Color Standard RGB color typedef (float)
static StatusBar * GetInstance()
static method to get the GUI dependent StatusBar-instance so the methods DisplayText, etc. can be called No reference counting, cause of decentral static use!
void SetBoolProperty(const char *propertyKey, bool boolValue, const mitk::BaseRenderer *renderer=nullptr)
Convenience method for setting boolean properties (instances of BoolProperty)
mitk::Point3D GetCenterOfMassCoordinates() const
Definition: mitkLabel.cpp:244
void Clear()
removes any temporary message being shown.
void UpdateCenterOfMass(PixelType pixelValue, unsigned int layer=0)
LabelSetImage class for handling labels and layers in a segmentation session.
void SetActiveLabel(PixelType)
static std::string GetName(std::string fileName, std::string suffix)
unsigned short PixelType
Definition: mitkLabel.h:40
const mitk::Color & GetColor() const
Definition: mitkLabel.cpp:199
US_USE_NAMESPACE std::string tmp1
LabelContainerConstIteratorType IteratorConstBegin() const
Returns a const iterator poiting to the begining of the container.
Dialog for QmitkInteractiveSegmentation.
unsigned int GetActiveLayer() const
Gets the ID of the currently active layer.
PixelType GetValue() const
Definition: mitkLabel.cpp:171
void RemoveLabel(PixelType)
void RequestUpdateAll(RequestType type=REQUEST_UPDATE_ALL)
Class for nodes of the DataTree.
Definition: mitkDataNode.h:66
DataVectorType GetWorkingData()
static mitk::ToolManagerProvider * GetInstance()
Returns an instance of ToolManagerProvider service.
void SetName(const std::string &name)
Definition: mitkLabel.cpp:148
void SetAllLabelsVisible(bool)
mitk::Image::Pointer CreateLabelMask(PixelType index)
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.