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