From 709d3deddba827afcff948a7ebfe8d4908e72f8f Mon Sep 17 00:00:00 2001 From: dsarrut Date: Wed, 15 Dec 2010 08:49:14 +0000 Subject: [PATCH] new crop like (allow to enlarge image) --- itk/clitkCropLikeImageFilter.h | 27 +++++-- itk/clitkCropLikeImageFilter.txx | 127 ++++++++++++++++++++++--------- 2 files changed, 112 insertions(+), 42 deletions(-) diff --git a/itk/clitkCropLikeImageFilter.h b/itk/clitkCropLikeImageFilter.h index 4ceadc1..d288dc4 100644 --- a/itk/clitkCropLikeImageFilter.h +++ b/itk/clitkCropLikeImageFilter.h @@ -30,9 +30,7 @@ namespace clitk { //-------------------------------------------------------------------- template - class ITK_EXPORT CropLikeImageFilter: - public itk::ImageToImageFilter { - + class ITK_EXPORT CropLikeImageFilter: public itk::ImageToImageFilter { public: /** Standard class typedefs. */ typedef CropLikeImageFilter Self; @@ -52,32 +50,49 @@ namespace clitk { typedef typename ImageType::PixelType PixelType; typedef typename ImageType::RegionType RegionType; typedef typename ImageType::PointType PointType; + typedef typename ImageType::IndexType IndexType; + typedef typename ImageType::SizeType SizeType; - /** Input image to crop */ - void SetInput(const ImageType * image); - /** Image filename for Crop Like */ void SetCropLikeFilename(std::string f); void SetCropLikeImage(const itk::ImageBase * like); void SetCropLikeImage(const itk::ImageBase * like, int axe); + // Set Background if 'like' is greater than input + itkSetMacro(BackgroundValue, PixelType); + itkGetConstMacro(BackgroundValue, PixelType); + /** ImageDimension constants */ itkStaticConstMacro(ImageDimension, unsigned int, ImageType::ImageDimension); + // void Update() { GenerateOutputInformation(); GenerateData(); } + protected: CropLikeImageFilter(); virtual ~CropLikeImageFilter() {} virtual void GenerateOutputInformation(); virtual void GenerateData(); + virtual void GenerateInputRequestedRegion(); + PixelType m_BackgroundValue; + RegionType m_OutputRegion; RegionType m_Region; std::string m_LikeFilename; bool m_LikeFilenameIsGiven; PointType m_Origin; const itk::ImageBase * m_LikeImage; + //typename ImageType::Pointer m_LikeImage; std::vector m_CropAlongThisDimension; + PointType m_StartPoint; // start point in physical world + IndexType m_StartSourceIndex; // start index in "source" image + IndexType m_StartDestIndex; // start index in "destination" image + + PointType m_StopPoint; // stop point in physical world + IndexType m_StopSourceIndex; // stop index in "source" image + IndexType m_StopDestIndex; // stop index in "destination" image + private: CropLikeImageFilter(const Self&); //purposely not implemented void operator=(const Self&); //purposely not implemented diff --git a/itk/clitkCropLikeImageFilter.txx b/itk/clitkCropLikeImageFilter.txx index 90190c6..8b90fe3 100644 --- a/itk/clitkCropLikeImageFilter.txx +++ b/itk/clitkCropLikeImageFilter.txx @@ -23,8 +23,7 @@ #include "clitkCommon.h" // itk -#include "itkRegionOfInterestImageFilter.h" - +#include "itkPasteImageFilter.h" //-------------------------------------------------------------------- template @@ -33,6 +32,7 @@ CropLikeImageFilter():itk::ImageToImageFilter() { this->SetNumberOfRequiredInputs(1); m_LikeImage = NULL; m_LikeFilenameIsGiven = false; + this->SetBackgroundValue(0); m_CropAlongThisDimension.resize(ImageType::ImageDimension); for(uint i=0; i * like, int axe template void clitk::CropLikeImageFilter:: -SetInput(const ImageType * image) { - // Process object is not const-correct so the const casting is required. - this->SetNthInput(0, const_cast( image )); +GenerateInputRequestedRegion() { + // Needed because output region can be larger than input + ImagePointer input = dynamic_cast(itk::ProcessObject::GetInput(0)); + input->SetRequestedRegion(input->GetLargestPossibleRegion()); } //-------------------------------------------------------------------- - + //-------------------------------------------------------------------- template void clitk::CropLikeImageFilter:: GenerateOutputInformation() { + DD("GenerateOutputInformation"); // Get input pointers ImageConstPointer input = dynamic_cast(itk::ProcessObject::GetInput(0)); // Get output pointer ImagePointer output = this->GetOutput(0); - + // Get input info typename ImageType::SizeType likeSize; typename ImageType::IndexType likeStart; typename ImageType::PointType likeOrigin; typename ImageType::SpacingType likeSpacing; - if (m_LikeImage) { + if (m_LikeImage) { likeSize = m_LikeImage->GetLargestPossibleRegion().GetSize(); likeStart = m_LikeImage->GetLargestPossibleRegion().GetIndex(); likeOrigin = m_LikeImage->GetOrigin(); likeSpacing = m_LikeImage->GetSpacing(); } else { + // Only load the header (allows to use 'like' with any image type) if (m_LikeFilenameIsGiven) { itk::ImageIOBase::Pointer header = readImageHeader(m_LikeFilename); for(unsigned int i=0; iGetIORegion().GetSize()[i]; //GetDimensions(i); - likeStart[i] = header->GetIORegion().GetIndex()[i]; + likeSize[i] = header->GetDimensions(i); + likeStart[i] = 0;//header->GetIORegion().GetIndex()[i]; likeOrigin[i] = header->GetOrigin(i); likeSpacing[i] = header->GetSpacing(i); } @@ -125,33 +128,77 @@ GenerateOutputInformation() { } } - // Compute region - typename ImageType::SizeType size; - typename ImageType::IndexType start; + // Check spacing for(unsigned int i=0; iGetLargestPossibleRegion().GetSize()[i]; - ol = input->GetOrigin()[i]; - } - double oi = input->GetOrigin()[i]; - start[i] = lrint((ol-oi)/input->GetSpacing()[i]); - m_Origin[i] = likeOrigin[i]; if (likeSpacing[i] != input->GetSpacing()[i]) { clitkExceptionMacro("Images must have the same spacing, but input's spacing(" << i <<") is " << input->GetSpacing()[i] << " while like's spacing(" << i << ") is " << likeSpacing[i] << "."); } } + // Define output region + m_OutputRegion.SetIndex(likeStart); + m_OutputRegion.SetSize(likeSize); + output->SetRegions(m_OutputRegion); + output->SetRequestedRegion(m_OutputRegion); + output->SetBufferedRegion(m_OutputRegion); + output->SetSpacing(likeSpacing); + output->SetOrigin(likeOrigin); + + // get startpoint source/dest + // for each dim + // if source < dest -> start from dest, compute in source + // if source > dest -> start from source, compute in dest + m_StartDestIndex = output->GetLargestPossibleRegion().GetIndex(); + m_StartSourceIndex = input->GetLargestPossibleRegion().GetIndex(); + PointType m_StartPointInSource; + PointType m_StartPointInDest; + m_StartSourceIndex = input->GetLargestPossibleRegion().GetIndex(); + input->TransformIndexToPhysicalPoint(m_StartSourceIndex, m_StartPointInSource); + m_StartDestIndex = output->GetLargestPossibleRegion().GetIndex(); + output->TransformIndexToPhysicalPoint(m_StartDestIndex, m_StartPointInDest); + IndexType startDestInSource; + IndexType startSourceInDest; + input->TransformPhysicalPointToIndex(m_StartPointInDest, startDestInSource); + output->TransformPhysicalPointToIndex(m_StartPointInSource, startSourceInDest); + for(int i=0; iGetLargestPossibleRegion().GetIndex()+ + input->GetLargestPossibleRegion().GetSize(); + m_StopDestIndex = output->GetLargestPossibleRegion().GetIndex()+ + output->GetLargestPossibleRegion().GetSize(); + PointType m_StopPointInSource; + PointType m_StopPointInDest; + input->TransformIndexToPhysicalPoint(m_StopSourceIndex, m_StopPointInSource); + output->TransformIndexToPhysicalPoint(m_StopDestIndex, m_StopPointInDest); + IndexType stopDestInSource; + IndexType stopSourceInDest; + input->TransformPhysicalPointToIndex(m_StopPointInDest, stopDestInSource); + output->TransformPhysicalPointToIndex(m_StopPointInSource, stopSourceInDest); + + for(int i=0; i m_StopPointInDest[i]) { + m_StopSourceIndex[i] = stopDestInSource[i]; + } + else { + m_StopDestIndex[i] = stopSourceInDest[i]; + } + } - m_Region.SetSize(size); - m_Region.SetIndex(start); - output->SetRegions(m_Region); - output->SetSpacing(input->GetSpacing()); + // Set size to the region we want to paste + SizeType s; + for(int i=0; i:: GenerateData() { // Get input pointers ImageConstPointer input = dynamic_cast(itk::ProcessObject::GetInput(0)); + + // Get output pointer, fill with Background + ImagePointer output = this->GetOutput(0); + output->Allocate(); + output->FillBuffer(GetBackgroundValue()); - typedef itk::RegionOfInterestImageFilter CropFilterType; - typename CropFilterType::Pointer cropFilter = CropFilterType::New(); - cropFilter->SetInput(input); - cropFilter->SetReleaseDataFlag(this->GetReleaseDataFlag()); - cropFilter->SetRegionOfInterest(m_Region); - cropFilter->Update(); + // Paste image inside + typedef itk::PasteImageFilter PasteFilterType; + typename PasteFilterType::Pointer pasteFilter = PasteFilterType::New(); + pasteFilter->SetSourceImage(input); + pasteFilter->SetDestinationImage(output); + pasteFilter->SetDestinationIndex(m_StartDestIndex); + pasteFilter->SetSourceRegion(m_Region); + pasteFilter->Update(); // Get (graft) output (SetNthOutput does not fit here because of Origin). - this->GraftOutput(cropFilter->GetOutput()); + // this->GraftOutput(cropFilter->GetOutput()); + this->GraftOutput(pasteFilter->GetOutput()); } //-------------------------------------------------------------------- -- 2.47.1