Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkLabelSetImage.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 "mitkLabelSetImage.h"
18 
19 #include "mitkImageAccessByItk.h"
20 #include "mitkImageCast.h"
21 #include "mitkImageReadAccessor.h"
22 #include "mitkInteractionConst.h"
24 #include "mitkPadImageFilter.h"
25 #include "mitkRenderingManager.h"
26 
27 #include <vtkCell.h>
28 #include <vtkTransform.h>
29 #include <vtkTransformPolyDataFilter.h>
30 
31 #include <itkImageRegionIterator.h>
32 #include <itkQuadEdgeMesh.h>
33 #include <itkTriangleMeshToBinaryImageFilter.h>
34 //#include <itkRelabelComponentImageFilter.h>
35 
36 #include <itkCommand.h>
37 
38 template <typename TPixel, unsigned int VDimensions>
39 void SetToZero(itk::Image<TPixel, VDimensions> *source)
40 {
41  source->FillBuffer(0);
42 }
43 
45  : mitk::Image(), m_ActiveLayer(0), m_activeLayerInvalid(false), m_ExteriorLabel(nullptr)
46 {
47  // Iniitlaize Background Label
48  mitk::Color color;
49  color.Set(0, 0, 0);
51  m_ExteriorLabel->SetColor(color);
52  m_ExteriorLabel->SetName("Exterior");
53  m_ExteriorLabel->SetOpacity(0.0);
54  m_ExteriorLabel->SetLocked(false);
55  m_ExteriorLabel->SetValue(0);
56 }
57 
59  : Image(other),
60  m_ActiveLayer(other.GetActiveLayer()),
61  m_activeLayerInvalid(false),
62  m_ExteriorLabel(other.GetExteriorLabel()->Clone())
63 {
64  for (unsigned int i = 0; i < other.GetNumberOfLayers(); i++)
65  {
66  // Clone LabelSet data
67  mitk::LabelSet::Pointer lsClone = other.GetLabelSet(i)->Clone();
68  // add modified event listener to LabelSet (listen to LabelSet changes)
70  command->SetCallbackFunction(this, &mitk::LabelSetImage::OnLabelSetModified);
71  lsClone->AddObserver(itk::ModifiedEvent(), command);
72  m_LabelSetContainer.push_back(lsClone);
73 
74  // clone layer Image data
75  mitk::Image::Pointer liClone = other.GetLayerImage(i)->Clone();
76  m_LayerContainer.push_back(liClone);
77  }
78 }
79 
81 {
82  Superclass::Modified();
83 }
84 
86 {
87  m_ExteriorLabel = label;
88 }
89 
91 {
92  return m_ExteriorLabel;
93 }
94 
96 {
97  return m_ExteriorLabel;
98 }
99 
101 {
102  mitk::PixelType pixelType(mitk::MakeScalarPixelType<LabelSetImage::PixelType>());
103  if (other->GetDimension() == 2)
104  {
105  const unsigned int dimensions[] = {other->GetDimension(0), other->GetDimension(1), 1};
106  Superclass::Initialize(pixelType, 3, dimensions);
107  }
108  else
109  {
110  Superclass::Initialize(pixelType, other->GetDimension(), other->GetDimensions());
111  }
112 
113  auto originalGeometry = other->GetTimeGeometry()->Clone();
114  this->SetTimeGeometry(originalGeometry);
115 
116  // initialize image memory to zero
117  if (4 == this->GetDimension())
118  {
120  }
121  else
122  {
123  AccessByItk(this, SetToZero);
124  }
125 
126  // Add a inital LabelSet ans corresponding image data to the stack
127  AddLayer();
128 }
129 
131 {
132  m_LabelSetContainer.clear();
133 }
134 
136 {
137  return m_LayerContainer[layer];
138 }
139 
140 const mitk::Image *mitk::LabelSetImage::GetLayerImage(unsigned int layer) const
141 {
142  return m_LayerContainer[layer];
143 }
144 
146 {
147  return m_ActiveLayer;
148 }
149 
151 {
152  return m_LabelSetContainer.size();
153 }
154 
156 {
157  int layerToDelete = GetActiveLayer();
158  // remove all observers from active label set
159  GetLabelSet(layerToDelete)->RemoveAllObservers();
160 
161  // set the active layer to one below, if exists.
162  if (layerToDelete != 0)
163  {
164  SetActiveLayer(layerToDelete - 1);
165  }
166  else
167  {
168  // we are deleting layer zero, it should not be copied back into the vector
169  m_activeLayerInvalid = true;
170  }
171 
172  // remove labelset and image data
173  m_LabelSetContainer.erase(m_LabelSetContainer.begin() + layerToDelete);
174  m_LayerContainer.erase(m_LayerContainer.begin() + layerToDelete);
175 
176  if (layerToDelete == 0)
177  {
178  this->SetActiveLayer(layerToDelete);
179  }
180 
181  this->Modified();
182 }
183 
185 {
187  newImage->Initialize(this->GetPixelType(),
188  this->GetDimension(),
189  this->GetDimensions(),
190  this->GetImageDescriptor()->GetNumberOfChannels());
191  newImage->SetTimeGeometry(this->GetTimeGeometry()->Clone());
192 
193  if (newImage->GetDimension() < 4)
194  {
195  AccessByItk(newImage, SetToZero);
196  }
197  else
198  {
199  AccessFixedDimensionByItk(newImage, SetToZero, 4);
200  }
201 
202  unsigned int newLabelSetId = this->AddLayer(newImage, lset);
203 
204  return newLabelSetId;
205 }
206 
208 {
209  unsigned int newLabelSetId = m_LayerContainer.size();
210 
211  // Add labelset to layer
213  if (lset.IsNotNull())
214  {
215  ls = lset;
216  }
217  else
218  {
219  ls = mitk::LabelSet::New();
220  ls->AddLabel(GetExteriorLabel());
221  ls->SetActiveLabel(0 /*Exterior Label*/);
222  }
223 
224  ls->SetLayer(newLabelSetId);
225  // Add exterior Label to label set
226  // mitk::Label::Pointer exteriorLabel = CreateExteriorLabel();
227 
228  // push a new working image for the new layer
229  m_LayerContainer.push_back(layerImage);
230 
231  // push a new labelset for the new layer
232  m_LabelSetContainer.push_back(ls);
233 
234  // add modified event listener to LabelSet (listen to LabelSet changes)
236  command->SetCallbackFunction(this, &mitk::LabelSetImage::OnLabelSetModified);
237  ls->AddObserver(itk::ModifiedEvent(), command);
238 
239  SetActiveLayer(newLabelSetId);
240  // MITK_INFO << GetActiveLayer();
241  this->Modified();
242  return newLabelSetId;
243 }
244 
245 void mitk::LabelSetImage::AddLabelSetToLayer(const unsigned int layerIdx, const mitk::LabelSet::Pointer labelSet)
246 {
247  if (m_LayerContainer.size() <= layerIdx)
248  {
249  mitkThrow() << "Trying to add labelSet to non-existing layer.";
250  }
251 
252  if (layerIdx < m_LabelSetContainer.size())
253  {
254  m_LabelSetContainer[layerIdx] = labelSet;
255  }
256  else
257  {
258  while (layerIdx >= m_LabelSetContainer.size())
259  {
260  mitk::LabelSet::Pointer defaultLabelSet = mitk::LabelSet::New();
261  defaultLabelSet->AddLabel(GetExteriorLabel());
262  defaultLabelSet->SetActiveLabel(0 /*Exterior Label*/);
263  defaultLabelSet->SetLayer(m_LabelSetContainer.size());
264  m_LabelSetContainer.push_back(defaultLabelSet);
265  }
266  m_LabelSetContainer.push_back(labelSet);
267  }
268 }
269 
270 void mitk::LabelSetImage::SetActiveLayer(unsigned int layer)
271 {
272  try
273  {
274  if (4 == this->GetDimension())
275  {
276  if ((layer != GetActiveLayer() || m_activeLayerInvalid) && (layer < this->GetNumberOfLayers()))
277  {
278  BeforeChangeLayerEvent.Send();
279 
280  if (m_activeLayerInvalid)
281  {
282  // We should not write the invalid layer back to the vector
283  m_activeLayerInvalid = false;
284  }
285  else
286  {
287  AccessFixedDimensionByItk_n(this, ImageToLayerContainerProcessing, 4, (GetActiveLayer()));
288  }
289  m_ActiveLayer = layer; // only at this place m_ActiveLayer should be manipulated!!! Use Getter and Setter
290  AccessFixedDimensionByItk_n(this, LayerContainerToImageProcessing, 4, (GetActiveLayer()));
291 
292  AfterChangeLayerEvent.Send();
293  }
294  }
295  else
296  {
297  if ((layer != GetActiveLayer() || m_activeLayerInvalid) && (layer < this->GetNumberOfLayers()))
298  {
299  BeforeChangeLayerEvent.Send();
300 
301  if (m_activeLayerInvalid)
302  {
303  // We should not write the invalid layer back to the vector
304  m_activeLayerInvalid = false;
305  }
306  else
307  {
308  AccessByItk_1(this, ImageToLayerContainerProcessing, GetActiveLayer());
309  }
310  m_ActiveLayer = layer; // only at this place m_ActiveLayer should be manipulated!!! Use Getter and Setter
311  AccessByItk_1(this, LayerContainerToImageProcessing, GetActiveLayer());
312 
313  AfterChangeLayerEvent.Send();
314  }
315  }
316  }
317  catch (itk::ExceptionObject &e)
318  {
319  mitkThrow() << e.GetDescription();
320  }
321  this->Modified();
322 }
323 
325 {
326  const unsigned int *otherDims = other->GetDimensions();
327  const unsigned int *thisDims = this->GetDimensions();
328  if ((otherDims[0] != thisDims[0]) || (otherDims[1] != thisDims[1]) || (otherDims[2] != thisDims[2]))
329  mitkThrow() << "Dimensions do not match.";
330 
331  try
332  {
333  int numberOfLayers = other->GetNumberOfLayers();
334  for (int layer = 0; layer < numberOfLayers; ++layer)
335  {
336  this->SetActiveLayer(layer);
337  AccessByItk_1(this, ConcatenateProcessing, other);
338  mitk::LabelSet *ls = other->GetLabelSet(layer);
339  auto it = ls->IteratorConstBegin();
340  auto end = ls->IteratorConstEnd();
341  it++; // skip exterior
342  while (it != end)
343  {
344  GetLabelSet()->AddLabel((it->second));
345  // AddLabelEvent.Send();
346  it++;
347  }
348  }
349  }
350  catch (itk::ExceptionObject &e)
351  {
352  mitkThrow() << e.GetDescription();
353  }
354  this->Modified();
355 }
356 
358 {
359  try
360  {
361  AccessByItk(this, ClearBufferProcessing);
362  this->Modified();
363  }
364  catch (itk::ExceptionObject &e)
365  {
366  mitkThrow() << e.GetDescription();
367  }
368 }
369 
371 {
372  bool exist = false;
373  for (unsigned int lidx = 0; lidx < GetNumberOfLayers(); lidx++)
374  exist |= m_LabelSetContainer[lidx]->ExistLabel(pixelValue);
375  return exist;
376 }
377 
378 bool mitk::LabelSetImage::ExistLabel(PixelType pixelValue, unsigned int layer) const
379 {
380  bool exist = m_LabelSetContainer[layer]->ExistLabel(pixelValue);
381  return exist;
382 }
383 
384 bool mitk::LabelSetImage::ExistLabelSet(unsigned int layer) const
385 {
386  return layer < m_LabelSetContainer.size();
387 }
388 
389 void mitk::LabelSetImage::MergeLabel(PixelType pixelValue, unsigned int /*layer*/)
390 {
391  int targetPixelValue = this->GetActiveLabel(GetActiveLayer())->GetValue();
392  try
393  {
394  AccessByItk_2(this, MergeLabelProcessing, targetPixelValue, pixelValue);
395  }
396  catch (itk::ExceptionObject &e)
397  {
398  mitkThrow() << e.GetDescription();
399  }
400  Modified();
401 }
402 
403 void mitk::LabelSetImage::MergeLabels(std::vector<PixelType> &VectorOfLablePixelValues,
404  PixelType pixelValue,
405  unsigned int layer)
406 {
407  GetLabelSet(layer)->SetActiveLabel(pixelValue);
408  try
409  {
410  for (unsigned int idx = 0; idx < VectorOfLablePixelValues.size(); idx++)
411  {
412  AccessByItk_2(this, MergeLabelProcessing, pixelValue, VectorOfLablePixelValues[idx]);
413  }
414  }
415  catch (itk::ExceptionObject &e)
416  {
417  mitkThrow() << e.GetDescription();
418  }
419  Modified();
420 }
421 
422 void mitk::LabelSetImage::RemoveLabels(std::vector<PixelType> &VectorOfLabelPixelValues, unsigned int layer)
423 {
424  for (unsigned int idx = 0; idx < VectorOfLabelPixelValues.size(); idx++)
425  {
426  GetLabelSet(layer)->RemoveLabel(VectorOfLabelPixelValues[idx]);
427  EraseLabel(VectorOfLabelPixelValues[idx], layer);
428  }
429 }
430 
431 void mitk::LabelSetImage::EraseLabels(std::vector<PixelType> &VectorOfLabelPixelValues, unsigned int layer)
432 {
433  for (unsigned int i = 0; i < VectorOfLabelPixelValues.size(); i++)
434  {
435  this->EraseLabel(VectorOfLabelPixelValues[i], layer);
436  }
437 }
438 
439 void mitk::LabelSetImage::EraseLabel(PixelType pixelValue, unsigned int layer)
440 {
441  try
442  {
443  AccessByItk_2(this, EraseLabelProcessing, pixelValue, layer);
444  }
445  catch (itk::ExceptionObject &e)
446  {
447  mitkThrow() << e.GetDescription();
448  }
449  Modified();
450 }
451 
453 {
454  if (m_LabelSetContainer.size() <= layer)
455  return nullptr;
456  else
457  return m_LabelSetContainer[layer]->GetActiveLabel();;
458 }
459 
460 mitk::Label *mitk::LabelSetImage::GetLabel(PixelType pixelValue, unsigned int layer) const
461 {
462  if (m_LabelSetContainer.size() <= layer)
463  return nullptr;
464  else
465  return m_LabelSetContainer[layer]->GetLabel(pixelValue);
466 }
467 
469 {
470  if (m_LabelSetContainer.size() <= layer)
471  return nullptr;
472  else
473  return m_LabelSetContainer[layer].GetPointer();
474 }
475 
476 const mitk::LabelSet *mitk::LabelSetImage::GetLabelSet(unsigned int layer) const
477 {
478  if (m_LabelSetContainer.size() <= layer)
479  return nullptr;
480  else
481  return m_LabelSetContainer[layer].GetPointer();
482 }
483 
485 {
486  if (m_LabelSetContainer.size() == 0)
487  return nullptr;
488  else
489  return m_LabelSetContainer[GetActiveLayer()].GetPointer();
490 }
491 
492 void mitk::LabelSetImage::UpdateCenterOfMass(PixelType pixelValue, unsigned int layer)
493 {
494  AccessByItk_2(this, CalculateCenterOfMassProcessing, pixelValue, layer);
495 }
496 
497 unsigned int mitk::LabelSetImage::GetNumberOfLabels(unsigned int layer) const
498 {
499  return m_LabelSetContainer[layer]->GetNumberOfLabels();
500 }
501 
503 {
504  unsigned int totalLabels(0);
505  auto layerIter = m_LabelSetContainer.begin();
506  for (; layerIter != m_LabelSetContainer.end(); ++layerIter)
507  totalLabels += (*layerIter)->GetNumberOfLabels();
508  return totalLabels;
509 }
510 
511 void mitk::LabelSetImage::MaskStamp(mitk::Image *mask, bool forceOverwrite)
512 {
513  try
514  {
516  padImageFilter->SetInput(0, mask);
517  padImageFilter->SetInput(1, this);
518  padImageFilter->SetPadConstant(0);
519  padImageFilter->SetBinaryFilter(false);
520  padImageFilter->SetLowerThreshold(0);
521  padImageFilter->SetUpperThreshold(1);
522 
523  padImageFilter->Update();
524 
525  mitk::Image::Pointer paddedMask = padImageFilter->GetOutput();
526 
527  if (paddedMask.IsNull())
528  return;
529 
530  AccessByItk_2(this, MaskStampProcessing, paddedMask, forceOverwrite);
531  }
532  catch (...)
533  {
534  mitkThrow() << "Could not stamp the provided mask on the selected label.";
535  }
536 }
537 
539 {
541  try
542  {
543  mask->Initialize(this);
544 
545  unsigned int byteSize = sizeof(LabelSetImage::PixelType);
546  for (unsigned int dim = 0; dim < mask->GetDimension(); ++dim)
547  {
548  byteSize *= mask->GetDimension(dim);
549  }
550 
551  mitk::ImageWriteAccessor *accessor = new mitk::ImageWriteAccessor(static_cast<mitk::Image *>(mask));
552  memset(accessor->GetData(), 0, byteSize);
553  delete accessor;
554 
555  auto geometry = this->GetTimeGeometry()->Clone();
556  mask->SetTimeGeometry(geometry);
557 
558  AccessByItk_2(this, CreateLabelMaskProcessing, mask, index);
559  }
560  catch (...)
561  {
562  mitkThrow() << "Could not create a mask out of the selected label.";
563  }
564 
565  return mask;
566 }
567 
569 {
570  if (image.IsNull() || image->IsEmpty() || !image->IsInitialized())
571  mitkThrow() << "Invalid labeled image.";
572 
573  try
574  {
575  this->Initialize(image);
576 
577  unsigned int byteSize = sizeof(LabelSetImage::PixelType);
578  for (unsigned int dim = 0; dim < image->GetDimension(); ++dim)
579  {
580  byteSize *= image->GetDimension(dim);
581  }
582 
583  mitk::ImageWriteAccessor *accessor = new mitk::ImageWriteAccessor(static_cast<mitk::Image *>(this));
584  memset(accessor->GetData(), 0, byteSize);
585  delete accessor;
586 
587  auto geometry = image->GetTimeGeometry()->Clone();
588  this->SetTimeGeometry(geometry);
589 
590  if (image->GetDimension() == 3)
591  {
592  AccessTwoImagesFixedDimensionByItk(this, image, InitializeByLabeledImageProcessing, 3);
593  }
594  else if (image->GetDimension() == 4)
595  {
596  AccessTwoImagesFixedDimensionByItk(this, image, InitializeByLabeledImageProcessing, 4);
597  }
598  else
599  {
600  mitkThrow() << image->GetDimension() << "-dimensional label set images not yet supported";
601  }
602  }
603  catch (...)
604  {
605  mitkThrow() << "Could not intialize by provided labeled image.";
606  }
607  this->Modified();
608 }
609 
610 template <typename LabelSetImageType, typename ImageType>
611 void mitk::LabelSetImage::InitializeByLabeledImageProcessing(LabelSetImageType *labelSetImage, ImageType *image)
612 {
613  typedef itk::ImageRegionConstIteratorWithIndex<ImageType> SourceIteratorType;
614  typedef itk::ImageRegionIterator<LabelSetImageType> TargetIteratorType;
615 
616  TargetIteratorType targetIter(labelSetImage, labelSetImage->GetRequestedRegion());
617  targetIter.GoToBegin();
618 
619  SourceIteratorType sourceIter(image, image->GetRequestedRegion());
620  sourceIter.GoToBegin();
621 
622  while (!sourceIter.IsAtEnd())
623  {
624  PixelType sourceValue = static_cast<PixelType>(sourceIter.Get());
625  targetIter.Set(sourceValue);
626 
627  if (!this->ExistLabel(sourceValue))
628  {
629  std::stringstream name;
630  name << "object-" << sourceValue;
631 
632  double rgba[4];
633  m_LabelSetContainer[this->GetActiveLayer()]->GetLookupTable()->GetTableValue(sourceValue, rgba);
634 
635  mitk::Color color;
636  color.SetRed(rgba[0]);
637  color.SetGreen(rgba[1]);
638  color.SetBlue(rgba[2]);
639 
640  auto label = mitk::Label::New();
641  label->SetName(name.str().c_str());
642  label->SetColor(color);
643  label->SetOpacity(rgba[3]);
644  label->SetValue(sourceValue);
645 
646  this->GetLabelSet()->AddLabel(label);
647 
648  if (GetActiveLabelSet()->GetNumberOfLabels() >= mitk::Label::MAX_LABEL_VALUE ||
649  sourceValue >= mitk::Label::MAX_LABEL_VALUE)
650  this->AddLayer();
651  }
652 
653  ++sourceIter;
654  ++targetIter;
655  }
656 }
657 
658 template <typename ImageType>
659 void mitk::LabelSetImage::MaskStampProcessing(ImageType *itkImage, mitk::Image *mask, bool forceOverwrite)
660 {
661  typename ImageType::Pointer itkMask;
662  mitk::CastToItkImage(mask, itkMask);
663 
664  typedef itk::ImageRegionConstIterator<ImageType> SourceIteratorType;
665  typedef itk::ImageRegionIterator<ImageType> TargetIteratorType;
666 
667  SourceIteratorType sourceIter(itkMask, itkMask->GetLargestPossibleRegion());
668  sourceIter.GoToBegin();
669 
670  TargetIteratorType targetIter(itkImage, itkImage->GetLargestPossibleRegion());
671  targetIter.GoToBegin();
672 
673  int activeLabel = this->GetActiveLabel(GetActiveLayer())->GetValue();
674 
675  while (!sourceIter.IsAtEnd())
676  {
677  PixelType sourceValue = sourceIter.Get();
678  PixelType targetValue = targetIter.Get();
679 
680  if ((sourceValue != 0) &&
681  (forceOverwrite || !this->GetLabel(targetValue)->GetLocked())) // skip exterior and locked labels
682  {
683  targetIter.Set(activeLabel);
684  }
685  ++sourceIter;
686  ++targetIter;
687  }
688 
689  this->Modified();
690 }
691 
692 template <typename ImageType>
694 {
695  typename ImageType::Pointer itkMask;
696  mitk::CastToItkImage(mask, itkMask);
697 
698  typedef itk::ImageRegionConstIterator<ImageType> SourceIteratorType;
699  typedef itk::ImageRegionIterator<ImageType> TargetIteratorType;
700 
701  SourceIteratorType sourceIter(itkImage, itkImage->GetLargestPossibleRegion());
702  sourceIter.GoToBegin();
703 
704  TargetIteratorType targetIter(itkMask, itkMask->GetLargestPossibleRegion());
705  targetIter.GoToBegin();
706 
707  while (!sourceIter.IsAtEnd())
708  {
709  PixelType sourceValue = sourceIter.Get();
710  if (sourceValue == index)
711  {
712  targetIter.Set(1);
713  }
714  ++sourceIter;
715  ++targetIter;
716  }
717 }
718 
719 template <typename ImageType>
720 void mitk::LabelSetImage::CalculateCenterOfMassProcessing(ImageType *itkImage, PixelType pixelValue, unsigned int layer)
721 {
722  // for now, we just retrieve the voxel in the middle
723  typedef itk::ImageRegionConstIterator<ImageType> IteratorType;
724  IteratorType iter(itkImage, itkImage->GetLargestPossibleRegion());
725  iter.GoToBegin();
726 
727  std::vector<typename ImageType::IndexType> indexVector;
728 
729  while (!iter.IsAtEnd())
730  {
731  // TODO fix comparison warning more effective
732  if (iter.Get() == pixelValue)
733  {
734  indexVector.push_back(iter.GetIndex());
735  }
736  ++iter;
737  }
738 
739  mitk::Point3D pos;
740  pos.Fill(0.0);
741 
742  if (!indexVector.empty())
743  {
744  typename itk::ImageRegionConstIteratorWithIndex<ImageType>::IndexType centerIndex;
745  centerIndex = indexVector.at(indexVector.size() / 2);
746  if (centerIndex.GetIndexDimension() == 3)
747  {
748  pos[0] = centerIndex[0];
749  pos[1] = centerIndex[1];
750  pos[2] = centerIndex[2];
751  }
752  else
753  return;
754  }
755 
756  GetLabelSet(layer)->GetLabel(pixelValue)->SetCenterOfMassIndex(pos);
757  this->GetSlicedGeometry()->IndexToWorld(pos, pos); // TODO: TimeGeometry?
758  GetLabelSet(layer)->GetLabel(pixelValue)->SetCenterOfMassCoordinates(pos);
759 }
760 
761 template <typename ImageType>
763 {
764  itkImage->FillBuffer(0);
765 }
766 
767 // todo: concatenate all layers and not just the active one
768 template <typename ImageType>
770 {
771  typename ImageType::Pointer itkSource = ImageType::New();
772  mitk::CastToItkImage(other, itkSource);
773 
774  typedef itk::ImageRegionConstIterator<ImageType> ConstIteratorType;
775  typedef itk::ImageRegionIterator<ImageType> IteratorType;
776 
777  ConstIteratorType sourceIter(itkSource, itkSource->GetLargestPossibleRegion());
778  IteratorType targetIter(itkTarget, itkTarget->GetLargestPossibleRegion());
779 
780  int numberOfTargetLabels = this->GetNumberOfLabels(GetActiveLayer()) - 1; // skip exterior
781  sourceIter.GoToBegin();
782  targetIter.GoToBegin();
783 
784  while (!sourceIter.IsAtEnd())
785  {
786  PixelType sourceValue = sourceIter.Get();
787  PixelType targetValue = targetIter.Get();
788  if ((sourceValue != 0) && !this->GetLabel(targetValue)->GetLocked()) // skip exterior and locked labels
789  {
790  targetIter.Set(sourceValue + numberOfTargetLabels);
791  }
792  ++sourceIter;
793  ++targetIter;
794  }
795 }
796 
797 template <typename TPixel, unsigned int VImageDimension>
798 void mitk::LabelSetImage::LayerContainerToImageProcessing(itk::Image<TPixel, VImageDimension> *target,
799  unsigned int layer)
800 {
801  typedef itk::Image<TPixel, VImageDimension> ImageType;
802  typename ImageType::Pointer itkSource;
803  // mitk::CastToItkImage(m_LayerContainer[layer], itkSource);
804  itkSource = ImageToItkImage<TPixel, VImageDimension>(m_LayerContainer[layer]);
805  typedef itk::ImageRegionConstIterator<ImageType> SourceIteratorType;
806  typedef itk::ImageRegionIterator<ImageType> TargetIteratorType;
807 
808  SourceIteratorType sourceIter(itkSource, itkSource->GetLargestPossibleRegion());
809  sourceIter.GoToBegin();
810 
811  TargetIteratorType targetIter(target, target->GetLargestPossibleRegion());
812  targetIter.GoToBegin();
813 
814  while (!sourceIter.IsAtEnd())
815  {
816  targetIter.Set(sourceIter.Get());
817  ++sourceIter;
818  ++targetIter;
819  }
820 }
821 
822 template <typename TPixel, unsigned int VImageDimension>
823 void mitk::LabelSetImage::ImageToLayerContainerProcessing(itk::Image<TPixel, VImageDimension> *source,
824  unsigned int layer) const
825 {
826  typedef itk::Image<TPixel, VImageDimension> ImageType;
827  typename ImageType::Pointer itkTarget;
828  // mitk::CastToItkImage(m_LayerContainer[layer], itkTarget);
829  itkTarget = ImageToItkImage<TPixel, VImageDimension>(m_LayerContainer[layer]);
830 
831  typedef itk::ImageRegionConstIterator<ImageType> SourceIteratorType;
832  typedef itk::ImageRegionIterator<ImageType> TargetIteratorType;
833 
834  SourceIteratorType sourceIter(source, source->GetLargestPossibleRegion());
835  sourceIter.GoToBegin();
836 
837  TargetIteratorType targetIter(itkTarget, itkTarget->GetLargestPossibleRegion());
838  targetIter.GoToBegin();
839 
840  while (!sourceIter.IsAtEnd())
841  {
842  targetIter.Set(sourceIter.Get());
843  ++sourceIter;
844  ++targetIter;
845  }
846 }
847 
848 template <typename ImageType>
849 void mitk::LabelSetImage::EraseLabelProcessing(ImageType *itkImage, PixelType pixelValue, unsigned int /*layer*/)
850 {
851  typedef itk::ImageRegionIterator<ImageType> IteratorType;
852 
853  IteratorType iter(itkImage, itkImage->GetLargestPossibleRegion());
854  iter.GoToBegin();
855 
856  while (!iter.IsAtEnd())
857  {
858  PixelType value = iter.Get();
859 
860  if (value == pixelValue)
861  {
862  iter.Set(0);
863  }
864  ++iter;
865  }
866 }
867 
868 template <typename ImageType>
870 {
871  typedef itk::ImageRegionIterator<ImageType> IteratorType;
872 
873  IteratorType iter(itkImage, itkImage->GetLargestPossibleRegion());
874  iter.GoToBegin();
875 
876  while (!iter.IsAtEnd())
877  {
878  if (iter.Get() == index)
879  {
880  iter.Set(pixelValue);
881  }
882  ++iter;
883  }
884 }
885 
886 bool mitk::Equal(const mitk::LabelSetImage &leftHandSide,
887  const mitk::LabelSetImage &rightHandSide,
888  ScalarType eps,
889  bool verbose)
890 {
891  bool returnValue = true;
892 
893  /* LabelSetImage members */
894 
895  MITK_INFO(verbose) << "--- LabelSetImage Equal ---";
896 
897  // number layers
898  returnValue = leftHandSide.GetNumberOfLayers() == rightHandSide.GetNumberOfLayers();
899  if (!returnValue)
900  {
901  MITK_INFO(verbose) << "Number of layers not equal.";
902  return false;
903  }
904 
905  // total number labels
906  returnValue = leftHandSide.GetTotalNumberOfLabels() == rightHandSide.GetTotalNumberOfLabels();
907  if (!returnValue)
908  {
909  MITK_INFO(verbose) << "Total number of labels not equal.";
910  return false;
911  }
912 
913  // active layer
914  returnValue = leftHandSide.GetActiveLayer() == rightHandSide.GetActiveLayer();
915  if (!returnValue)
916  {
917  MITK_INFO(verbose) << "Active layer not equal.";
918  return false;
919  }
920 
921  if (4 == leftHandSide.GetDimension())
922  {
923  MITK_INFO(verbose) << "Can not compare image data for 4D images - skipping check.";
924  }
925  else
926  {
927  // working image data
928  returnValue = mitk::Equal((const mitk::Image &)leftHandSide, (const mitk::Image &)rightHandSide, eps, verbose);
929  if (!returnValue)
930  {
931  MITK_INFO(verbose) << "Working image data not equal.";
932  return false;
933  }
934  }
935 
936  for (unsigned int layerIndex = 0; layerIndex < leftHandSide.GetNumberOfLayers(); layerIndex++)
937  {
938  if (4 == leftHandSide.GetDimension())
939  {
940  MITK_INFO(verbose) << "Can not compare image data for 4D images - skipping check.";
941  }
942  else
943  {
944  // layer image data
945  returnValue =
946  mitk::Equal(*leftHandSide.GetLayerImage(layerIndex), *rightHandSide.GetLayerImage(layerIndex), eps, verbose);
947  if (!returnValue)
948  {
949  MITK_INFO(verbose) << "Layer image data not equal.";
950  return false;
951  }
952  }
953  // layer labelset data
954 
955  returnValue =
956  mitk::Equal(*leftHandSide.GetLabelSet(layerIndex), *rightHandSide.GetLabelSet(layerIndex), eps, verbose);
957  if (!returnValue)
958  {
959  MITK_INFO(verbose) << "Layer labelset data not equal.";
960  return false;
961  }
962  }
963 
964  return returnValue;
965 }
void LayerContainerToImageProcessing(itk::Image< TPixel, VImageDimension > *source, unsigned int layer)
itk::SmartPointer< Self > Pointer
void ClearBufferProcessing(ImageType *input)
Pointer Clone() const
void InitializeByLabeledImageProcessing(LabelSetImageType *input, ImageType *other)
void ImageToLayerContainerProcessing(itk::Image< TPixel, VImageDimension > *source, unsigned int layer) const
#define MITK_INFO
Definition: mitkLogMacros.h:22
void Concatenate(mitk::LabelSetImage *image)
#define AccessFixedDimensionByItk(mitkImage, itkImageTypeFunction, dimension)
Access a mitk-image with known dimension by an itk-image.
virtual void Initialize() override
Definition: mitkImage.cpp:802
double ScalarType
void InitializeByLabeledImage(mitk::Image::Pointer image)
Initialize a new mitk::LabelSetImage by an given image. For all distinct pixel values of the paramete...
#define AccessFixedDimensionByItk_n(mitkImage, itkImageTypeFunction, dimension, va_tuple)
Access a mitk-image with known dimension by an itk-image with one or more parameters.
void RemoveLayer()
Removes the active layer and the respective mitk::LabelSet and image information. The new active laye...
DataCollection - Class to facilitate loading/accessing structured data.
mitk::Label * GetLabel(PixelType pixelValue, unsigned int layer=0) const
Returns the mitk::Label with the given pixelValue and for the given layer.
A data structure describing a label.
Definition: mitkLabel.h:35
const mitk::TimeGeometry * GetTimeGeometry() const
Return the TimeGeometry of the data as const pointer.
Definition: mitkBaseData.h:52
void CalculateCenterOfMassProcessing(ImageType *input, PixelType index, unsigned int layer)
void CreateLabelMaskProcessing(ImageType *input, mitk::Image *mask, PixelType index)
void * GetData()
Gives full data access.
Constants for most interaction classes, due to the generic StateMachines.
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()
static Pointer New()
LabelContainerConstIteratorType IteratorConstEnd() const
Returns a const iterator pointing to the end of the container.
unsigned int GetTotalNumberOfLabels() const
Returns the number of all labels summed up across all layers.
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.
mitk::Label * GetExteriorLabel()
Gets the mitk::Label which is used as default exterior label.
#define AccessByItk_1(mitkImage, itkImageTypeFunction, arg1)
void AddLabelSetToLayer(const unsigned int layerIdx, const mitk::LabelSet::Pointer labelSet)
Add a LabelSet to an existing layer.
mitk::Label::Pointer m_ExteriorLabel
std::vector< Image::Pointer > m_LayerContainer
void RemoveLabels(std::vector< PixelType > &VectorOfLabelPixelValues, unsigned int layer=0)
Removes labels from the mitk::LabelSet of given layer. Calls mitk::LabelSetImage::EraseLabels() which...
static Pointer New()
void MaskStampProcessing(ImageType *input, mitk::Image *mask, bool forceOverwrite)
map::core::discrete::Elements< 3 >::InternalImageType ImageType
unsigned int * GetDimensions() const
Get the sizes of all dimensions as an integer-array.
Definition: mitkImage.cpp:1308
void SetExteriorLabel(mitk::Label *label)
Sets the label which is used as default exterior label when creating a new layer. ...
void MergeLabel(PixelType targetPixelValue, unsigned int layer=0)
Merges the mitk::Label with a given target value with the active label.
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...
#define mitkThrow()
static const PixelType MAX_LABEL_VALUE
The maximum value a label can get: Since the value is of type unsigned short MAX_LABEL_VALUE = 65535...
Definition: mitkLabel.h:45
unsigned int AddLayer(mitk::LabelSet::Pointer layer=nullptr)
Adds a new layer to the LabelSetImage. The new layer will be set as the active one.
mitk::LabelSet * GetActiveLabelSet()
Returns the currently active mitk::LabelSet.
Image class for storing images.
Definition: mitkImage.h:76
unsigned int GetNumberOfLayers() const
void ConcatenateProcessing(ImageType *input, mitk::LabelSetImage *other)
bool ExistLabelSet(unsigned int layer) const
Returns true if the labelset exists.
mitk::Image * GetLayerImage(unsigned int layer)
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.
#define AccessByItk(mitkImage, itkImageTypeFunction)
Access a MITK image by an ITK image.
mitk::Label::PixelType PixelType
static Pointer New()
itk::RGBPixel< float > Color
Color Standard RGB color typedef (float)
void SetActiveLayer(unsigned int layer)
void SetToZero(itk::Image< TPixel, VDimensions > *source)
void UpdateCenterOfMass(PixelType pixelValue, unsigned int layer=0)
MITKNEWMODULE_EXPORT bool Equal(mitk::ExampleDataStructure *leftHandSide, mitk::ExampleDataStructure *rightHandSide, mitk::ScalarType eps, bool verbose)
Returns true if the example data structures are considered equal.
bool ExistLabel(PixelType pixelValue) const
Returns true if the value exists in one of the labelsets.
void MITKCORE_EXPORT CastToItkImage(const mitk::Image *mitkImage, itk::SmartPointer< ItkOutputImageType > &itkOutputImage)
Cast an mitk::Image to an itk::Image with a specific type.
static Pointer New()
LabelSetImage class for handling labels and layers in a segmentation session.
void MaskStamp(mitk::Image *mask, bool forceOverwrite)
MITKCORE_EXPORT const ScalarType eps
#define AccessTwoImagesFixedDimensionByItk(mitkImage1, mitkImage2, itkImageTypeFunction, dimension)
Access two mitk-images with known dimension by itk-images.
Pointer Clone() const
ImageWriteAccessor class to get locked write-access for a particular image part.
#define AccessByItk_2(mitkImage, itkImageTypeFunction, arg1, arg2)
LabelContainerConstIteratorType IteratorConstBegin() const
Returns a const iterator poiting to the begining of the container.
unsigned int GetActiveLayer() const
Gets the ID of the currently active layer.
unsigned int GetDimension() const
Get dimension of the image.
Definition: mitkImage.cpp:110
mitk::LabelSet * GetLabelSet(unsigned int layer=0)
Gets the mitk::LabelSet for the given layer.
LabelSetImage(const LabelSetImage &other)
void MergeLabelProcessing(ImageType *input, PixelType pixelValue, PixelType index)
std::vector< LabelSet::Pointer > m_LabelSetContainer
Class for defining the data type of pixels.
Definition: mitkPixelType.h:55
Pointer Clone() const
void EraseLabelProcessing(ImageType *input, PixelType index, unsigned int layer)
mitk::Image::Pointer CreateLabelMask(PixelType index)
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.