diff --git a/Modules/Core/TestingHelper/src/mitkTestDynamicImageGenerator.cpp b/Modules/Core/TestingHelper/src/mitkTestDynamicImageGenerator.cpp index 73a8af779d..c53112436a 100644 --- a/Modules/Core/TestingHelper/src/mitkTestDynamicImageGenerator.cpp +++ b/Modules/Core/TestingHelper/src/mitkTestDynamicImageGenerator.cpp @@ -1,253 +1,212 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkTestDynamicImageGenerator.h" #include "mitkArbitraryTimeGeometry.h" #include "mitkImageCast.h" +#include "mitkDynamicImageGenerationFilter.h" namespace mitk { typedef itk::Image FrameITKImageType; typedef itk::Image DynamicITKImageType; typedef itk::Image MaskITKImageType; TestImageType::Pointer GenerateTestImage(int factor) { TestImageType::Pointer image = TestImageType::New(); TestImageType::IndexType start; start[0] = 0; // first index on X start[1] = 0; // first index on Y TestImageType::SizeType size; size[0] = 3; // size along X size[1] = 3; // size along Y TestImageType::RegionType region; region.SetSize(size); region.SetIndex(start); image->SetRegions(region); image->Allocate(); itk::ImageRegionIterator it = itk::ImageRegionIterator(image, image->GetLargestPossibleRegion()); int count = 1; while (!it.IsAtEnd()) { it.Set(count * factor); ++it; ++count; } return image; } TestMaskType::Pointer GenerateTestMask() { TestMaskType::Pointer image = TestMaskType::New(); TestMaskType::IndexType start; start[0] = 0; // first index on X start[1] = 0; // first index on Y TestMaskType::SizeType size; size[0] = 3; // size along X size[1] = 3; // size along Y TestMaskType::RegionType region; region.SetSize(size); region.SetIndex(start); image->SetRegions(region); image->Allocate(); itk::ImageRegionIterator it = itk::ImageRegionIterator(image, image->GetLargestPossibleRegion()); int count = 1; while (!it.IsAtEnd()) { if (count > 1 && count < 5) { it.Set(1); } else { it.Set(0); } ++it; ++count; } return image; } Image::Pointer GenerateTestFrame(double timePoint) { FrameITKImageType::Pointer image = FrameITKImageType::New(); FrameITKImageType::IndexType start; start[0] = 0; // first index on X start[1] = 0; // first index on Y start[2] = 0; // first index on Z FrameITKImageType::SizeType size; size[0] = 3; // size along X size[1] = 3; // size along Y size[2] = 3; // size along Z FrameITKImageType::RegionType region; region.SetSize(size); region.SetIndex(start); image->SetRegions(region); image->Allocate(); itk::ImageRegionIterator it = itk::ImageRegionIterator(image, image->GetLargestPossibleRegion()); int count = 0; while (!it.IsAtEnd()) { double slope = count % (size[0] * size[1]); double offset = itk::Math::Floor(count / (size[0] * size[1])) * 10; it.Set(slope * timePoint + offset); ++it; ++count; } mitk::Image::Pointer mitkImage = mitk::Image::New(); mitkImage->InitializeByItk(image.GetPointer()); mitkImage->SetVolume(image->GetBufferPointer()); return mitkImage; } Image::Pointer GenerateTestMaskMITK() { MaskITKImageType::Pointer image = MaskITKImageType::New(); MaskITKImageType::IndexType start; start[0] = 0; // first index on X start[1] = 0; // first index on Y start[2] = 0; // first index on Z MaskITKImageType::SizeType size; size[0] = 3; // size along X size[1] = 3; // size along Y size[2] = 3; // size along Z MaskITKImageType::RegionType region; region.SetSize(size); region.SetIndex(start); image->SetRegions(region); image->Allocate(); itk::ImageRegionIterator it = itk::ImageRegionIterator(image, image->GetLargestPossibleRegion()); int count = 0; while (!it.IsAtEnd()) { if (count < 14) { it.Set(1); } else { it.Set(0); } ++it; ++count; } mitk::Image::Pointer mitkImage = mitk::Image::New(); mitkImage->InitializeByItk(image.GetPointer()); mitkImage->SetVolume(image->GetBufferPointer()); return mitkImage; } Image::Pointer GenerateDynamicTestImageMITK() { + auto filter = mitk::DynamicImageGenerationFilter::New(); - mitk::Image::Pointer tempImage = GenerateTestFrame(1); - mitk::Image::Pointer dynamicImage = mitk::Image::New(); - - DynamicITKImageType::Pointer dynamicITKImage = DynamicITKImageType::New(); - DynamicITKImageType::RegionType dynamicITKRegion; - DynamicITKImageType::PointType dynamicITKOrigin; - DynamicITKImageType::IndexType dynamicITKIndex; - DynamicITKImageType::SpacingType dynamicITKSpacing; - - dynamicITKSpacing[0] = tempImage->GetGeometry()->GetSpacing()[0]; - dynamicITKSpacing[1] = tempImage->GetGeometry()->GetSpacing()[1]; - dynamicITKSpacing[2] = tempImage->GetGeometry()->GetSpacing()[2]; - dynamicITKSpacing[3] = 5.0; - - dynamicITKIndex[0] = 0; // The first pixel of the REGION - dynamicITKIndex[1] = 0; - dynamicITKIndex[2] = 0; - dynamicITKIndex[3] = 0; - - dynamicITKRegion.SetSize(0, tempImage->GetDimension(0)); - dynamicITKRegion.SetSize(1, tempImage->GetDimension(1)); - dynamicITKRegion.SetSize(2, tempImage->GetDimension(2)); - dynamicITKRegion.SetSize(3, 10); - - dynamicITKRegion.SetIndex(dynamicITKIndex); - - dynamicITKOrigin[0] = tempImage->GetGeometry()->GetOrigin()[0]; - dynamicITKOrigin[1] = tempImage->GetGeometry()->GetOrigin()[1]; - dynamicITKOrigin[2] = tempImage->GetGeometry()->GetOrigin()[2]; - - dynamicITKImage->SetOrigin(dynamicITKOrigin); - dynamicITKImage->SetSpacing(dynamicITKSpacing); - dynamicITKImage->SetRegions(dynamicITKRegion); - dynamicITKImage->Allocate(); - dynamicITKImage->FillBuffer(0); //not sure if this is necessary - - // Convert - mitk::CastToMitkImage(dynamicITKImage, dynamicImage); - - ArbitraryTimeGeometry::Pointer timeGeometry = ArbitraryTimeGeometry::New(); - timeGeometry->ClearAllGeometries(); - - + mitk::DynamicImageGenerationFilter::TimeBoundsVectorType bounds; for (int i = 0; i < 10; ++i) { - mitk::Image::Pointer frameImage = GenerateTestFrame(1 + (dynamicITKSpacing[3] * i)); - mitk::ImageReadAccessor accessor(frameImage); - dynamicImage->SetVolume(accessor.GetData(), i); - - timeGeometry->AppendNewTimeStepClone(frameImage->GetGeometry(), 1 + (dynamicITKSpacing[3] * i), - 1 + (dynamicITKSpacing[3]*(i+1))); + filter->SetInput(i, GenerateTestFrame(1 + (5.0 * i))); + bounds.push_back(1 + (5.0 * (i + 1))); } - dynamicImage->SetTimeGeometry(timeGeometry); + filter->SetFirstMinTimeBound(1.); + filter->SetMaxTimeBounds(bounds); + + filter->Update(); - return dynamicImage; + return filter->GetOutput(); } } diff --git a/Modules/Core/files.cmake b/Modules/Core/files.cmake index e13405173c..d27e5a27de 100644 --- a/Modules/Core/files.cmake +++ b/Modules/Core/files.cmake @@ -1,323 +1,324 @@ file(GLOB_RECURSE H_FILES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/include/*") set(CPP_FILES mitkCoreActivator.cpp mitkCoreObjectFactoryBase.cpp mitkCoreObjectFactory.cpp mitkCoreServices.cpp mitkException.cpp Algorithms/mitkBaseDataSource.cpp Algorithms/mitkClippedSurfaceBoundsCalculator.cpp Algorithms/mitkCompareImageDataFilter.cpp Algorithms/mitkCompositePixelValueToString.cpp Algorithms/mitkConvert2Dto3DImageFilter.cpp Algorithms/mitkDataNodeSource.cpp Algorithms/mitkExtractSliceFilter.cpp Algorithms/mitkExtractSliceFilter2.cpp Algorithms/mitkHistogramGenerator.cpp Algorithms/mitkImageChannelSelector.cpp Algorithms/mitkImageSliceSelector.cpp Algorithms/mitkImageSource.cpp Algorithms/mitkImageTimeSelector.cpp Algorithms/mitkImageToImageFilter.cpp Algorithms/mitkImageToSurfaceFilter.cpp Algorithms/mitkMultiComponentImageDataComparisonFilter.cpp Algorithms/mitkPlaneGeometryDataToSurfaceFilter.cpp Algorithms/mitkPointSetSource.cpp Algorithms/mitkPointSetToPointSetFilter.cpp Algorithms/mitkRGBToRGBACastImageFilter.cpp Algorithms/mitkSubImageSelector.cpp Algorithms/mitkSurfaceSource.cpp Algorithms/mitkSurfaceToImageFilter.cpp Algorithms/mitkSurfaceToSurfaceFilter.cpp Algorithms/mitkUIDGenerator.cpp Algorithms/mitkVolumeCalculator.cpp + Algorithms/mitkDynamicImageGenerationFilter.cpp Controllers/mitkBaseController.cpp Controllers/mitkCallbackFromGUIThread.cpp Controllers/mitkCameraController.cpp Controllers/mitkCameraRotationController.cpp Controllers/mitkLimitedLinearUndo.cpp Controllers/mitkOperationEvent.cpp Controllers/mitkPlanePositionManager.cpp Controllers/mitkProgressBar.cpp Controllers/mitkRenderingManager.cpp Controllers/mitkSliceNavigationController.cpp Controllers/mitkSlicesCoordinator.cpp Controllers/mitkStatusBar.cpp Controllers/mitkStepper.cpp Controllers/mitkTestManager.cpp Controllers/mitkUndoController.cpp Controllers/mitkVerboseLimitedLinearUndo.cpp Controllers/mitkVtkLayerController.cpp DataManagement/mitkAnatomicalStructureColorPresets.cpp DataManagement/mitkArbitraryTimeGeometry.cpp DataManagement/mitkAbstractTransformGeometry.cpp DataManagement/mitkAnnotationProperty.cpp DataManagement/mitkApplicationCursor.cpp DataManagement/mitkApplyTransformMatrixOperation.cpp DataManagement/mitkBaseData.cpp DataManagement/mitkBaseGeometry.cpp DataManagement/mitkBaseProperty.cpp DataManagement/mitkChannelDescriptor.cpp DataManagement/mitkClippingProperty.cpp DataManagement/mitkColorProperty.cpp DataManagement/mitkDataNode.cpp DataManagement/mitkDataStorage.cpp DataManagement/mitkEnumerationProperty.cpp DataManagement/mitkFloatPropertyExtension.cpp DataManagement/mitkGeometry3D.cpp DataManagement/mitkGeometryData.cpp DataManagement/mitkGeometryTransformHolder.cpp DataManagement/mitkGroupTagProperty.cpp DataManagement/mitkGenericIDRelationRule.cpp DataManagement/mitkIdentifiable.cpp DataManagement/mitkImageAccessorBase.cpp DataManagement/mitkImageCaster.cpp DataManagement/mitkImageCastPart1.cpp DataManagement/mitkImageCastPart2.cpp DataManagement/mitkImageCastPart3.cpp DataManagement/mitkImageCastPart4.cpp DataManagement/mitkImage.cpp DataManagement/mitkImageDataItem.cpp DataManagement/mitkImageDescriptor.cpp DataManagement/mitkImageReadAccessor.cpp DataManagement/mitkImageStatisticsHolder.cpp DataManagement/mitkImageVtkAccessor.cpp DataManagement/mitkImageVtkReadAccessor.cpp DataManagement/mitkImageVtkWriteAccessor.cpp DataManagement/mitkImageWriteAccessor.cpp DataManagement/mitkIntPropertyExtension.cpp DataManagement/mitkIPersistenceService.cpp DataManagement/mitkIPropertyAliases.cpp DataManagement/mitkIPropertyDescriptions.cpp DataManagement/mitkIPropertyExtensions.cpp DataManagement/mitkIPropertyFilters.cpp DataManagement/mitkIPropertyOwner.cpp DataManagement/mitkIPropertyPersistence.cpp DataManagement/mitkIPropertyProvider.cpp DataManagement/mitkLandmarkProjectorBasedCurvedGeometry.cpp DataManagement/mitkLandmarkProjector.cpp DataManagement/mitkLevelWindow.cpp DataManagement/mitkLevelWindowManager.cpp DataManagement/mitkLevelWindowPreset.cpp DataManagement/mitkLevelWindowProperty.cpp DataManagement/mitkLine.cpp DataManagement/mitkLookupTable.cpp DataManagement/mitkLookupTableProperty.cpp DataManagement/mitkLookupTables.cpp # specializations of GenericLookupTable DataManagement/mitkMaterial.cpp DataManagement/mitkMemoryUtilities.cpp DataManagement/mitkModalityProperty.cpp DataManagement/mitkModifiedLock.cpp DataManagement/mitkNodePredicateAnd.cpp DataManagement/mitkNodePredicateBase.cpp DataManagement/mitkNodePredicateCompositeBase.cpp DataManagement/mitkNodePredicateData.cpp DataManagement/mitkNodePredicateDataType.cpp DataManagement/mitkNodePredicateDataUID.cpp DataManagement/mitkNodePredicateDimension.cpp DataManagement/mitkNodePredicateFirstLevel.cpp DataManagement/mitkNodePredicateFunction.cpp DataManagement/mitkNodePredicateGeometry.cpp DataManagement/mitkNodePredicateNot.cpp DataManagement/mitkNodePredicateOr.cpp DataManagement/mitkNodePredicateProperty.cpp DataManagement/mitkNodePredicateDataProperty.cpp DataManagement/mitkNodePredicateSource.cpp DataManagement/mitkNumericConstants.cpp DataManagement/mitkPlaneGeometry.cpp DataManagement/mitkPlaneGeometryData.cpp DataManagement/mitkPlaneOperation.cpp DataManagement/mitkPlaneOrientationProperty.cpp DataManagement/mitkPointOperation.cpp DataManagement/mitkPointSet.cpp DataManagement/mitkPointSetShapeProperty.cpp DataManagement/mitkProperties.cpp DataManagement/mitkPropertyAliases.cpp DataManagement/mitkPropertyDescriptions.cpp DataManagement/mitkPropertyExtension.cpp DataManagement/mitkPropertyExtensions.cpp DataManagement/mitkPropertyFilter.cpp DataManagement/mitkPropertyFilters.cpp DataManagement/mitkPropertyKeyPath.cpp DataManagement/mitkPropertyList.cpp DataManagement/mitkPropertyListReplacedObserver.cpp DataManagement/mitkPropertyNameHelper.cpp DataManagement/mitkPropertyObserver.cpp DataManagement/mitkPropertyPersistence.cpp DataManagement/mitkPropertyPersistenceInfo.cpp DataManagement/mitkPropertyRelationRuleBase.cpp DataManagement/mitkProportionalTimeGeometry.cpp DataManagement/mitkRenderingModeProperty.cpp DataManagement/mitkResliceMethodProperty.cpp DataManagement/mitkRestorePlanePositionOperation.cpp DataManagement/mitkRotationOperation.cpp DataManagement/mitkScaleOperation.cpp DataManagement/mitkSlicedData.cpp DataManagement/mitkSlicedGeometry3D.cpp DataManagement/mitkSmartPointerProperty.cpp DataManagement/mitkStandaloneDataStorage.cpp DataManagement/mitkStringProperty.cpp DataManagement/mitkSurface.cpp DataManagement/mitkSurfaceOperation.cpp DataManagement/mitkSourceImageRelationRule.cpp DataManagement/mitkThinPlateSplineCurvedGeometry.cpp DataManagement/mitkTimeGeometry.cpp DataManagement/mitkTransferFunction.cpp DataManagement/mitkTransferFunctionInitializer.cpp DataManagement/mitkTransferFunctionProperty.cpp DataManagement/mitkTemporoSpatialStringProperty.cpp DataManagement/mitkUIDManipulator.cpp DataManagement/mitkVector.cpp DataManagement/mitkVectorProperty.cpp DataManagement/mitkVtkInterpolationProperty.cpp DataManagement/mitkVtkRepresentationProperty.cpp DataManagement/mitkVtkResliceInterpolationProperty.cpp DataManagement/mitkVtkScalarModeProperty.cpp DataManagement/mitkVtkVolumeRenderingProperty.cpp DataManagement/mitkWeakPointerProperty.cpp DataManagement/mitkIPropertyRelations.cpp DataManagement/mitkPropertyRelations.cpp Interactions/mitkAction.cpp Interactions/mitkBindDispatcherInteractor.cpp Interactions/mitkCrosshairPositionEvent.cpp Interactions/mitkDataInteractor.cpp Interactions/mitkDispatcher.cpp Interactions/mitkDisplayActionEventBroadcast.cpp Interactions/mitkDisplayActionEventFunctions.cpp Interactions/mitkDisplayActionEventHandler.cpp Interactions/mitkDisplayActionEventHandlerDesynchronized.cpp Interactions/mitkDisplayActionEventHandlerStd.cpp Interactions/mitkDisplayActionEventHandlerSynchronized.cpp Interactions/mitkDisplayCoordinateOperation.cpp Interactions/mitkDisplayInteractor.cpp Interactions/mitkEventConfig.cpp Interactions/mitkEventFactory.cpp Interactions/mitkEventRecorder.cpp Interactions/mitkEventStateMachine.cpp Interactions/mitkInteractionEventConst.cpp Interactions/mitkInteractionEvent.cpp Interactions/mitkInteractionEventHandler.cpp Interactions/mitkInteractionEventObserver.cpp Interactions/mitkInteractionKeyEvent.cpp Interactions/mitkInteractionPositionEvent.cpp Interactions/mitkInteractionSchemeSwitcher.cpp Interactions/mitkInternalEvent.cpp Interactions/mitkMouseDoubleClickEvent.cpp Interactions/mitkMouseModeSwitcher.cpp Interactions/mitkMouseMoveEvent.cpp Interactions/mitkMousePressEvent.cpp Interactions/mitkMouseReleaseEvent.cpp Interactions/mitkMouseWheelEvent.cpp Interactions/mitkPointSetDataInteractor.cpp Interactions/mitkSinglePointDataInteractor.cpp Interactions/mitkStateMachineAction.cpp Interactions/mitkStateMachineCondition.cpp Interactions/mitkStateMachineContainer.cpp Interactions/mitkStateMachineState.cpp Interactions/mitkStateMachineTransition.cpp Interactions/mitkVtkEventAdapter.cpp Interactions/mitkVtkInteractorStyle.cxx Interactions/mitkXML2EventParser.cpp IO/mitkAbstractFileIO.cpp IO/mitkAbstractFileReader.cpp IO/mitkAbstractFileWriter.cpp IO/mitkCustomMimeType.cpp IO/mitkFileReader.cpp IO/mitkFileReaderRegistry.cpp IO/mitkFileReaderSelector.cpp IO/mitkFileReaderWriterBase.cpp IO/mitkFileWriter.cpp IO/mitkFileWriterRegistry.cpp IO/mitkFileWriterSelector.cpp IO/mitkGeometry3DToXML.cpp IO/mitkIFileIO.cpp IO/mitkIFileReader.cpp IO/mitkIFileWriter.cpp IO/mitkGeometryDataReaderService.cpp IO/mitkGeometryDataWriterService.cpp IO/mitkImageGenerator.cpp IO/mitkImageVtkLegacyIO.cpp IO/mitkImageVtkXmlIO.cpp IO/mitkIMimeTypeProvider.cpp IO/mitkIOConstants.cpp IO/mitkIOMimeTypes.cpp IO/mitkIOUtil.cpp IO/mitkItkImageIO.cpp IO/mitkItkLoggingAdapter.cpp IO/mitkLegacyFileReaderService.cpp IO/mitkLegacyFileWriterService.cpp IO/mitkLocaleSwitch.cpp IO/mitkLog.cpp IO/mitkMimeType.cpp IO/mitkMimeTypeProvider.cpp IO/mitkOperation.cpp IO/mitkPixelType.cpp IO/mitkPointSetReaderService.cpp IO/mitkPointSetWriterService.cpp IO/mitkProportionalTimeGeometryToXML.cpp IO/mitkRawImageFileReader.cpp IO/mitkStandardFileLocations.cpp IO/mitkSurfaceStlIO.cpp IO/mitkSurfaceVtkIO.cpp IO/mitkSurfaceVtkLegacyIO.cpp IO/mitkSurfaceVtkXmlIO.cpp IO/mitkVtkLoggingAdapter.cpp IO/mitkPreferenceListReaderOptionsFunctor.cpp Rendering/mitkAbstractAnnotationRenderer.cpp Rendering/mitkAnnotationUtils.cpp Rendering/mitkBaseRenderer.cpp #Rendering/mitkGLMapper.cpp Moved to deprecated LegacyGL Module Rendering/mitkGradientBackground.cpp Rendering/mitkImageVtkMapper2D.cpp Rendering/mitkMapper.cpp Rendering/mitkAnnotation.cpp Rendering/mitkPlaneGeometryDataMapper2D.cpp Rendering/mitkPlaneGeometryDataVtkMapper3D.cpp Rendering/mitkPointSetVtkMapper2D.cpp Rendering/mitkPointSetVtkMapper3D.cpp Rendering/mitkRenderWindowBase.cpp Rendering/mitkRenderWindow.cpp Rendering/mitkRenderWindowFrame.cpp #Rendering/mitkSurfaceGLMapper2D.cpp Moved to deprecated LegacyGL Module Rendering/mitkSurfaceVtkMapper2D.cpp Rendering/mitkSurfaceVtkMapper3D.cpp Rendering/mitkVtkEventProvider.cpp Rendering/mitkVtkMapper.cpp Rendering/mitkVtkPropRenderer.cpp Rendering/mitkVtkWidgetRendering.cpp Rendering/vtkMitkLevelWindowFilter.cpp Rendering/vtkMitkRectangleProp.cpp Rendering/vtkMitkRenderProp.cpp Rendering/vtkMitkThickSlicesFilter.cpp Rendering/vtkNeverTranslucentTexture.cpp ) set(RESOURCE_FILES Interactions/globalConfig.xml Interactions/DisplayInteraction.xml Interactions/DisplayConfig.xml Interactions/DisplayConfigPACS.xml Interactions/DisplayConfigPACSPan.xml Interactions/DisplayConfigPACSScroll.xml Interactions/DisplayConfigPACSZoom.xml Interactions/DisplayConfigPACSLevelWindow.xml Interactions/DisplayConfigMITK.xml Interactions/DisplayConfigMITKNoCrosshair.xml Interactions/DisplayConfigMITKRotation.xml Interactions/DisplayConfigMITKRotationUnCoupled.xml Interactions/DisplayConfigMITKSwivel.xml Interactions/DisplayConfigMITKLimited.xml Interactions/PointSet.xml Interactions/Legacy/StateMachine.xml Interactions/Legacy/DisplayConfigMITKTools.xml Interactions/PointSetConfig.xml mitkLevelWindowPresets.xml mitkAnatomicalStructureColorPresets.xml ) diff --git a/Modules/ModelFit/include/mitkDynamicImageGenerator.h b/Modules/Core/include/mitkDynamicImageGenerationFilter.h similarity index 54% rename from Modules/ModelFit/include/mitkDynamicImageGenerator.h rename to Modules/Core/include/mitkDynamicImageGenerationFilter.h index 77f49e254d..0acfb95dea 100644 --- a/Modules/ModelFit/include/mitkDynamicImageGenerator.h +++ b/Modules/Core/include/mitkDynamicImageGenerationFilter.h @@ -1,52 +1,61 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef DYNAMICIMAGEGENERATOR_H #define DYNAMICIMAGEGENERATOR_H #include "mitkImageToImageFilter.h" -#include "MitkModelFitExports.h" +#include "MitkCoreExports.h" namespace mitk { - /** Filter that takes n inputs and fuse it to a dynamic image (with n time points).*/ - class MITKMODELFIT_EXPORT DynamicImageGenerationFilter : public ImageToImageFilter + /** Filter that takes n mitk images as inputs and fuse them to a dynamic image (with n time points). + Preconditions of this filter are, that all input images have the same pixel type and geometry. + It no time bounds are defined the dynamic image will start at 0 ms and each time step has a duration + of 1 ms.*/ + class MITKCORE_EXPORT DynamicImageGenerationFilter : public ImageToImageFilter { public: mitkClassMacro(DynamicImageGenerationFilter, ImageToImageFilter); itkFactorylessNewMacro(DynamicImageGenerationFilter); itkCloneMacro(Self); typedef std::vector TimeBoundsVectorType; - itkGetConstMacro(TimeBounds, TimeBoundsVectorType); - void SetTimeBounds(const TimeBoundsVectorType &bounds); + itkGetConstMacro(FirstMinTimeBound, mitk::TimePointType); + /**Set custom min time bound for the first time step.*/ + itkSetMacro(FirstMinTimeBound, mitk::TimePointType); + + itkGetConstMacro(MaxTimeBounds, TimeBoundsVectorType); + /**Set custom max time bounds for all time steps.*/ + void SetMaxTimeBounds(const TimeBoundsVectorType &bounds); protected: DynamicImageGenerationFilter(){}; ~DynamicImageGenerationFilter() override{}; void GenerateInputRequestedRegion() override; void GenerateOutputInformation() override; void GenerateData() override; private: - TimeBoundsVectorType m_TimeBounds; + TimeBoundsVectorType m_MaxTimeBounds; + mitk::TimePointType m_FirstMinTimeBound = 0.0; }; } #endif // MODELSIGNALIMAGEGENERATOR_H diff --git a/Modules/ModelFit/src/Common/mitkDynamicImageGenerator.cpp b/Modules/Core/src/Algorithms/mitkDynamicImageGenerationFilter.cpp similarity index 51% rename from Modules/ModelFit/src/Common/mitkDynamicImageGenerator.cpp rename to Modules/Core/src/Algorithms/mitkDynamicImageGenerationFilter.cpp index eb14f56b0c..bb46c43c8b 100644 --- a/Modules/ModelFit/src/Common/mitkDynamicImageGenerator.cpp +++ b/Modules/Core/src/Algorithms/mitkDynamicImageGenerationFilter.cpp @@ -1,87 +1,120 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ -#include "mitkDynamicImageGenerator.h" +#include "mitkDynamicImageGenerationFilter.h" #include #include "mitkArbitraryTimeGeometry.h" #include "mitkImageReadAccessor.h" +#include "mitkTemporoSpatialStringProperty.h" -void mitk::DynamicImageGenerationFilter::SetTimeBounds(const TimeBoundsVectorType& timeBounds) +void mitk::DynamicImageGenerationFilter::SetMaxTimeBounds(const TimeBoundsVectorType& timeBounds) { - m_TimeBounds = timeBounds; + m_MaxTimeBounds = timeBounds; this->Modified(); } void mitk::DynamicImageGenerationFilter::GenerateInputRequestedRegion() { Superclass::GenerateInputRequestedRegion(); - mitk::Image* input = this->GetInput(); - - input->SetRequestedRegionToLargestPossibleRegion(); + for (DataObjectPointerArraySizeType pos = 0; pos < this->GetNumberOfInputs(); pos++) + { + this->GetInput(pos)->SetRequestedRegionToLargestPossibleRegion(); + } } void mitk::DynamicImageGenerationFilter::GenerateOutputInformation() { mitk::Image::ConstPointer input = this->GetInput(); mitk::Image::Pointer output = this->GetOutput(); - auto timeBounds = m_TimeBounds; + auto timeBounds = m_MaxTimeBounds; if (timeBounds.empty()) { - timeBounds.resize(this->GetNumberOfInputs() + 1); - std::iota(timeBounds.begin(), timeBounds.end(), 0.0); + timeBounds.resize(this->GetNumberOfInputs()); + std::iota(timeBounds.begin(), timeBounds.end(), 1.0); } - else if(timeBounds.size() != this->GetNumberOfInputs() + 1) + else if(timeBounds.size() != this->GetNumberOfInputs()) { - mitkThrow() << "User defined time bounds does not match the number if inputs (" << this->GetNumberOfInputs() << "). Size of timebounds is " << timeBounds.size() << ", but it should be " << this->GetNumberOfInputs() + 1 << "."; + mitkThrow() << "User defined max time bounds do not match the number if inputs (" << this->GetNumberOfInputs() << "). Size of max timebounds is " << timeBounds.size() << ", but it should be " << this->GetNumberOfInputs() << "."; } + timeBounds.insert(timeBounds.begin(), m_FirstMinTimeBound); + auto timeGeo = mitk::ArbitraryTimeGeometry::New(); timeGeo->ReserveSpaceForGeometries(this->GetNumberOfInputs()); for (DataObjectPointerArraySizeType pos = 0; pos < this->GetNumberOfInputs(); pos++) { timeGeo->AppendNewTimeStepClone(this->GetInput(pos)->GetGeometry(), timeBounds[pos], timeBounds[pos + 1]); } - output->Initialize(input->GetPixelType(), *timeGeo); - output->SetPropertyList(input->GetPropertyList()->Clone()); + + auto newPropList = input->GetPropertyList()->Clone(); + for (DataObjectPointerArraySizeType pos = 1; pos < this->GetNumberOfInputs(); pos++) + { + const auto otherList = this->GetInput(pos)->GetPropertyList(); + for (const auto& key : otherList->GetPropertyKeys()) + { + auto prop = newPropList->GetProperty(key); + if (prop == nullptr) + { + newPropList->SetProperty(key, otherList->GetProperty(key)->Clone()); + } + else + { + auto tempoSpatialProp = dynamic_cast(prop); + auto oTempoSpatialProp = dynamic_cast(otherList->GetProperty(key)); + if (prop != nullptr && oTempoSpatialProp != nullptr) + { + auto availabelSlices = oTempoSpatialProp->GetAvailableSlices(0); + + for (const auto& sliceID : availabelSlices) + { + tempoSpatialProp->SetValue(pos, sliceID, oTempoSpatialProp->GetValueBySlice(sliceID)); + } + } + //other prop types can be ignored, we only use the values of the first frame. + } + } + } + + output->SetPropertyList(newPropList); } void mitk::DynamicImageGenerationFilter::GenerateData() { mitk::Image::Pointer output = this->GetOutput(); mitk::Image::ConstPointer refInput = this->GetInput(); for (DataObjectPointerArraySizeType pos = 0; pos < this->GetNumberOfInputs(); pos++) { if (!Equal(*(refInput->GetGeometry()), *(this->GetInput(pos)->GetGeometry()), mitk::eps, false)) { mitkThrow() << "Cannot fuse images. At least image #" << pos << " has another geometry than the first image."; } if (refInput->GetPixelType() != this->GetInput(pos)->GetPixelType()) { mitkThrow() << "Cannot fuse images. At least image #" << pos << " has another pixeltype than the first image."; } } for (DataObjectPointerArraySizeType pos = 0; pos < this->GetNumberOfInputs(); pos++) { mitk::ImageReadAccessor accessor(this->GetInput(pos)); output->SetVolume(accessor.GetData(), pos); } } diff --git a/Modules/ModelFit/cmdapps/Fuse3Dto4DImageMiniApp.cpp b/Modules/ModelFit/cmdapps/Fuse3Dto4DImageMiniApp.cpp index b479520b36..8de94a704f 100644 --- a/Modules/ModelFit/cmdapps/Fuse3Dto4DImageMiniApp.cpp +++ b/Modules/ModelFit/cmdapps/Fuse3Dto4DImageMiniApp.cpp @@ -1,171 +1,172 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ // std includes #include #include // itk includes #include "itksys/SystemTools.hxx" // CTK includes #include "mitkCommandLineParser.h" // MITK includes #include #include -#include +#include mitkCommandLineParser::StringContainerType inFilenames; std::string outFileName; std::vector images; std::vector timebounds; void setupParser(mitkCommandLineParser& parser) { // set general information about your MiniApp parser.setCategory("Dynamic Data Analysis Tools"); parser.setTitle("Fuse 3D to 4D Image"); parser.setDescription("MiniApp that allows to fuse several 3D images (with same geometry) into a 3D+t (4D) image that can be processed as dynamic data."); parser.setContributor("DKFZ MIC"); //! [create parser] //! [add arguments] // how should arguments be prefixed parser.setArgumentPrefix("--", "-"); // add each argument, unless specified otherwise each argument is optional // see mitkCommandLineParser::addArgument for more information parser.beginGroup("Required I/O parameters"); parser.addArgument( "inputs", "i", mitkCommandLineParser::StringList, "Input files", "Pathes to the input images that should be fused", us::Any(), false, false, false, mitkCommandLineParser::Input); parser.addArgument("output", "o", mitkCommandLineParser::File, "Output file path", "Path to the fused 3D+t image.", us::Any(), false, false, false, mitkCommandLineParser::Output); parser.endGroup(); parser.beginGroup("Optional parameters"); parser.addArgument( "time", "t", mitkCommandLineParser::StringList, "Time bounds", "Defines the time geometry of the resulting dynamic image in [ms]. The first number is the start time point of the first time step. All other numbers are the max bound of a time step. So the structure is [minBound0 maxBound1 [maxBound2 [... maxBoundN]]]; e.g. \"2 3.5 10\" encodes a time geometry with two time steps and that starts at 2 ms and the second time step starts at 3.5 ms and ends at 10 ms. If not set e propertional time geometry with 1 ms duration will be generated!", us::Any(), true, false, false, mitkCommandLineParser::Input); parser.addArgument("help", "h", mitkCommandLineParser::Bool, "Help:", "Show this help text"); parser.endGroup(); //! [add arguments] } bool configureApplicationSettings(std::map parsedArgs) { if (parsedArgs.size() == 0) return false; inFilenames = us::any_cast(parsedArgs["inputs"]); outFileName = us::any_cast(parsedArgs["output"]); if (parsedArgs.count("time")) { auto timeBoundsStr = us::any_cast(parsedArgs["time"]); for (const auto& timeBoundStr : timeBoundsStr) { std::istringstream stream; stream.imbue(std::locale("C")); stream.str(timeBoundStr); mitk::TimePointType time = 0 ; stream >> time; timebounds.emplace_back(time); } } return true; } int main(int argc, char* argv[]) { mitkCommandLineParser parser; setupParser(parser); mitk::PreferenceListReaderOptionsFunctor readerFilterFunctor = mitk::PreferenceListReaderOptionsFunctor({ "MITK DICOM Reader v2 (classic config)" }, { "MITK DICOM Reader" }); const std::map& parsedArgs = parser.parseArguments(argc, argv); if (!configureApplicationSettings(parsedArgs)) { return EXIT_FAILURE; }; // Show a help message if (parsedArgs.count("help") || parsedArgs.count("h")) { std::cout << parser.helpText(); return EXIT_SUCCESS; } if (timebounds.empty()) { timebounds.resize(inFilenames.size()+1); std::iota(timebounds.begin(), timebounds.end(), 0.0); } - else if (inFilenames.size() != timebounds.size() + 1) + else if (inFilenames.size() + 1 != timebounds.size()) { std::cerr << "Cannot fuse images. Explicitly specified time bounds do not match. Use --help for more information on how to specify time bounds correctly."; return EXIT_FAILURE; }; //! [do processing] try { std::cout << "Load images:" << std::endl; auto filter = mitk::DynamicImageGenerationFilter::New(); unsigned int step = 0; for (auto path : inFilenames) { std::cout << "Time step #"<(path, &readerFilterFunctor); images.push_back(image); filter->SetInput(step, image); ++step; } - filter->SetTimeBounds(timebounds); + filter->SetFirstMinTimeBound(timebounds[0]); + filter->SetMaxTimeBounds({ timebounds.begin() + 1, timebounds.end() }); std::cout << "Fuse the images ..." << std::endl; filter->Update(); auto output = filter->GetOutput(); std::cout << "Save output image: " << outFileName << std::endl; mitk::IOUtil::Save(output, outFileName); std::cout << "Processing finished." << std::endl; return EXIT_SUCCESS; } catch (const itk::ExceptionObject& e) { MITK_ERROR << e.what(); return EXIT_FAILURE; } catch (const std::exception& e) { MITK_ERROR << e.what(); return EXIT_FAILURE; } catch (...) { MITK_ERROR << "Unexpected error encountered."; return EXIT_FAILURE; } } diff --git a/Modules/ModelFit/files.cmake b/Modules/ModelFit/files.cmake index 89d64451c4..40d7ada4fc 100644 --- a/Modules/ModelFit/files.cmake +++ b/Modules/ModelFit/files.cmake @@ -1,77 +1,76 @@ file(GLOB_RECURSE H_FILES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/include/*") set(CPP_FILES Common/mitkExtractTimeGrid.cpp Common/mitkTimeGridHelper.cpp Common/mitkMaskedDynamicImageStatisticsGenerator.cpp Common/mitkModelFitConstants.cpp Common/mitkModelFitParameter.cpp Common/mitkModelFitCmdAppsHelper.cpp Common/mitkParameterFitImageGeneratorBase.cpp Common/mitkPixelBasedParameterFitImageGenerator.cpp Common/mitkROIBasedParameterFitImageGenerator.cpp Common/mitkModelFitInfo.cpp Common/mitkModelFitStaticParameterMap.cpp Common/mitkModelGenerator.cpp Common/mitkModelFitUIDHelper.cpp Common/mitkModelFitResultHelper.cpp Common/mitkScalarListLookupTable.cpp Common/mitkScalarListLookupTableProperty.cpp Common/mitkScalarListLookupTablePropertySerializer.cpp Common/mitkIModelFitProvider.cpp Common/mitkModelFitParameterValueExtraction.cpp Common/mitkBinaryImageToLabelSetImageFilter.cpp Common/mitkFormulaParser.cpp Common/mitkFresnel.cpp Common/mitkModelFitPlotDataHelper.cpp Common/mitkModelSignalImageGenerator.cpp - Common/mitkDynamicImageGenerator.cpp Functors/mitkSimpleFunctorBase.cpp Functors/mitkSimpleFunctorPolicy.cpp Functors/mitkChiSquareFitCostFunction.cpp Functors/mitkReducedChiSquareFitCostFunction.cpp Functors/mitkConstraintCheckerBase.cpp Functors/mitkSimpleBarrierConstraintChecker.cpp Functors/mitkSquaredDifferencesFitCostFunction.cpp Functors/mitkSumOfSquaredDifferencesFitCostFunction.cpp Functors/mitkMVConstrainedCostFunctionDecorator.cpp Functors/mitkMVModelFitCostFunction.cpp Functors/mitkNormalizedSumOfSquaredDifferencesFitCostFunction.cpp Functors/mitkSVModelFitCostFunction.cpp Functors/mitkModelFitFunctorBase.cpp Functors/mitkLevenbergMarquardtModelFitFunctor.cpp Functors/mitkDummyModelFitFunctor.cpp Functors/mitkModelFitInfoSignalGenerationFunctor.cpp Functors/mitkIndexedValueFunctorPolicy.cpp Functors/mitkModelDataGenerationFunctor.cpp Models/mitkModelBase.cpp Models/mitkModelFactoryBase.cpp Models/mitkModelParameterizerBase.cpp Models/mitkLinearModel.cpp Models/mitkLinearModelFactory.cpp Models/mitkInitialParameterizationDelegateBase.cpp Models/mitkImageBasedParameterizationDelegate.cpp Models/mitkGenericParamModel.cpp Models/mitkGenericParamModelFactory.cpp Models/mitkGenericParamModelParameterizer.cpp Models/mitkValueBasedParameterizationDelegate.cpp Models/mitkT2DecayModel.cpp Models/mitkT2DecayModelFactory.cpp Models/mitkT2DecayModelParameterizer.cpp TestingHelper/mitkTestModel.cpp TestingHelper/mitkTestModelFactory.cpp ) set(TPP_FILES include/itkMultiOutputNaryFunctorImageFilter.tpp include/itkMaskedStatisticsImageFilter.hxx include/itkMaskedNaryStatisticsImageFilter.hxx include/mitkModelFitProviderBase.tpp ) set(HXX_FILES ) set(MOC_H_FILES )