diff --git a/Modules/Segmentation/SegmentationUtilities/MorphologicalOperations/mitkMorphologicalOperations.cpp b/Modules/Segmentation/SegmentationUtilities/MorphologicalOperations/mitkMorphologicalOperations.cpp index e630aef6cf..fd3b295c64 100644 --- a/Modules/Segmentation/SegmentationUtilities/MorphologicalOperations/mitkMorphologicalOperations.cpp +++ b/Modules/Segmentation/SegmentationUtilities/MorphologicalOperations/mitkMorphologicalOperations.cpp @@ -1,384 +1,418 @@ /*=================================================================== 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 "mitkMorphologicalOperations.h" #include #include #include #include #include #include #include #include #include #include #include void mitk::MorphologicalOperations::Closing(mitk::Image::Pointer &image, int factor, mitk::MorphologicalOperations::StructuralElementType structuralElement) { MITK_INFO << "Start Closing..."; auto timeSteps = static_cast(image->GetTimeSteps()); if (timeSteps > 1) { mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New(); timeSelector->SetInput(image); for (int t = 0; t < timeSteps; ++t) { MITK_INFO << " Processing time step " << t; timeSelector->SetTimeNr(t); timeSelector->Update(); mitk::Image::Pointer img3D = timeSelector->GetOutput(); img3D->DisconnectPipeline(); AccessByItk_3(img3D, itkClosing, img3D, factor, structuralElement); mitk::ImageReadAccessor accessor(img3D); image->SetVolume(accessor.GetData(), t); } } else { AccessByItk_3(image, itkClosing, image, factor, structuralElement); } MITK_INFO << "Finished Closing"; } void mitk::MorphologicalOperations::Erode(mitk::Image::Pointer &image, int factor, mitk::MorphologicalOperations::StructuralElementType structuralElement) { MITK_INFO << "Start Erode..."; auto timeSteps = static_cast(image->GetTimeSteps()); if (timeSteps > 1) { mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New(); timeSelector->SetInput(image); for (int t = 0; t < timeSteps; ++t) { MITK_INFO << " Processing time step " << t; timeSelector->SetTimeNr(t); timeSelector->Update(); mitk::Image::Pointer img3D = timeSelector->GetOutput(); img3D->DisconnectPipeline(); AccessByItk_3(img3D, itkErode, img3D, factor, structuralElement); mitk::ImageReadAccessor accessor(img3D); image->SetVolume(accessor.GetData(), t); } } else { AccessByItk_3(image, itkErode, image, factor, structuralElement); } MITK_INFO << "Finished Erode"; } void mitk::MorphologicalOperations::Dilate(mitk::Image::Pointer &image, int factor, mitk::MorphologicalOperations::StructuralElementType structuralElement) { MITK_INFO << "Start Dilate..."; auto timeSteps = static_cast(image->GetTimeSteps()); if (timeSteps > 1) { mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New(); timeSelector->SetInput(image); for (int t = 0; t < timeSteps; ++t) { MITK_INFO << " Processing time step " << t; timeSelector->SetTimeNr(t); timeSelector->Update(); mitk::Image::Pointer img3D = timeSelector->GetOutput(); img3D->DisconnectPipeline(); AccessByItk_3(img3D, itkDilate, img3D, factor, structuralElement); mitk::ImageReadAccessor accessor(img3D); image->SetVolume(accessor.GetData(), t); } } else { AccessByItk_3(image, itkDilate, image, factor, structuralElement); } MITK_INFO << "Finished Dilate"; } void mitk::MorphologicalOperations::Opening(mitk::Image::Pointer &image, int factor, mitk::MorphologicalOperations::StructuralElementType structuralElement) { MITK_INFO << "Start Opening..."; auto timeSteps = static_cast(image->GetTimeSteps()); if (timeSteps > 1) { mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New(); timeSelector->SetInput(image); for (int t = 0; t < timeSteps; ++t) { MITK_INFO << " Processing time step " << t; timeSelector->SetTimeNr(t); timeSelector->Update(); mitk::Image::Pointer img3D = timeSelector->GetOutput(); img3D->DisconnectPipeline(); AccessByItk_3(img3D, itkOpening, img3D, factor, structuralElement); mitk::ImageReadAccessor accessor(img3D); image->SetVolume(accessor.GetData(), t); } } else { AccessByItk_3(image, itkOpening, image, factor, structuralElement); } MITK_INFO << "Finished Opening"; } void mitk::MorphologicalOperations::FillHoles(mitk::Image::Pointer &image) { MITK_INFO << "Start FillHole..."; auto timeSteps = static_cast(image->GetTimeSteps()); if (timeSteps > 1) { mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New(); timeSelector->SetInput(image); for (int t = 0; t < timeSteps; ++t) { MITK_INFO << " Processing time step " << t; timeSelector->SetTimeNr(t); timeSelector->Update(); mitk::Image::Pointer img3D = timeSelector->GetOutput(); img3D->DisconnectPipeline(); AccessByItk_1(img3D, itkFillHoles, img3D); mitk::ImageReadAccessor accessor(img3D); image->SetVolume(accessor.GetData(), t); } } else { AccessByItk_1(image, itkFillHoles, image); } MITK_INFO << "Finished FillHole"; } template void mitk::MorphologicalOperations::itkClosing( itk::Image *sourceImage, mitk::Image::Pointer &resultImage, int factor, mitk::MorphologicalOperations::StructuralElementType structuralElementFlags) { typedef itk::Image ImageType; typedef itk::BinaryBallStructuringElement BallType; typedef itk::BinaryCrossStructuringElement CrossType; typedef typename itk::BinaryMorphologicalClosingImageFilter BallClosingFilterType; typedef typename itk::BinaryMorphologicalClosingImageFilter CrossClosingFilterType; if (structuralElementFlags & (Ball_Axial | Ball_Coronal | Ball_Sagital)) { BallType ball = CreateStructuringElement(structuralElementFlags, factor); typename BallClosingFilterType::Pointer closingFilter = BallClosingFilterType::New(); closingFilter->SetKernel(ball); closingFilter->SetInput(sourceImage); closingFilter->SetForegroundValue(1); closingFilter->UpdateLargestPossibleRegion(); mitk::CastToMitkImage(closingFilter->GetOutput(), resultImage); } else { CrossType cross = CreateStructuringElement(structuralElementFlags, factor); typename CrossClosingFilterType::Pointer closingFilter = CrossClosingFilterType::New(); closingFilter->SetKernel(cross); closingFilter->SetInput(sourceImage); closingFilter->SetForegroundValue(1); closingFilter->UpdateLargestPossibleRegion(); mitk::CastToMitkImage(closingFilter->GetOutput(), resultImage); } } template void mitk::MorphologicalOperations::itkErode( itk::Image *sourceImage, mitk::Image::Pointer &resultImage, int factor, mitk::MorphologicalOperations::StructuralElementType structuralElementFlags) { typedef itk::Image ImageType; typedef itk::BinaryBallStructuringElement BallType; typedef itk::BinaryCrossStructuringElement CrossType; typedef typename itk::BinaryErodeImageFilter BallErodeFilterType; typedef typename itk::BinaryErodeImageFilter CrossErodeFilterType; if (structuralElementFlags & (Ball_Axial | Ball_Coronal | Ball_Sagital)) { BallType ball = CreateStructuringElement(structuralElementFlags, factor); typename BallErodeFilterType::Pointer erodeFilter = BallErodeFilterType::New(); erodeFilter->SetKernel(ball); erodeFilter->SetInput(sourceImage); erodeFilter->SetErodeValue(1); erodeFilter->UpdateLargestPossibleRegion(); mitk::CastToMitkImage(erodeFilter->GetOutput(), resultImage); } else { CrossType cross = CreateStructuringElement(structuralElementFlags, factor); typename CrossErodeFilterType::Pointer erodeFilter = CrossErodeFilterType::New(); erodeFilter->SetKernel(cross); erodeFilter->SetInput(sourceImage); erodeFilter->SetErodeValue(1); erodeFilter->UpdateLargestPossibleRegion(); mitk::CastToMitkImage(erodeFilter->GetOutput(), resultImage); } } template void mitk::MorphologicalOperations::itkDilate( itk::Image *sourceImage, mitk::Image::Pointer &resultImage, int factor, mitk::MorphologicalOperations::StructuralElementType structuralElementFlags) { typedef itk::Image ImageType; typedef itk::BinaryBallStructuringElement BallType; typedef itk::BinaryCrossStructuringElement CrossType; typedef typename itk::BinaryDilateImageFilter BallDilateFilterType; typedef typename itk::BinaryDilateImageFilter CrossDilateFilterType; if (structuralElementFlags & (Ball_Axial | Ball_Coronal | Ball_Sagital)) { BallType ball = CreateStructuringElement(structuralElementFlags, factor); typename BallDilateFilterType::Pointer dilateFilter = BallDilateFilterType::New(); dilateFilter->SetKernel(ball); dilateFilter->SetInput(sourceImage); dilateFilter->SetDilateValue(1); dilateFilter->UpdateLargestPossibleRegion(); mitk::CastToMitkImage(dilateFilter->GetOutput(), resultImage); } else { CrossType cross = CreateStructuringElement(structuralElementFlags, factor); typename CrossDilateFilterType::Pointer dilateFilter = CrossDilateFilterType::New(); dilateFilter->SetKernel(cross); dilateFilter->SetInput(sourceImage); dilateFilter->SetDilateValue(1); dilateFilter->UpdateLargestPossibleRegion(); mitk::CastToMitkImage(dilateFilter->GetOutput(), resultImage); } } template void mitk::MorphologicalOperations::itkOpening( itk::Image *sourceImage, mitk::Image::Pointer &resultImage, int factor, mitk::MorphologicalOperations::StructuralElementType structuralElementFlags) { typedef itk::Image ImageType; typedef itk::BinaryBallStructuringElement BallType; typedef itk::BinaryCrossStructuringElement CrossType; typedef typename itk::BinaryMorphologicalOpeningImageFilter BallOpeningFiltertype; typedef typename itk::BinaryMorphologicalOpeningImageFilter CrossOpeningFiltertype; if (structuralElementFlags & (Ball_Axial | Ball_Coronal | Ball_Sagital)) { BallType ball = CreateStructuringElement(structuralElementFlags, factor); typename BallOpeningFiltertype::Pointer openingFilter = BallOpeningFiltertype::New(); openingFilter->SetKernel(ball); openingFilter->SetInput(sourceImage); openingFilter->SetForegroundValue(1); openingFilter->SetBackgroundValue(0); openingFilter->UpdateLargestPossibleRegion(); mitk::CastToMitkImage(openingFilter->GetOutput(), resultImage); } else { CrossType cross = CreateStructuringElement(structuralElementFlags, factor); typename CrossOpeningFiltertype::Pointer openingFilter = CrossOpeningFiltertype::New(); openingFilter->SetKernel(cross); openingFilter->SetInput(sourceImage); openingFilter->SetForegroundValue(1); openingFilter->SetBackgroundValue(0); openingFilter->UpdateLargestPossibleRegion(); mitk::CastToMitkImage(openingFilter->GetOutput(), resultImage); } } template void mitk::MorphologicalOperations::itkFillHoles(itk::Image *sourceImage, mitk::Image::Pointer &resultImage) { typedef itk::Image ImageType; typedef typename itk::BinaryFillholeImageFilter FillHoleFilterType; typename FillHoleFilterType::Pointer fillHoleFilter = FillHoleFilterType::New(); fillHoleFilter->SetInput(sourceImage); fillHoleFilter->SetForegroundValue(1); fillHoleFilter->UpdateLargestPossibleRegion(); mitk::CastToMitkImage(fillHoleFilter->GetOutput(), resultImage); } + +template +TStructuringElement mitk::MorphologicalOperations::CreateStructuringElement(StructuralElementType structuralElementFlag, int factor) +{ + TStructuringElement strElem; + typename TStructuringElement::SizeType size; + size.Fill(0); + switch (structuralElementFlag) + { + case Ball_Axial: + case Cross_Axial: + size.SetElement(0, factor); + size.SetElement(1, factor); + break; + case Ball_Coronal: + case Cross_Coronal: + size.SetElement(0, factor); + size.SetElement(2, factor); + break; + case Ball_Sagital: + case Cross_Sagital: + size.SetElement(1, factor); + size.SetElement(2, factor); + break; + case Ball: + case Cross: + size.Fill(factor); + break; + } + + strElem.SetRadius(size); + strElem.CreateStructuringElement(); + return strElem; +} \ No newline at end of file diff --git a/Modules/Segmentation/SegmentationUtilities/MorphologicalOperations/mitkMorphologicalOperations.h b/Modules/Segmentation/SegmentationUtilities/MorphologicalOperations/mitkMorphologicalOperations.h index f7ce9e997d..a615a73820 100644 --- a/Modules/Segmentation/SegmentationUtilities/MorphologicalOperations/mitkMorphologicalOperations.h +++ b/Modules/Segmentation/SegmentationUtilities/MorphologicalOperations/mitkMorphologicalOperations.h @@ -1,124 +1,93 @@ /*=================================================================== 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. ===================================================================*/ #ifndef mitkMorphologicalOperations_h #define mitkMorphologicalOperations_h #include #include namespace mitk { /** \brief Encapsulates several morphological operations that can be performed on segmentations. */ class MITKSEGMENTATION_EXPORT MorphologicalOperations { public: enum StructuralElementType { Ball = 7, Ball_Axial = 1, Ball_Sagital = 2, Ball_Coronal = 4, Cross = 56, Cross_Axial = 8, Cross_Sagital = 16, Cross_Coronal = 32 }; ///@{ /** \brief Perform morphological operation on 2D, 3D or 3D+t segmentation. */ static void Closing(mitk::Image::Pointer &image, int factor, StructuralElementType structuralElement); static void Erode(mitk::Image::Pointer &image, int factor, StructuralElementType structuralElement); static void Dilate(mitk::Image::Pointer &image, int factor, StructuralElementType structuralElement); static void Opening(mitk::Image::Pointer &image, int factor, StructuralElementType structuralElement); static void FillHoles(mitk::Image::Pointer &image); ///@} private: MorphologicalOperations(); template - static TStructuringElement CreateStructuringElement(StructuralElementType structuralElementFlag, int factor) - { - TStructuringElement strElem; - typename TStructuringElement::SizeType size; - size.Fill(0); - switch (structuralElementFlag) - { - case Ball_Axial: - case Cross_Axial: - size.SetElement(0, factor); - size.SetElement(1, factor); - break; - case Ball_Coronal: - case Cross_Coronal: - size.SetElement(0, factor); - size.SetElement(2, factor); - break; - case Ball_Sagital: - case Cross_Sagital: - size.SetElement(1, factor); - size.SetElement(2, factor); - break; - case Ball: - case Cross: - size.Fill(factor); - break; - } - - strElem.SetRadius(size); - strElem.CreateStructuringElement(); - return strElem; - } + static TStructuringElement CreateStructuringElement(StructuralElementType structuralElementFlag, int factor); ///@{ /** \brief Perform morphological operation by using corresponding ITK filter. */ template - void static itkClosing(itk::Image *sourceImage, + static void itkClosing(itk::Image *sourceImage, mitk::Image::Pointer &resultImage, int factor, StructuralElementType structuralElement); template - void static itkErode(itk::Image *sourceImage, + static void itkErode(itk::Image *sourceImage, mitk::Image::Pointer &resultImage, int factor, StructuralElementType structuralElement); template - void static itkDilate(itk::Image *sourceImage, + static void itkDilate(itk::Image *sourceImage, mitk::Image::Pointer &resultImage, int factor, StructuralElementType structuralElement); template - void static itkOpening(itk::Image *sourceImage, + static void itkOpening(itk::Image *sourceImage, mitk::Image::Pointer &resultImage, int factor, StructuralElementType structuralElement); template - void static itkFillHoles(itk::Image *sourceImage, mitk::Image::Pointer &resultImage); + static void itkFillHoles(itk::Image *sourceImage, mitk::Image::Pointer &resultImage); ///@} }; } #endif diff --git a/Wrapping/Common/mitk_swig_classes.i b/Wrapping/Common/mitk_swig_classes.i index e531e6fc84..52a12a12f9 100644 --- a/Wrapping/Common/mitk_swig_classes.i +++ b/Wrapping/Common/mitk_swig_classes.i @@ -1,126 +1,144 @@ // // Defining some Macros that make problems with SWIG as the // corresponding definitions are not included by default. // Luckely, these includes are not necessary for SWIG. // #define ITK_NOEXCEPT #define ITKCommon_EXPORT #define ITK_OVERRIDE #define MITKCORE_EXPORT #define MITKCLCORE_EXPORT #define MITKCLUTILITIES_EXPORT #define ITKCommon_EXPORT #define MITKMATCHPOINTREGISTRATION_EXPORT #define MAPDeployment_EXPORT #define MAPAlgorithms_EXPORT +#define MITKSEGMENTATION_EXPORT +#define MITKMULTILABEL_EXPORT #define ITKCommon_EXPORT #define ITK_FORWARD_EXPORT #define ITK_OVERRIDE #define ITK_NOEXCEPT %include %include %include %include %include %include #define DEPRECATED(func) func #undef ITK_DISALLOW_COPY_AND_ASSIGN #define ITK_DISALLOW_COPY_AND_ASSIGN(TypeName) %pythoncode %{ convertion_list = {} %} SWIG_ADD_MITK_CLASS(Object, itkObject.h, itk) SWIG_ADD_MITK_CLASS(DataObject, itkDataObject.h, itk) SWIG_ADD_MITK_CLASS(TimeGeometry, mitkTimeGeometry.h, mitk) SWIG_ADD_MITK_CLASS(ArbitraryTimeGeometry, mitkArbitraryTimeGeometry.h, mitk) SWIG_ADD_MITK_CLASS(ProportionalTimeGeometry, mitkProportionalTimeGeometry.h, mitk) SWIG_ADD_MITK_CLASS(BaseGeometry, mitkBaseGeometry.h, mitk) SWIG_ADD_MITK_CLASS(Geometry3D, mitkGeometry3D.h, mitk) SWIG_ADD_MITK_CLASS(SlicedGeometry3D, mitkSlicedGeometry3D.h, mitk) SWIG_ADD_MITK_CLASS(PlaneGeometry , mitkPlaneGeometry.h, mitk) SWIG_ADD_NONOBJECT_NOVECTOR_CLASS(BoundingBox, mitkBaseGeometry.h, mitk) SWIG_ADD_NONOBJECT_CLASS(TimeBounds, mitkBaseGeometry.h, mitk) SWIG_ADD_NONOBJECT_CLASS(FixedArrayType, mitkBaseGeometry.h, mitk) SWIG_ADD_NONOBJECT_CLASS(Point2D, mitkPoint.h, mitk) SWIG_ADD_NONOBJECT_CLASS(Point3D, mitkPoint.h, mitk) SWIG_ADD_NONOBJECT_CLASS(Point4D, mitkPoint.h, mitk) SWIG_ADD_NONOBJECT_CLASS(Point2I, mitkPoint.h, mitk) SWIG_ADD_NONOBJECT_CLASS(Point3I, mitkPoint.h, mitk) SWIG_ADD_NONOBJECT_CLASS(Point4I, mitkPoint.h, mitk) SWIG_ADD_NONOBJECT_CLASS(VnlVector, mitkVector.h, mitk) SWIG_ADD_NONOBJECT_CLASS(Vector2D, mitkVector.h, mitk) SWIG_ADD_NONOBJECT_CLASS(Vector3D, mitkVector.h, mitk) SWIG_ADD_NONOBJECT_CLASS(Vector4D, mitkVector.h, mitk) SWIG_ADD_MITK_CLASS(BaseData, mitkBaseData.h, mitk) SWIG_ADD_MITK_CLASS(SlicedData, mitkSlicedData.h, mitk) SWIG_ADD_MITK_CLASS(Image, mitkImage.h, mitk) +SWIG_ADD_MITK_CLASS(LabelSetImage, mitkLabelSetImage.h, mitk) SWIG_ADD_MITK_CLASS(PointSet, mitkPointSet.h, mitk) +%{ +using mitk::Message; +%} // // Phenotyping Related Classes // SWIG_ADD_MITK_CLASS(AbstractGlobalImageFeature, mitkAbstractGlobalImageFeature.h, mitk) SWIG_ADD_MITK_CLASS(GIFImageDescriptionFeatures, mitkGIFImageDescriptionFeatures.h, mitk) SWIG_ADD_MITK_CLASS(GIFFirstOrderStatistics, mitkGIFFirstOrderStatistics.h, mitk) SWIG_ADD_MITK_CLASS(GIFFirstOrderHistogramStatistics, mitkGIFFirstOrderHistogramStatistics.h, mitk) SWIG_ADD_MITK_CLASS(GIFVolumetricStatistics, mitkGIFVolumetricStatistics.h, mitk) SWIG_ADD_MITK_CLASS(GIFVolumetricDensityStatistics, mitkGIFVolumetricDensityStatistics.h, mitk) SWIG_ADD_MITK_CLASS(GIFCooccurenceMatrix2, mitkGIFCooccurenceMatrix2.h, mitk) SWIG_ADD_MITK_CLASS(GIFNeighbouringGreyLevelDependenceFeature, mitkGIFNeighbouringGreyLevelDependenceFeatures.h, mitk) SWIG_ADD_MITK_CLASS(GIFGreyLevelRunLength, mitkGIFGreyLevelRunLength.h, mitk) SWIG_ADD_MITK_CLASS(GIFGreyLevelSizeZone, mitkGIFGreyLevelSizeZone.h, mitk) SWIG_ADD_MITK_CLASS(GIFGreyLevelDistanceZone, mitkGIFGreyLevelDistanceZone.h, mitk) SWIG_ADD_MITK_CLASS(GIFLocalIntensity, mitkGIFLocalIntensity.h, mitk) SWIG_ADD_MITK_CLASS(GIFIntensityVolumeHistogramFeatures, mitkGIFIntensityVolumeHistogramFeatures.h, mitk) SWIG_ADD_MITK_CLASS(GIFNeighbourhoodGreyToneDifferenceFeatures, mitkGIFNeighbourhoodGreyToneDifferenceFeatures.h, mitk) SWIG_ADD_MITK_CLASS(GIFCurvatureStatistic, mitkGIFCurvatureStatistic.h, mitk) +// +// Conversion and Segmentation based Classes +// +SWIG_ADD_MITK_CLASS(ContourModelSetToImageFilter, mitkContourModelSetToImageFilter.h, mitk) +SWIG_ADD_NONOBJECT_NOVECTOR_CLASS(BooleanOperation, mitkBooleanOperation.h, mitk) +SWIG_ADD_NONOBJECT_NOVECTOR_CLASS(MorphologicalOperations, mitkMorphologicalOperations.h, mitk) +%{ + #include + typedef itk::DataObject::DataObjectIdentifierType DataObjectIdentifierType; + typedef itk::ProcessObject::DataObjectPointerArraySizeType DataObjectPointerArraySizeType; +%} + // // MatchPoint Related Classes // MITKSWIG_ADD_CLASS(MITKAlgorithmHelper, mitkAlgorithmHelper.h, mitk) MITKSWIG_ADD_CLASS(RegistrationType, mitkImageMappingHelper.h, mitk::ImageMappingHelper) MITKSWIG_ADD_CLASS(MITKRegistrationType, mitkImageMappingHelper.h, mitk::ImageMappingHelper) %ignore map::deployment::DLLHandle::New(const LibraryHandleType& libraryHandle, const map::algorithm::UID* pUID, const core::String& libraryFile, const core::String& profileStr); %ignore map::deployment::DLLHandle::New(const map::algorithm::UID* pUID,const core::String& libraryFilePath,const core::String& profileStr); %ignore map::deployment::DLLInfo::New(const map::algorithm::UID* pUID,const core::String& libraryFilePath,const core::String& profileStr); %ignore map::deployment::DLLHandle::New; SWIG_ADD_MITK_CLASS_VECTORFREE(DLLDirectoryBrowser, mapDeploymentDLLDirectoryBrowser.h, ::map::deployment) SWIG_ADD_MITK_CLASS_VECTORFREE(DLLInfo, mapDeploymentDLLInfo.h, ::map::deployment) SWIG_ADD_MITK_CLASS_VECTORFREE(DLLHandle, mapDeploymentDLLHandle.h, ::map::deployment) SWIG_ADD_MITK_CLASS_VECTORFREE(UID, mapUID.h, ::map::algorithm) %{ namespace algorithm { typedef map::algorithm::UID UID; } namespace core { typedef map::core::String String; } %} MITKSWIG_ADD_HEADERFILE(mapDeploymentDLLAccess.h) SWIG_ADD_MITK_CLASS_VECTORFREE(DLLHandle, mapDeploymentDLLHandle.h, ::map::deployment) // SWIG_ADD_MITK_CLASS(FastSymmetricForcesDemonsMultiResDefaultRegistrationAlgorithm, mitkFastSymmetricForcesDemonsMultiResDefaultRegistrationAlgorithm.h, mitk) // SWIG_ADD_MITK_CLASS(LevelSetMotionMultiResDefaultRegistrationAlgorithm, mitkLevelSetMotionMultiResDefaultRegistrationAlgorithm.h, mitk) // SWIG_ADD_MITK_CLASS(MultiModalAffineDefaultRegistrationAlgorithm, mitkMultiModalAffineDefaultRegistrationAlgorithm.h, mitk) // SWIG_ADD_MITK_CLASS(MultiModalRigidDefaultRegistrationAlgorithm, mitkMultiModalRigidDefaultRegistrationAlgorithm.h, mitk) // SWIG_ADD_MITK_CLASS(MultiModalTransDefaultRegistrationAlgorithm, mitkMultiModalTransDefaultRegistrationAlgorithm.h, mitk) // SWIG_ADD_MITK_CLASS(RigidClosedFormPointsDefaultRegistrationAlgorithm, mitkRigidClosedFormPointsDefaultRegistrationAlgorithm.h, mitk) // SWIG_ADD_MITK_CLASS(RigidICPDefaultRegistrationAlgorithm, mitkRigidICPDefaultRegistrationAlgorithm.h, mitk) \ No newline at end of file diff --git a/Wrapping/Common/mitk_swig_macros.i b/Wrapping/Common/mitk_swig_macros.i index 9938aebc28..51288dd2cb 100644 --- a/Wrapping/Common/mitk_swig_macros.i +++ b/Wrapping/Common/mitk_swig_macros.i @@ -1,219 +1,228 @@ // // This file contains macros for swig. // // // MITKSWIG_ADD_HEADERFILE includes a header-file into SWIG // %define MITKSWIG_ADD_HEADERFILE( classinclude ) // Include the include file in the generated cpp file %{ #include < ## classinclude ## > %} // Include the given header, where the class definition is found %include < ## classinclude ## > %enddef // // MITKSWIG_ADD_CLASS is a helper macro in order to do // all important stuff in order to wrap an existing // class // %define MITKSWIG_ADD_CLASS(classname, classinclude, nspace) MITKSWIG_ADD_HEADERFILE( classinclude ) // Using class name in order to remove ambigiouties %{ typedef nspace ## :: ## classname classname ## ; using nspace ## :: ## classname ; %} using nspace ##:: ## classname ; // Typedef is necessary to overcome ambigiouties resulting in the fact that SWIG // ignores namespaces. This can lead to some problems with templates. typedef nspace ## :: ## classname classname ## ; %enddef // // MITKSWIG_AUTOMATED_CASTING is a helper macro in order to // provide a convinience interface for up/downcasting of // classes // %define MITKSWIG_AUTOMATED_CASTING(classname, classinclude, nspace) // Define a conversion method to convert from and to types %template(ConvertTo ## classname) ConvertTo< nspace ##:: ## classname ## >; // This extend is necessary to have the automatic cast methods available %extend itk::SmartPointer< nspace ## :: ## classname ## ::Self> { %pythoncode %{ def _GetListOfValidItems(self): - return [str(k) for k in self.GetClassHierarchy() if k in convertion_list.keys() ] + return [str(k).replace("class itk::","") for k in self.GetClassHierarchy() if str(k).replace("class itk::","") in convertion_list.keys() ] %} %pythoncode %{ def __getattr__(self, item): if type(item)==str: if (len(item) > 9) and ('ConvertTo' in item): searchString=item[9:] if searchString in self._GetListOfValidItems(): def func_t(): return convertion_list[searchString](self) return func_t %} %pythoncode %{ def __dir__(self): return super().__dir__() + ['ConvertTo'+k for k in self._GetListOfValidItems()] %} } %extend std::vector< nspace ## :: ## classname *>::value_type { %pythoncode %{ def _GetListOfValidItems(self): - return [str(k) for k in self.GetClassHierarchy() if k in convertion_list.keys() ] + return [str(k).replace("class itk::","") for k in self.GetClassHierarchy() if str(k).replace("class itk::","") in convertion_list.keys() ] %} %pythoncode %{ def __getattr__(self, item): if type(item)==str: if (len(item) > 9) and ('ConvertTo' in item): searchString=item[9:] if searchString in self._GetListOfValidItems(): def func_t(): return convertion_list[searchString](self) return func_t %} %pythoncode %{ def __dir__(self): return super().__dir__() + ['ConvertTo'+k for k in self._GetListOfValidItems()] %} } %pythoncode %{ convertion_list['classname'] = ConvertTo ## classname %} %enddef // // MITKSWIG_SMARTPOINTERVECTOR : Wrapper for Vectors of Smartpointer-Classes // %define MITKSWIG_SMARTPOINTERVECTOR(classname, classinclude, nspace) // Initianziation of std. vectors containing pointers to these classes. This allows to use // vectors of these types as target language arrays. %template(Vector ## classname ## Pointer) std::vector< nspace ## :: ## classname ## ::Pointer >; %template(Vector ## classname) std::vector< nspace ## :: ## classname ## ::Self *>; %enddef // // MITKSWIG_POINTERVECTOR : Wrapper for Vectors of Classes // %define MITKSWIG_POINTERVECTOR(classname, classinclude, nspace) // Initianziation of std. vectors containing pointers to these classes. This allows to use // vectors of these types as target language arrays. %template(Vector ## classname ## Pointer) std::vector< nspace ## :: ## classname * >; %template(Vector ## classname) std::vector< nspace ## :: ## classname >; %enddef // -// MITKSWIG_MITKSMARTPOINTER : Wrapper for Vectors of Smartpointer-Classes +// MITKSWIG_MITKSMARTPOINTER_INITIALIZATION : Wrapper for Vectors of Smartpointer-Classes // -%define MITKSWIG_MITKSMARTPOINTER(classname, classinclude, nspace) +%define MITKSWIG_MITKSMARTPOINTER_INITIALIZATION(classname, classinclude, nspace) // Declaring that this class is a smart-pointer class, in order to handle // online upcasting where necessary (for example python) %feature("smartptr", noblock=1) nspace ##:: ## classname { itk::SmartPointer } +%enddef +// +// MITKSWIG_MITKSMARTPOINTER_TEMPLATE : Wrapper for Vectors of Smartpointer-Classes +// +%define MITKSWIG_MITKSMARTPOINTER_TEMPLATE(classname, classinclude, nspace) // Defining the Smartpointer, allows easy access in target language %template(classname ## Pointer) itk::SmartPointer; %enddef // // SWIG_ADD_MITK_CLASS is a helper macro in order to do // all important stuff before an mitk::Class is included. // Requires the name of the class as it is in c++ as classname // and the include file, in which the class is defined. // It is assumed that the class is somehow inherited from // mitk::BaseData, and supports smartpointers. // %define SWIG_ADD_MITK_CLASS_VECTORFREE(classname, classinclude, nspace) + MITKSWIG_MITKSMARTPOINTER_INITIALIZATION(classname, classinclude, nspace) MITKSWIG_ADD_CLASS( classname, classinclude, nspace ) class nspace ## :: ## classname ## ; class nspace ## :: ## classname ## ::Pointer; - MITKSWIG_MITKSMARTPOINTER(classname, classinclude, nspace) + MITKSWIG_MITKSMARTPOINTER_TEMPLATE(classname, classinclude, nspace) MITKSWIG_AUTOMATED_CASTING(classname, classinclude, nspace) %enddef // // SWIG_ADD_MITK_CLASS is a helper macro in order to do // all important stuff before an mitk::Class is included. // Requires the name of the class as it is in c++ as classname // and the include file, in which the class is defined. // It is assumed that the class is somehow inherited from // mitk::BaseData, and supports smartpointers. // %define SWIG_ADD_MITK_CLASS(classname, classinclude, nspace) + MITKSWIG_MITKSMARTPOINTER_INITIALIZATION(classname, classinclude, nspace) MITKSWIG_ADD_CLASS( classname, classinclude, nspace ) - class nspace ## :: ## classname ## ; - class nspace ## :: ## classname ## ::Pointer; - MITKSWIG_MITKSMARTPOINTER(classname, classinclude, nspace) + class nspace ## :: ## classname ## ; + //class nspace ## :: ## classname ## ::Pointer; + // It is important to first define the Vectors and + // then define the Smartpointer. Otherwise a SWIG-bug ... MITKSWIG_SMARTPOINTERVECTOR(classname, classinclude, nspace) + MITKSWIG_MITKSMARTPOINTER_TEMPLATE(classname, classinclude, nspace) + MITKSWIG_AUTOMATED_CASTING(classname, classinclude, nspace) %enddef // // SWIG_ADD_NONOBJECT_CLASS is a helper macro in order to do // all important stuff before an mitk::Class is included. // Requires the name of the class as it is in c++ as classname // and the include file, in which the class is defined. // It is assumed that the class is somehow inherited from // mitk::BaseData, and supports smartpointers. // %define SWIG_ADD_NONOBJECT_CLASS(classname, classinclude, nspace) - MITKSWIG_ADD_CLASS( classname, classinclude, nspace ) // Typedef is necessary to overcome ambigiouties resulting in the fact that SWIG // ignores namespaces. This can lead to some problems with templates. typedef nspace ## :: ## classname classname ## ; class nspace ## :: ## classname ## ; MITKSWIG_POINTERVECTOR(classname, classinclude, nspace) %enddef // // SWIG_ADD_NONOBJECT_CLASS is a helper macro in order to do // all important stuff before an mitk::Class is included. // Requires the name of the class as it is in c++ as classname // and the include file, in which the class is defined. // It is assumed that the class is somehow inherited from // mitk::BaseData, and supports smartpointers. // %define SWIG_ADD_NONOBJECT_NOVECTOR_CLASS(classname, classinclude, nspace) MITKSWIG_ADD_CLASS( classname, classinclude, nspace ) // Typedef is necessary to overcome ambigiouties resulting in the fact that SWIG // ignores namespaces. This can lead to some problems with templates. typedef nspace ## :: ## classname classname ## ; // Initianziation of std. vectors containing pointers to these classes. This allows to use // vectors of these types as target language arrays. %template(Vector ## classname ## Pointer) std::vector< nspace ## :: ## classname * >; %enddef diff --git a/Wrapping/Python/CMakeLists.txt b/Wrapping/Python/CMakeLists.txt index 086b30dd8b..cb9327dc76 100644 --- a/Wrapping/Python/CMakeLists.txt +++ b/Wrapping/Python/CMakeLists.txt @@ -1,77 +1,77 @@ # Version 2.8.1 is the minium requirement for this script. # this is lower than the general minimum requirement. #cmake_minimum_required ( VERSION 2.8.1 FATAL_ERROR ) include(mitkTargetLinkLibrariesWithDynamicLookup) project( MITK_Python ) set(CMAKE_SHARED_LINKER_FLAGS "" CACHE INTERNAL "" FORCE) set(CMAKE_MODULE_LINKER_FLAGS "" CACHE INTERNAL "" FORCE) mitk_check_dynamic_lookup(MODULE SHARED MITK_UNDEFINED_SYMBOLS_ALLOWED ) # # Find the necessary libraries etc.. # if ( MITK_UNDEFINED_SYMBOLS_ALLOWED ) set( _QUIET_LIBRARY "QUIET" ) else() set( _QUIET_LIBRARY "REQUIRED" ) endif() find_package ( PythonInterp REQUIRED ) find_package ( PythonLibs ${_QUIET_LIBRARY} ) include_directories ( ${CMAKE_CURRENT_SOURCE_DIR} ) # # Options # option ( MITK_PYTHON_THREADS "Enable threaded python usage by unlocking the GIL." ON ) mark_as_advanced( MITK_PYTHON_THREADS ) option ( MITK_PYTHON_EGG "Add building of python eggs to the dist target." OFF ) mark_as_advanced( MITK_PYTHON_EGG ) option ( MITK_PYTHON_WHEEL "Add building of python wheels to the dist target." ON ) mark_as_advanced( MITK_PYTHON_WHEEL ) # Prepare the SWIG-File, i.e. especially add necessary include folders -mitkSwigPrepareFiles(pyMITK MITK.i "MitkCore;MitkCLCore;MitkCLUtilities;ITKCommon;MitkMatchPointRegistration") +mitkSwigPrepareFiles(pyMITK MITK.i "MitkCore;MitkCLCore;MitkCLUtilities;ITKCommon;MitkMatchPointRegistration;MitkSegmentation;MitkMultilabel;MitkDICOMReader;MitkDICOMReaderServices;MitkDicomRT") # Add additional SWIG Parameters # These parameters depend on the target language set(CMAKE_SWIG_FLAGS ${CMAKE_SWIG_GLOBAL_FLAGS} -features autodoc=1 -keyword ) if( MITK_PYTHON_THREADS ) set(CMAKE_SWIG_FLAGS ${CMAKE_SWIG_FLAGS} -threads) endif() set(CMAKE_SWIG_OUTDIR ${CMAKE_CURRENT_BINARY_DIR}) # Create the actual SWIG project swig_add_module(pyMITK python MITK.i ) -mitkSwigAddLibraryDependencies(pyMITK "MitkCore;MitkCLCore;MitkCLUtilities;ITKCommon;MitkMatchPointRegistration") +mitkSwigAddLibraryDependencies(pyMITK "MitkCore;MitkCLCore;MitkCLUtilities;ITKCommon;MitkMatchPointRegistration;MitkSegmentation;MitkMultilabel;MitkDICOMReader;MitkDICOMReaderServices;MitkDicomRT") mitk_target_link_libraries_with_dynamic_lookup(${SWIG_MODULE_pyMITK_REAL_NAME} ${PYTHON_LIBRARIES}) if(DEFINED SKBUILD) message(WARNING "SKBuild exists") # Currently this installation install(FILES ${CMAKE_CURRENT_BINARY_DIR}/pyMITK.py ${CMAKE_CURRENT_SOURCE_DIR}/Packaging/__init__.py # ${MITK_DOC_FILES} DESTINATION pyMITK COMPONENT Runtime ) install(TARGETS ${SWIG_MODULE_pyMITK_REAL_NAME} RUNTIME DESTINATION pyMITK LIBRARY DESTINATION pyMITK COMPONENT Runtime ) else() message(WARNING "SKBuild missing") include(LegacyPackaging.cmake) endif() diff --git a/Wrapping/Python/MITK.i b/Wrapping/Python/MITK.i index cbdd3c857c..f7a188f7ed 100644 --- a/Wrapping/Python/MITK.i +++ b/Wrapping/Python/MITK.i @@ -1,171 +1,167 @@ %module pyMITK %include %{ #include "mitkNumpyArrayConversion.cxx" %} // Numpy array conversion support %native(_GetMemoryViewFromImage) PyObject *mitk_GetMemoryViewFromImage( PyObject *self, PyObject *args ); %native(_SetImageFromArray) PyObject *mitk_SetImageFromArray( PyObject *(self), PyObject *args ); %pythoncode %{ HAVE_NUMPY = True try: import numpy except ImportError: HAVE_NUMPY = False def _get_numpy_dtype( mitkImage ): """Given a MITK image, returns the numpy.dtype which describes the data""" if not HAVE_NUMPY: raise ImportError('Numpy not available.') # this is a mapping from MITK's pixel id to numpy's dtype _mitk_np = {ComponentTypeUInt8:numpy.uint8, ComponentTypeUInt16:numpy.uint16, ComponentTypeUInt32:numpy.uint32, ComponentTypeInt8:numpy.int8, ComponentTypeInt16:numpy.int16, ComponentTypeInt32:numpy.int32, ComponentTypeFloat:numpy.float32, ComponentTypeDouble:numpy.float64, } return _mitk_np[ mitkImage.GetPixelType().GetComponentType() ] def _get_mitk_pixelid(numpy_array_type): """Returns a MITK PixelID given a numpy array.""" if not HAVE_NUMPY: raise ImportError('Numpy not available.') # This is a Mapping from numpy array types to sitks pixel types. _np_mitk = {numpy.character:ComponentTypeUInt8, numpy.uint8:ComponentTypeUInt8, numpy.uint16:ComponentTypeUInt16, numpy.uint32:ComponentTypeUInt32, numpy.int8:ComponentTypeInt8, numpy.int16:ComponentTypeInt16, numpy.int32:ComponentTypeInt32, numpy.float32:ComponentTypeFloat, numpy.float64:ComponentTypeDouble, } try: return _np_mitk[numpy_array_type.dtype] except KeyError: for key in _np_mitk: if numpy.issubdtype(numpy_array_type.dtype, key): return _np_mitk[key] raise TypeError('dtype: {0} is not supported.'.format(numpy_array_type.dtype)) def _get_sitk_vector_pixelid(numpy_array_type): """Returns a MITK vecotr PixelID given a numpy array.""" if not HAVE_NUMPY: raise ImportError('Numpy not available.') # This is a Mapping from numpy array types to sitks pixel types. _np_sitk = {numpy.character:sitkVectorUInt8, numpy.uint8:sitkVectorUInt8, numpy.uint16:sitkVectorUInt16, numpy.uint32:sitkVectorUInt32, numpy.uint64:sitkVectorUInt64, numpy.int8:sitkVectorInt8, numpy.int16:sitkVectorInt16, numpy.int32:sitkVectorInt32, numpy.int64:sitkVectorInt64, numpy.float32:sitkVectorFloat32, numpy.float64:sitkVectorFloat64, } try: return _np_sitk[numpy_array_type.dtype] except KeyError: for key in _np_sitk: if numpy.issubdtype(numpy_array_type.dtype, key): return _np_sitk[key] raise TypeError('dtype: {0} is not supported.'.format(numpy_array_type.dtype)) # MITK <-> Numpy Array conversion support. #http://www.nickdarnell.com/swig-casting-revisited/ def GetArrayViewFromImage(image): """Get a NumPy ndarray view of a MITK Image. Returns a Numpy ndarray object as a "view" of the MITK's Image buffer. This reduces pixel buffer copies, but requires that the MITK image object is kept around while the buffer is being used. """ if not HAVE_NUMPY: raise ImportError('NumPy not available.') dtype = _get_numpy_dtype( image ) shape = GetImageSize(image); if image.GetPixelType().GetNumberOfComponents() > 1: shape = ( image.GetPixelType().GetNumberOfComponents(), ) + shape imageMemoryView = _pyMITK._GetMemoryViewFromImage(image) arrayView = numpy.asarray(imageMemoryView).view(dtype = dtype) arrayView.shape = shape[::-1] return arrayView def GetArrayFromImage(image): """Get a NumPy ndarray from a MITK Image. This is a deep copy of the image buffer and is completely safe and without potential side effects. """ # TODO: If the image is already not unique then a second copy may be made before the numpy copy is done. arrayView = GetArrayViewFromImage(image) # perform deep copy of the image buffer return numpy.array(arrayView, copy=True) def GetImageFromArray( arr, isVector=False): """Get a MITK Image from a numpy array. If isVector is True, then a 3D array will be treated as a 2D vector image, otherwise it will be treated as a 3D image""" if not HAVE_NUMPY: raise ImportError('Numpy not available.') z = numpy.asarray( arr ) assert z.ndim in ( 2, 3, 4 ), \ "Only arrays of 2, 3 or 4 dimensions are supported." id = _get_mitk_pixelid( z ) #img = Image_New() if ( z.ndim == 3 and isVector ) or (z.ndim == 4): pixelType=MakePixelTypeFromTypeID(id, z.shape[-1]) newShape=VectorUInt32(z.shape[-2::-1]) img = MakeImage(pixelType, newShape) #img.Initialize(pixelType, z.ndim - 1, z.shape[-2::-1]) elif z.ndim in ( 2, 3 ): pixelType=MakePixelTypeFromTypeID(id, 1) newShape=VectorUInt32(z.shape[::-1]) img = MakeImage(pixelType, newShape) #img.Initialize(pixelType, z.ndim, z.shape[::-1]) _pyMITK._SetImageFromArray( z.tostring(), img ) return img -#convertion_list = {'Image':ConvertToImage, -# 'SlicedData':ConvertToSlicedData, -# 'BaseData':ConvertToBaseData} - %}