From df51e4850f784f8f2fbaead7bb82bd6897fb9fab Mon Sep 17 00:00:00 2001 From: delmon Date: Tue, 11 Jan 2011 10:40:18 +0000 Subject: [PATCH] Use MultipleBSplineDeformableTransform instead of BSplineDeformableTransform in clitkBLUTDIR, allowing the user to register different regions of an image at the same time. --- registration/clitkBLUTDIR.ggo | 2 +- registration/clitkBLUTDIRGenericFilter.cxx | 85 ++++++++++++++-------- registration/clitkBLUTDIRGenericFilter.h | 4 +- 3 files changed, 56 insertions(+), 35 deletions(-) diff --git a/registration/clitkBLUTDIR.ggo b/registration/clitkBLUTDIR.ggo index 4443da1..8be34e7 100755 --- a/registration/clitkBLUTDIR.ggo +++ b/registration/clitkBLUTDIR.ggo @@ -18,7 +18,7 @@ section "Input" option "reference" r "Input reference 3D image (float)" string yes option "target" t "Input target 2D image (float)" string yes -option "referenceMask" m "Mask to placed over the reference image" string no +option "referenceMask" m "Mask or labels to placed over the reference image" string no option "targetMask" - "Mask to placed over the target image" string no section "Output" diff --git a/registration/clitkBLUTDIRGenericFilter.cxx b/registration/clitkBLUTDIRGenericFilter.cxx index 9640282..c8c42f0 100755 --- a/registration/clitkBLUTDIRGenericFilter.cxx +++ b/registration/clitkBLUTDIRGenericFilter.cxx @@ -127,8 +127,8 @@ namespace clitk typedef typename RegistrationType::FixedImageType FixedImageType; typedef typename FixedImageType::RegionType RegionType; itkStaticConstMacro(ImageDimension, unsigned int,FixedImageType::ImageDimension); - typedef clitk::BSplineDeformableTransform TransformType; - typedef clitk::BSplineDeformableTransformInitializer InitializerType; + typedef clitk::MultipleBSplineDeformableTransform TransformType; + typedef clitk::MultipleBSplineDeformableTransformInitializer InitializerType; typedef typename InitializerType::CoefficientImageType CoefficientImageType; typedef itk::CastImageFilter CastImageFilterType; typedef typename TransformType::ParametersType ParametersType; @@ -186,14 +186,20 @@ namespace clitk registration->SetMetric(metric); // Get the current coefficient image and make a COPY - typename itk::ImageDuplicator::Pointer caster=itk::ImageDuplicator::New(); - caster->SetInputImage(m_Initializer->GetTransform()->GetCoefficientImage()); - caster->Update(); - typename CoefficientImageType::Pointer currentCoefficientImage=caster->GetOutput(); + typename itk::ImageDuplicator::Pointer caster = itk::ImageDuplicator::New(); + std::vector currentCoefficientImages = m_Initializer->GetTransform()->GetCoefficientImages(); + for (unsigned i = 0; i < currentCoefficientImages.size(); ++i) + { + caster->SetInputImage(currentCoefficientImages[i]); + caster->Update(); + currentCoefficientImages[i] = caster->GetOutput(); + } + /* // Write the intermediate result? if (m_ArgsInfo.intermediate_given>=numberOfLevels) writeImage(currentCoefficientImage, m_ArgsInfo.intermediate_arg[currentLevel-2], m_ArgsInfo.verbose_flag); + */ // Set the new transform properties m_Initializer->SetImage(registration->GetFixedImagePyramid()->GetOutput(currentLevel-1)); @@ -231,7 +237,7 @@ namespace clitk // Set the previous transform parameters to the registration // if(m_Initializer->m_Parameters!=NULL )delete m_Initializer->m_Parameters; - m_Initializer->SetInitialParameters(currentCoefficientImage,*newParameters); + m_Initializer->SetInitialParameters(currentCoefficientImages, *newParameters); registration->SetInitialTransformParametersOfNextLevel(*newParameters); } } @@ -320,43 +326,46 @@ namespace clitk // If given, we connect a mask to reference or target //============================================================================ typedef itk::ImageMaskSpatialObject< InputImageType::ImageDimension > MaskType; - typename MaskType::Pointer fixedMask=NULL; + typedef itk::Image< unsigned char, InputImageType::ImageDimension > ImageLabelType; + typename MaskType::Pointer fixedMask = NULL; + typename ImageLabelType::Pointer labels = NULL; if (m_ArgsInfo.referenceMask_given) { - fixedMask= MaskType::New(); - typedef itk::Image< unsigned char,InputImageType::ImageDimension > ImageMaskType; - typedef itk::ImageFileReader< ImageMaskType > MaskReaderType; - typename MaskReaderType::Pointer maskReader = MaskReaderType::New(); - maskReader->SetFileName(m_ArgsInfo.referenceMask_arg); + fixedMask = MaskType::New(); + labels = ImageLabelType::New(); + typedef itk::ImageFileReader< ImageLabelType > LabelReaderType; + typename LabelReaderType::Pointer labelReader = LabelReaderType::New(); + labelReader->SetFileName(m_ArgsInfo.referenceMask_arg); try { - maskReader->Update(); + labelReader->Update(); } catch( itk::ExceptionObject & err ) { - std::cerr << "ExceptionObject caught while reading mask !" << std::endl; + std::cerr << "ExceptionObject caught while reading mask or labels !" << std::endl; std::cerr << err << std::endl; return; } if (m_Verbose)std::cout <<"Reference image mask was read..." < ResamplerType; + // Resample labels + typedef itk::ResampleImageFilter ResamplerType; typename ResamplerType::Pointer resampler = ResamplerType::New(); - typedef itk::NearestNeighborInterpolateImageFunction InterpolatorType; + typedef itk::NearestNeighborInterpolateImageFunction InterpolatorType; typename InterpolatorType::Pointer interpolator = InterpolatorType::New(); resampler->SetOutputParametersFromImage(fixedImage); resampler->SetInterpolator(interpolator); - resampler->SetInput(maskReader->GetOutput()); + resampler->SetInput(labelReader->GetOutput()); resampler->Update(); + labels = resampler->GetOutput(); // Set the image to the spatialObject - fixedMask->SetImage(resampler->GetOutput()); + fixedMask->SetImage(labels); // Find the bounding box of the "inside" label - typedef itk::LabelGeometryImageFilter GeometryImageFilterType; + typedef itk::LabelGeometryImageFilter GeometryImageFilterType; typename GeometryImageFilterType::Pointer geometryImageFilter=GeometryImageFilterType::New(); - geometryImageFilter->SetInput(resampler->GetOutput()); + geometryImageFilter->SetInput(labels); geometryImageFilter->Update(); typename GeometryImageFilterType::BoundingBoxType boundingBox = geometryImageFilter->GetBoundingBox(1); @@ -484,15 +493,15 @@ namespace clitk //======================================================= // B-LUT FFD Transform //======================================================= - typedef clitk::BSplineDeformableTransform TransformType; - typename TransformType::Pointer transform= TransformType::New(); - if (fixedMask) transform->SetMask( fixedMask ); - if (rigidTransform) transform->SetBulkTransform( rigidTransform ); + typedef clitk::MultipleBSplineDeformableTransform TransformType; + typename TransformType::Pointer transform = TransformType::New(); + if (labels) transform->SetLabels(labels); + if (rigidTransform) transform->SetBulkTransform(rigidTransform); //------------------------------------------------------------------------- // The transform initializer //------------------------------------------------------------------------- - typedef clitk::BSplineDeformableTransformInitializer< TransformType,FixedImageType> InitializerType; + typedef clitk::MultipleBSplineDeformableTransformInitializer< TransformType,FixedImageType> InitializerType; typename InitializerType::Pointer initializer = InitializerType::New(); initializer->SetVerbose(m_Verbose); initializer->SetImage(fixedImagePyramid->GetOutput(0)); @@ -696,12 +705,24 @@ namespace clitk if (m_ArgsInfo.coeff_given) { typedef typename TransformType::CoefficientImageType CoefficientImageType; - typename CoefficientImageType::Pointer coefficientImage =transform->GetCoefficientImage(); + std::vector coefficientImages = transform->GetCoefficientImages(); typedef itk::ImageFileWriter CoeffWriterType; - typename CoeffWriterType::Pointer coeffWriter=CoeffWriterType::New(); - coeffWriter->SetInput(coefficientImage); - coeffWriter->SetFileName(m_ArgsInfo.coeff_arg); - coeffWriter->Update(); + typename CoeffWriterType::Pointer coeffWriter = CoeffWriterType::New(); + unsigned nLabels = transform->GetnLabels(); + + std::string fname(m_ArgsInfo.coeff_arg); + int dotpos = fname.length() - 1; + while (dotpos >= 0 && fname[dotpos] != '.') + dotpos--; + + for (unsigned i = 0; i < nLabels; ++i) + { + std::ostringstream osfname; + osfname << fname.substr(0, dotpos) << '_' << i << fname.substr(dotpos); + coeffWriter->SetInput(coefficientImages[i]); + coeffWriter->SetFileName(osfname.str()); + coeffWriter->Update(); + } } diff --git a/registration/clitkBLUTDIRGenericFilter.h b/registration/clitkBLUTDIRGenericFilter.h index 215bcd5..472ab6d 100755 --- a/registration/clitkBLUTDIRGenericFilter.h +++ b/registration/clitkBLUTDIRGenericFilter.h @@ -35,11 +35,11 @@ #include "clitkDifferenceImageFilter.h" #include "clitkTransformUtilities.h" #include "clitkLBFGSBOptimizer.h" -#include "clitkBSplineDeformableTransform.h" +#include "clitkMultipleBSplineDeformableTransform.h" #include "clitkGenericOptimizer.h" #include "clitkGenericInterpolator.h" #include "clitkGenericMetric.h" -#include "clitkBSplineDeformableTransformInitializer.h" +#include "clitkMultipleBSplineDeformableTransformInitializer.h" #include "clitkMultiResolutionPyramidRegionFilter.h" #include "clitkImageToImageGenericFilter.h" -- 2.47.1