diff --git a/Modules/Multilabel/mitkLabelSetImageConverter.cpp b/Modules/Multilabel/mitkLabelSetImageConverter.cpp index 48910a74fd..4b23fdc984 100644 --- a/Modules/Multilabel/mitkLabelSetImageConverter.cpp +++ b/Modules/Multilabel/mitkLabelSetImageConverter.cpp @@ -1,134 +1,160 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkLabelSetImageConverter.h" // mitk includes #include "mitkImageAccessByItk.h" #include "mitkImageCast.h" #include // itk includes #include "itkImage.h" #include "itkVectorImage.h" #include #include +#include "itkImageDuplicator.h" template < typename TPixel, unsigned int VImageDimension > void VectorOfMitkImagesToMitkVectorImage(const itk::Image* source, mitk::Image::Pointer &output, mitk::LabelSetImage::ConstPointer input) { typedef itk::ComposeImageFilter< itk::Image > ComposeFilterType; unsigned int numberOfLayers = input->GetNumberOfLayers(); - - ComposeFilterType::Pointer vectorImageComposer = ComposeFilterType::New(); - - for (unsigned int layer(0); layer < numberOfLayers; layer++) + // 2015/07/01 At the time of writing MITK has problems with mitk::Images encapsulating itk::VectorImage + // if the vector length is less than 2, which might very well happen for segmentations. + if ( numberOfLayers > 1 ) + { // if we have only one image we do not need to create a vector + ComposeFilterType::Pointer vectorImageComposer = ComposeFilterType::New(); + + unsigned int activeLayer = input->GetActiveLayer(); + for (unsigned int layer(0); layer < numberOfLayers; layer++) + { + typename itk::Image::Pointer itkCurrentLayer; + // for the active layer use the current state not the saved one in the vector + if (layer == activeLayer) + { + mitk::CastToItkImage(dynamic_cast(input.GetPointer()), itkCurrentLayer); + } + else + { + mitk::CastToItkImage(input->GetLayerImage(layer), itkCurrentLayer); + } + + vectorImageComposer->SetInput(layer, itkCurrentLayer); + } + + try + { + vectorImageComposer->Update(); + } + catch (const itk::ExceptionObject& e) + { + MITK_ERROR << "Caught exception while updating compose filter: " << e.what(); + } + + output = mitk::GrabItkImageMemory(vectorImageComposer->GetOutput()); + } + else { + // we want the clone to be a mitk::Image, not a mitk::LabelSetImage typename itk::Image::Pointer itkCurrentLayer; - mitk::CastToItkImage(input->GetLayerImage(layer), itkCurrentLayer); + mitk::CastToItkImage(dynamic_cast(input.GetPointer()), itkCurrentLayer); + typedef itk::ImageDuplicator< itk::Image > DuplicatorType; + DuplicatorType::Pointer duplicator = DuplicatorType::New(); + duplicator->SetInputImage(itkCurrentLayer); + duplicator->Update(); - vectorImageComposer->SetInput(layer, itkCurrentLayer); + output = mitk::GrabItkImageMemory(duplicator->GetOutput()); } - - try - { - vectorImageComposer->Update(); - } - catch (const itk::ExceptionObject& e) - { - MITK_ERROR << "Caugt exception while updating compose filter: " << e.what(); - } - - output = mitk::GrabItkImageMemory(vectorImageComposer->GetOutput()); output->SetGeometry(input->GetGeometry()->Clone()); } mitk::Image::Pointer mitk::LabelSetImageConverter::ConvertLabelSetImageToImage(const mitk::LabelSetImage::ConstPointer input) { unsigned int numberOfLayers = input->GetNumberOfLayers(); if (numberOfLayers == 0) { mitkThrow() << "Tried to convert LabelSetImage without layers"; } mitk::Image::Pointer output; AccessByItk_2(input->GetLayerImage(0), VectorOfMitkImagesToMitkVectorImage, output, input); return output; } template void MitkImageToMitkLabelSetImage(itk::Image< TPixel, VDimensions> * source, mitk::LabelSetImage::Pointer &output) { // do nothing for non-vector images } template void MitkImageToMitkLabelSetImage(itk::VectorImage< TPixel, VDimensions> * source, mitk::LabelSetImage::Pointer &output) { typedef itk::VectorImage< TPixel, VDimensions > VectorImageType; typedef itk::Image< TPixel, VDimensions > ImageType; typedef itk::VectorIndexSelectionCastImageFilter< VectorImageType, ImageType > VectorIndexSelectorType; unsigned int numberOfComponents = source->GetVectorLength(); if (numberOfComponents < 1) { mitkThrow() << "At least one Component is required." } typename VectorIndexSelectorType::Pointer vectorIndexSelector = typename VectorIndexSelectorType::New(); VectorIndexSelector->SetIndex(0); VectorIndexSelector->SetInput(source); mitk::Image::Pointer tempImage; mitk::GrabItkImageMemory(VectorIndexSelector->GetOutput(), tempImage); output = mitk::LabelSetImage::New(); output->InitializeByLabeledImage(tempImage); for (unsigned int layer = 1; layer < numberOfComponents; ++layer) { typename VectorIndexSelectorType::Pointer vectorIndexSelectorLoop = typename VectorIndexSelectorType::New(); VectorIndexSelectorLoop->SetIndex(layer); VectorIndexSelector->SetInput(source); mitk::Image::Pointer loopImage; mitk::GrabItkImageMemory(vectorIndexSelectorLoop->GetOutput(), loopImage); output->AddLayer(loopImage); } } mitk::LabelSetImage::Pointer mitk::LabelSetImageConverter::ConvertImageToLabelSetImage(const mitk::Image::Pointer input) { mitk::LabelSetImage::Pointer output; AccessByItk_1(input, MitkImageToMitkLabelSetImage, output); // if no vector image was detected if ( output.IsNull() ) { output = mitk::LabelSetImage::New(); output->InitializeByLabeledImage( input ); } return output; }