[Insight-users] Streaming RegionOfInterest Shrink

Florian Pierron F.Pierron at exeter.ac.uk
Fri May 16 05:39:40 EDT 2008


Hi Luis,

Sorry to bother you again :-) but just to finish with what I was doing: 
I am using the following pipeline to crop and resample really really big 
images on import as mentioned before:

MetaImageIO (with  UseStreamedReadingOn) -> RegionOfInterestImageFilter 
-> ShrinkImageFilter

Everything was streaming fine (only a small portion of the image was 
loaded into memory) except after adding the ShrinkImageFilter. I can 
understand that this filter needs the whole input to compute its output 
as there is no easy way to tell the upstream filters that the requested 
region is in fact a list of small unconnected regions (am I correct or 
is there some ways to specify that? Maybe there is because some filters 
support streaming...). Anyway, my idea to get around this was to plug in 
the SreamingFilter at the end of the ShrinkImageFilter to request 
smaller regions. So the pipeline is as follow:

MetaImageIO (with  UseStreamedReadingOn) -> RegionOfInterestImageFilter 
-> ShrinkImageFilter -> StreamingFilter

Unfortunately the result was similar: the ShrinkImageFilter requests the 
whole input! After having a quick look at the code of the 
ShrinkImageFilter, I came across this line:


******************************
ShrinkImageFilter<TInputImage,TOutputImage>
::EnlargeOutputRequestedRegion(DataObject *output)
{
  // call the superclass' implementation of this method
  Superclass::EnlargeOutputRequestedRegion(output);
 
  output->SetRequestedRegionToLargestPossibleRegion();   --> Why setting 
the requested region to largest possible region??
}
******************************

So commenting this line worked fine and the ShrinkImageFilter is now 
requesting only a small portion of the input.

<Remark>
To optimize computation time and specially memory footprint I have added 
the following lines to ShrinkImageFilter::GenerateInputRequestedRegion()

******************************
if (outputRequestedRegionSize[i] == 1)
  {
  inputRequestedRegionSize[i] = 1;       
  }
else
  {
      inputRequestedRegionSize[i]
         = outputRequestedRegionSize[i] * (size_t)m_ShrinkFactors[i];
  }
******************************

Is there a nicer way to do it? We are requesting much more data that we 
actually need to specially when the ShrinkFactor is quite big (in 
hundreds in my case). I saw that there are functions to split regions 
and so on, so is there a way to define a list of requestedRegion or 
something with a similar outcomes (stream at the pixel level)
<EndRemark>


But even after these modifications, the pipeline was still not working 
and the whole image was loaded (trying to be loaded) into memory :-(. I 
then had a look at the RegionOfInterestImageFilter and I realized that 
this filter doesn't take into account the RequestedRegion!? So I 
modified the following function as below:


******************************
template <class TInputImage, class TOutputImage>
void
RegionOfInterestImageFilter<TInputImage,TOutputImage>
::GenerateInputRequestedRegion()
{
  // call the superclass' implementation of this method
  Superclass::GenerateInputRequestedRegion();
 
  // get pointer to the input
  typename Superclass::InputImagePointer  inputPtr =
    const_cast< TInputImage * >( this->GetInput() );
  OutputImagePointer outputPtr = this->GetOutput();

  if ( !inputPtr || !outputPtr )
    {
    return;
    }

  // If the requested region is smaller / contained in m_RegionOfInterest
  // then the inputRequestedRegion is cropped to match the requested region
  // Otherwise (can this happen?) the inputRequestedRegion is
  // NOT cropped and is equal to the m_RegionOfInterest
  typename TInputImage::RegionType inputRequestedRegion( 
m_RegionOfInterest );
  inputRequestedRegion.Crop( outputPtr->GetRequestedRegion() );
  inputRequestedRegion.Crop( inputPtr->GetLargestPossibleRegion() ); // 
is this really needed?

  inputPtr->SetRequestedRegion( inputRequestedRegion );   
}
******************************


And in the same way than the ShrinkFilter, I have commented the 
output->SetRequestedRegionToLargestPossibleRegion() in  
RegionOfInterestImageFilter::EnlargeOutputRequestedRegion ().

I don't understand why the 
output->SetRequestedRegionToLargestPossibleRegion() is there for the 
ShrinkFilter and RegionOfInterestImageFilter. So if someone with 
experience in developing ITK code can have a quick look and check that I 
didn't break anything by removing this line, it would be really great!

Find attached the patch for the ShrinkFilter and 
RegionOfInterestImageFilter. Let me know if you want me to enter this as 
a feature request in the bug tracker

Regards,
Florian

-------- Original Message --------
Subject: 	Re: [Insight-users] MetaImage: absolute path in 
ElementDataFile not working
Date: 	Tue, 13 May 2008 23:57:39 +0100
From: 	Florian Pierron <f.pierron at exeter.ac.uk>
To: 	Luis Ibanez <luis.ibanez at kitware.com>
CC: 	insight-users at itk.org
References: 	<48283AE6.3020203 at exeter.ac.uk> 
<48284B0D.3010401 at kitware.com> <48296C66.8090809 at exeter.ac.uk> 
<4829C215.9090808 at kitware.com> <482A0114.10802 at exeter.ac.uk> 
<482A0D9A.6060802 at kitware.com>



Hi Luis,

Sorry for the misunderstanding: yes I was speaking about the 
ElementDataFile field inside the .mhd / header file.

The thing is that I don't necessary have the write access on the folder 
containing the raw image. That's the reason why I need an absolute path...

To give you the full picture of the problem, I need to read really 
really really really big data (300 GB) and resample / crop them on 
import. I tried to use the UseStreamedReadingOn on the RawImageIO and 
UseStreamingOn on the ImageFileReader followed by a 
RegionOfInterestImageFilter and ShrinkImageFilter. But I couldn't get 
the streaming work on the RawImageIO. After reading some posts on the 
mailing list, it seems that the MetaImageIO is the only streamable 
reader. So I created a temporary .mhd file and the streaming seems to 
work like a charm now :-). That is simply amazing, thanks for this good 
piece of code!

Regards,
Florian

PS: I think the patch I provided to allow absolute path in the 
ElementDataFile of an .mha file is quite useful for the reason mentioned 
above. Moreover
if the ElementDataFile field is NOT an absolute path, it will work as 
before and append the header path to the ElementDataFile. But if the 
ElementDataFile field is an absolute path, it will NOT append the header 
path. But at the end, you are the one who decides ;-)

-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: Patch_ITK-3-4_RegionOfInterestFilter_ShrinkFilter
URL: <http://www.itk.org/pipermail/insight-users/attachments/20080516/604d6a4c/attachment.asc>


More information about the Insight-users mailing list