28 #include <vtkTransform.h>
29 #include <vtkTransformPolyDataFilter.h>
31 #include <itkImageRegionIterator.h>
32 #include <itkQuadEdgeMesh.h>
33 #include <itkTriangleMeshToBinaryImageFilter.h>
36 #include <itkCommand.h>
38 template <
typename TPixel,
unsigned int VDimensions>
39 void SetToZero(itk::Image<TPixel, VDimensions> *source)
41 source->FillBuffer(0);
45 :
mitk::
Image(), m_ActiveLayer(0), m_activeLayerInvalid(false), m_ExteriorLabel(nullptr)
60 m_ActiveLayer(other.GetActiveLayer()),
61 m_activeLayerInvalid(false),
62 m_ExteriorLabel(other.GetExteriorLabel()->
Clone())
71 lsClone->AddObserver(itk::ModifiedEvent(), command);
82 Superclass::Modified();
87 m_ExteriorLabel = label;
92 return m_ExteriorLabel;
97 return m_ExteriorLabel;
102 mitk::PixelType pixelType(mitk::MakeScalarPixelType<LabelSetImage::PixelType>());
106 Superclass::Initialize(pixelType, 3, dimensions);
114 this->SetTimeGeometry(originalGeometry);
117 if (4 == this->GetDimension())
132 m_LabelSetContainer.clear();
137 return m_LayerContainer[layer];
142 return m_LayerContainer[layer];
147 return m_ActiveLayer;
152 return m_LabelSetContainer.size();
157 int layerToDelete = GetActiveLayer();
159 GetLabelSet(layerToDelete)->RemoveAllObservers();
162 if (layerToDelete != 0)
164 SetActiveLayer(layerToDelete - 1);
169 m_activeLayerInvalid =
true;
173 m_LabelSetContainer.erase(m_LabelSetContainer.begin() + layerToDelete);
174 m_LayerContainer.erase(m_LayerContainer.begin() + layerToDelete);
176 if (layerToDelete == 0)
178 this->SetActiveLayer(layerToDelete);
188 this->GetDimension(),
189 this->GetDimensions(),
190 this->GetImageDescriptor()->GetNumberOfChannels());
191 newImage->SetTimeGeometry(this->GetTimeGeometry()->
Clone());
193 if (newImage->GetDimension() < 4)
202 unsigned int newLabelSetId = this->AddLayer(newImage, lset);
204 return newLabelSetId;
209 unsigned int newLabelSetId = m_LayerContainer.size();
213 if (lset.IsNotNull())
220 ls->AddLabel(GetExteriorLabel());
221 ls->SetActiveLabel(0 );
224 ls->SetLayer(newLabelSetId);
229 m_LayerContainer.push_back(layerImage);
232 m_LabelSetContainer.push_back(ls);
237 ls->AddObserver(itk::ModifiedEvent(), command);
239 SetActiveLayer(newLabelSetId);
242 return newLabelSetId;
247 if (m_LayerContainer.size() <= layerIdx)
249 mitkThrow() <<
"Trying to add labelSet to non-existing layer.";
252 if (layerIdx < m_LabelSetContainer.size())
254 m_LabelSetContainer[layerIdx] = labelSet;
258 while (layerIdx >= m_LabelSetContainer.size())
261 defaultLabelSet->AddLabel(GetExteriorLabel());
262 defaultLabelSet->SetActiveLabel(0 );
263 defaultLabelSet->SetLayer(m_LabelSetContainer.size());
264 m_LabelSetContainer.push_back(defaultLabelSet);
266 m_LabelSetContainer.push_back(labelSet);
274 if (4 == this->GetDimension())
276 if ((layer != GetActiveLayer() || m_activeLayerInvalid) && (layer < this->GetNumberOfLayers()))
278 BeforeChangeLayerEvent.Send();
280 if (m_activeLayerInvalid)
283 m_activeLayerInvalid =
false;
289 m_ActiveLayer = layer;
292 AfterChangeLayerEvent.Send();
297 if ((layer != GetActiveLayer() || m_activeLayerInvalid) && (layer < this->GetNumberOfLayers()))
299 BeforeChangeLayerEvent.Send();
301 if (m_activeLayerInvalid)
304 m_activeLayerInvalid =
false;
308 AccessByItk_1(
this, ImageToLayerContainerProcessing, GetActiveLayer());
310 m_ActiveLayer = layer;
311 AccessByItk_1(
this, LayerContainerToImageProcessing, GetActiveLayer());
313 AfterChangeLayerEvent.Send();
317 catch (itk::ExceptionObject &e)
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.";
334 for (
int layer = 0; layer < numberOfLayers; ++layer)
336 this->SetActiveLayer(layer);
344 GetLabelSet()->AddLabel((it->second));
350 catch (itk::ExceptionObject &e)
364 catch (itk::ExceptionObject &e)
373 for (
unsigned int lidx = 0; lidx < GetNumberOfLayers(); lidx++)
374 exist |= m_LabelSetContainer[lidx]->ExistLabel(pixelValue);
380 bool exist = m_LabelSetContainer[layer]->ExistLabel(pixelValue);
386 return layer < m_LabelSetContainer.size();
391 int targetPixelValue = this->GetActiveLabel(GetActiveLayer())->GetValue();
394 AccessByItk_2(
this, MergeLabelProcessing, targetPixelValue, pixelValue);
396 catch (itk::ExceptionObject &e)
407 GetLabelSet(layer)->SetActiveLabel(pixelValue);
410 for (
unsigned int idx = 0; idx < VectorOfLablePixelValues.size(); idx++)
412 AccessByItk_2(
this, MergeLabelProcessing, pixelValue, VectorOfLablePixelValues[idx]);
415 catch (itk::ExceptionObject &e)
424 for (
unsigned int idx = 0; idx < VectorOfLabelPixelValues.size(); idx++)
426 GetLabelSet(layer)->RemoveLabel(VectorOfLabelPixelValues[idx]);
427 EraseLabel(VectorOfLabelPixelValues[idx], layer);
433 for (
unsigned int i = 0; i < VectorOfLabelPixelValues.size(); i++)
435 this->EraseLabel(VectorOfLabelPixelValues[i], layer);
443 AccessByItk_2(
this, EraseLabelProcessing, pixelValue, layer);
445 catch (itk::ExceptionObject &e)
454 if (m_LabelSetContainer.size() <= layer)
457 return m_LabelSetContainer[layer]->GetActiveLabel();;
462 if (m_LabelSetContainer.size() <= layer)
465 return m_LabelSetContainer[layer]->GetLabel(pixelValue);
470 if (m_LabelSetContainer.size() <= layer)
473 return m_LabelSetContainer[layer].GetPointer();
478 if (m_LabelSetContainer.size() <= layer)
481 return m_LabelSetContainer[layer].GetPointer();
486 if (m_LabelSetContainer.size() == 0)
489 return m_LabelSetContainer[GetActiveLayer()].GetPointer();
494 AccessByItk_2(
this, CalculateCenterOfMassProcessing, pixelValue, layer);
499 return m_LabelSetContainer[layer]->GetNumberOfLabels();
504 unsigned int totalLabels(0);
505 auto layerIter = m_LabelSetContainer.begin();
506 for (; layerIter != m_LabelSetContainer.end(); ++layerIter)
507 totalLabels += (*layerIter)->GetNumberOfLabels();
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);
523 padImageFilter->Update();
527 if (paddedMask.IsNull())
530 AccessByItk_2(
this, MaskStampProcessing, paddedMask, forceOverwrite);
534 mitkThrow() <<
"Could not stamp the provided mask on the selected label.";
543 mask->Initialize(
this);
546 for (
unsigned int dim = 0; dim < mask->GetDimension(); ++dim)
548 byteSize *= mask->GetDimension(dim);
552 memset(accessor->
GetData(), 0, byteSize);
555 auto geometry = this->GetTimeGeometry()->Clone();
556 mask->SetTimeGeometry(geometry);
562 mitkThrow() <<
"Could not create a mask out of the selected label.";
570 if (image.IsNull() || image->IsEmpty() || !image->IsInitialized())
575 this->Initialize(image);
578 for (
unsigned int dim = 0; dim < image->GetDimension(); ++dim)
580 byteSize *= image->GetDimension(dim);
584 memset(accessor->
GetData(), 0, byteSize);
587 auto geometry = image->GetTimeGeometry()->Clone();
588 this->SetTimeGeometry(geometry);
590 if (image->GetDimension() == 3)
594 else if (image->GetDimension() == 4)
600 mitkThrow() << image->GetDimension() <<
"-dimensional label set images not yet supported";
605 mitkThrow() <<
"Could not intialize by provided labeled image.";
610 template <
typename LabelSetImageType,
typename ImageType>
613 typedef itk::ImageRegionConstIteratorWithIndex<ImageType> SourceIteratorType;
614 typedef itk::ImageRegionIterator<LabelSetImageType> TargetIteratorType;
616 TargetIteratorType targetIter(labelSetImage, labelSetImage->GetRequestedRegion());
617 targetIter.GoToBegin();
619 SourceIteratorType sourceIter(image, image->GetRequestedRegion());
620 sourceIter.GoToBegin();
622 while (!sourceIter.IsAtEnd())
625 targetIter.Set(sourceValue);
627 if (!this->ExistLabel(sourceValue))
629 std::stringstream name;
630 name <<
"object-" << sourceValue;
633 m_LabelSetContainer[this->GetActiveLayer()]->GetLookupTable()->GetTableValue(sourceValue, rgba);
636 color.SetRed(rgba[0]);
637 color.SetGreen(rgba[1]);
638 color.SetBlue(rgba[2]);
641 label->SetName(name.str().c_str());
642 label->SetColor(color);
643 label->SetOpacity(rgba[3]);
644 label->SetValue(sourceValue);
646 this->GetLabelSet()->AddLabel(label);
658 template <
typename ImageType>
664 typedef itk::ImageRegionConstIterator<ImageType> SourceIteratorType;
665 typedef itk::ImageRegionIterator<ImageType> TargetIteratorType;
667 SourceIteratorType sourceIter(itkMask, itkMask->GetLargestPossibleRegion());
668 sourceIter.GoToBegin();
670 TargetIteratorType targetIter(itkImage, itkImage->GetLargestPossibleRegion());
671 targetIter.GoToBegin();
673 int activeLabel = this->GetActiveLabel(GetActiveLayer())->GetValue();
675 while (!sourceIter.IsAtEnd())
677 PixelType sourceValue = sourceIter.Get();
678 PixelType targetValue = targetIter.Get();
680 if ((sourceValue != 0) &&
681 (forceOverwrite || !this->GetLabel(targetValue)->GetLocked()))
683 targetIter.Set(activeLabel);
692 template <
typename ImageType>
698 typedef itk::ImageRegionConstIterator<ImageType> SourceIteratorType;
699 typedef itk::ImageRegionIterator<ImageType> TargetIteratorType;
701 SourceIteratorType sourceIter(itkImage, itkImage->GetLargestPossibleRegion());
702 sourceIter.GoToBegin();
704 TargetIteratorType targetIter(itkMask, itkMask->GetLargestPossibleRegion());
705 targetIter.GoToBegin();
707 while (!sourceIter.IsAtEnd())
709 PixelType sourceValue = sourceIter.Get();
710 if (sourceValue == index)
719 template <
typename ImageType>
723 typedef itk::ImageRegionConstIterator<ImageType> IteratorType;
724 IteratorType iter(itkImage, itkImage->GetLargestPossibleRegion());
727 std::vector<typename ImageType::IndexType> indexVector;
729 while (!iter.IsAtEnd())
732 if (iter.Get() == pixelValue)
734 indexVector.push_back(iter.GetIndex());
742 if (!indexVector.empty())
744 typename itk::ImageRegionConstIteratorWithIndex<ImageType>::IndexType centerIndex;
745 centerIndex = indexVector.at(indexVector.size() / 2);
746 if (centerIndex.GetIndexDimension() == 3)
748 pos[0] = centerIndex[0];
749 pos[1] = centerIndex[1];
750 pos[2] = centerIndex[2];
756 GetLabelSet(layer)->GetLabel(pixelValue)->SetCenterOfMassIndex(pos);
757 this->GetSlicedGeometry()->IndexToWorld(pos, pos);
758 GetLabelSet(layer)->GetLabel(pixelValue)->SetCenterOfMassCoordinates(pos);
761 template <
typename ImageType>
764 itkImage->FillBuffer(0);
768 template <
typename ImageType>
774 typedef itk::ImageRegionConstIterator<ImageType> ConstIteratorType;
775 typedef itk::ImageRegionIterator<ImageType> IteratorType;
777 ConstIteratorType sourceIter(itkSource, itkSource->GetLargestPossibleRegion());
778 IteratorType targetIter(itkTarget, itkTarget->GetLargestPossibleRegion());
780 int numberOfTargetLabels = this->GetNumberOfLabels(GetActiveLayer()) - 1;
781 sourceIter.GoToBegin();
782 targetIter.GoToBegin();
784 while (!sourceIter.IsAtEnd())
786 PixelType sourceValue = sourceIter.Get();
787 PixelType targetValue = targetIter.Get();
788 if ((sourceValue != 0) && !this->GetLabel(targetValue)->GetLocked())
790 targetIter.Set(sourceValue + numberOfTargetLabels);
797 template <
typename TPixel,
unsigned int VImageDimension>
801 typedef itk::Image<TPixel, VImageDimension>
ImageType;
804 itkSource = ImageToItkImage<TPixel, VImageDimension>(m_LayerContainer[layer]);
805 typedef itk::ImageRegionConstIterator<ImageType> SourceIteratorType;
806 typedef itk::ImageRegionIterator<ImageType> TargetIteratorType;
808 SourceIteratorType sourceIter(itkSource, itkSource->GetLargestPossibleRegion());
809 sourceIter.GoToBegin();
811 TargetIteratorType targetIter(target, target->GetLargestPossibleRegion());
812 targetIter.GoToBegin();
814 while (!sourceIter.IsAtEnd())
816 targetIter.Set(sourceIter.Get());
822 template <
typename TPixel,
unsigned int VImageDimension>
824 unsigned int layer)
const
826 typedef itk::Image<TPixel, VImageDimension>
ImageType;
829 itkTarget = ImageToItkImage<TPixel, VImageDimension>(m_LayerContainer[layer]);
831 typedef itk::ImageRegionConstIterator<ImageType> SourceIteratorType;
832 typedef itk::ImageRegionIterator<ImageType> TargetIteratorType;
834 SourceIteratorType sourceIter(source, source->GetLargestPossibleRegion());
835 sourceIter.GoToBegin();
837 TargetIteratorType targetIter(itkTarget, itkTarget->GetLargestPossibleRegion());
838 targetIter.GoToBegin();
840 while (!sourceIter.IsAtEnd())
842 targetIter.Set(sourceIter.Get());
848 template <
typename ImageType>
851 typedef itk::ImageRegionIterator<ImageType> IteratorType;
853 IteratorType iter(itkImage, itkImage->GetLargestPossibleRegion());
856 while (!iter.IsAtEnd())
860 if (value == pixelValue)
868 template <
typename ImageType>
871 typedef itk::ImageRegionIterator<ImageType> IteratorType;
873 IteratorType iter(itkImage, itkImage->GetLargestPossibleRegion());
876 while (!iter.IsAtEnd())
878 if (iter.Get() == index)
880 iter.Set(pixelValue);
891 bool returnValue =
true;
895 MITK_INFO(verbose) <<
"--- LabelSetImage Equal ---";
901 MITK_INFO(verbose) <<
"Number of layers not equal.";
909 MITK_INFO(verbose) <<
"Total number of labels not equal.";
917 MITK_INFO(verbose) <<
"Active layer not equal.";
923 MITK_INFO(verbose) <<
"Can not compare image data for 4D images - skipping check.";
931 MITK_INFO(verbose) <<
"Working image data not equal.";
936 for (
unsigned int layerIndex = 0; layerIndex < leftHandSide.
GetNumberOfLayers(); layerIndex++)
940 MITK_INFO(verbose) <<
"Can not compare image data for 4D images - skipping check.";
949 MITK_INFO(verbose) <<
"Layer image data not equal.";
959 MITK_INFO(verbose) <<
"Layer labelset data not equal.";
void LayerContainerToImageProcessing(itk::Image< TPixel, VImageDimension > *source, unsigned int layer)
itk::SmartPointer< Self > Pointer
void ClearBufferProcessing(ImageType *input)
void InitializeByLabeledImageProcessing(LabelSetImageType *input, ImageType *other)
void ImageToLayerContainerProcessing(itk::Image< TPixel, VImageDimension > *source, unsigned int layer) const
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
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 OnLabelSetModified()
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.
const mitk::TimeGeometry * GetTimeGeometry() const
Return the TimeGeometry of the data as const pointer.
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()
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...
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.
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...
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...
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.
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
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.
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.
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.
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.
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.