]> Creatis software - clitk.git/commitdiff
new crop like (allow to enlarge image)
authordsarrut <dsarrut>
Wed, 15 Dec 2010 08:49:14 +0000 (08:49 +0000)
committerdsarrut <dsarrut>
Wed, 15 Dec 2010 08:49:14 +0000 (08:49 +0000)
itk/clitkCropLikeImageFilter.h
itk/clitkCropLikeImageFilter.txx

index 4ceadc1698e068959b986b3f7b0b6f8efc5d8c8f..d288dc4034d792ef34e554fd370c36a2ce6d536a 100644 (file)
@@ -30,9 +30,7 @@ namespace clitk {
   //--------------------------------------------------------------------
   
   template <class ImageType>
-  class ITK_EXPORT CropLikeImageFilter: 
-    public itk::ImageToImageFilter<ImageType, ImageType> {
-
+  class ITK_EXPORT CropLikeImageFilter: public itk::ImageToImageFilter<ImageType, ImageType> {
   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<ImageType::ImageDimension> * like);
     void SetCropLikeImage(const itk::ImageBase<ImageType::ImageDimension> * 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<ImageDimension> * m_LikeImage;
+    //typename ImageType::Pointer m_LikeImage;
     std::vector<bool> 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
index 90190c61b83eaae08c92fe02a2e1a2b08fbc8790..8b90fe30e704a1b1b61454608b01c477ceda89d6 100644 (file)
@@ -23,8 +23,7 @@
 #include "clitkCommon.h"
 
 // itk
-#include "itkRegionOfInterestImageFilter.h"
-
+#include "itkPasteImageFilter.h"
 
 //--------------------------------------------------------------------
 template <class ImageType>
@@ -33,6 +32,7 @@ CropLikeImageFilter():itk::ImageToImageFilter<ImageType, ImageType>() {
   this->SetNumberOfRequiredInputs(1);
   m_LikeImage = NULL;
   m_LikeFilenameIsGiven = false;
+  this->SetBackgroundValue(0);
   m_CropAlongThisDimension.resize(ImageType::ImageDimension);
   for(uint i=0; i<ImageType::ImageDimension; i++)
     m_CropAlongThisDimension[i] = true;
@@ -81,41 +81,44 @@ SetCropLikeImage(const itk::ImageBase<ImageType::ImageDimension> * like, int axe
 template <class ImageType>
 void 
 clitk::CropLikeImageFilter<ImageType>::
-SetInput(const ImageType * image) {
-  // Process object is not const-correct so the const casting is required.
-  this->SetNthInput(0, const_cast<ImageType *>( image ));
+GenerateInputRequestedRegion() {
+  // Needed because output region can be larger than input
+  ImagePointer input = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(0));
+  input->SetRequestedRegion(input->GetLargestPossibleRegion());
 }
 //--------------------------------------------------------------------
-  
+
 
 //--------------------------------------------------------------------
 template <class ImageType>
 void 
 clitk::CropLikeImageFilter<ImageType>::
 GenerateOutputInformation() {    
+  DD("GenerateOutputInformation");
   // Get input pointers
   ImageConstPointer input = dynamic_cast<const ImageType*>(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; i<ImageType::ImageDimension; i++) {
-        likeSize[i] = header->GetIORegion().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; i<ImageType::ImageDimension; i++) {
-    double ol;
-    if (m_CropAlongThisDimension[i]) {
-      size[i] = likeSize[i];
-      ol = likeOrigin[i];
-    }
-    else {
-      size[i] = input->GetLargestPossibleRegion().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; i<ImageType::ImageDimension; i++) {
+    if (m_StartPointInSource[i] < m_StartPointInDest[i]) {
+      m_StartSourceIndex[i] = startDestInSource[i];
+    }
+    else {
+      m_StartDestIndex[i] = startSourceInDest[i];
+    }
+  }
+  m_Region.SetIndex(m_StartSourceIndex);
+
+  // Stop index
+  m_StopSourceIndex = input->GetLargestPossibleRegion().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<ImageType::ImageDimension; i++) {
+    if (m_StopPointInSource[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<ImageType::ImageDimension; i++)
+    s[i] = m_StopSourceIndex[i]-m_StartSourceIndex[i];
+  m_Region.SetSize(s);
 }
 //--------------------------------------------------------------------
    
@@ -162,16 +209,24 @@ clitk::CropLikeImageFilter<ImageType>::
 GenerateData() {
   // Get input pointers
   ImageConstPointer input = dynamic_cast<const ImageType*>(itk::ProcessObject::GetInput(0));
+
+  // Get output pointer, fill with Background
+  ImagePointer output = this->GetOutput(0);
+  output->Allocate();
+  output->FillBuffer(GetBackgroundValue());
   
-  typedef itk::RegionOfInterestImageFilter<ImageType, ImageType> 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<ImageType,ImageType> 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());
 }
 //--------------------------------------------------------------------