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