[Insight-developers] Re: [Insight-users] One error and one is sue with itkImagePCAShapeModelEstimator

Miller, James V (Research) millerjv at crd.ge.com
Mon, 17 May 2004 17:11:43 -0400


Zachary, 

You could provide a custom GenerateInputRegion to handle the
case of the varying start indices.  But then you still have a 
mapping problem of how to set each inputs start index based 
on the start index of the output RequestedRegion. If you can find
some logical way to do this, then have it.

A user could use the ChangeInformation filter to change the 
start indices to be the same. 

Jim

-----Original Message-----
From: Zachary Pincus [mailto:zpincus at stanford.edu]
Sent: Monday, May 17, 2004 2:00 PM
To: Miller, James V (Research)
Subject: Re: [Insight-developers] Re: [Insight-users] One error and one
is sue with itkImagePCAShapeModelEstimator


Jim,

Thanks for your detailed explanation here. I will work up a patch to 
make the PCA model estimator work a little more cleanly.

A few questions, though:

> The cleanest thing to do, however, is to probably drive this off an
> output requested region. The outputs should be images so this seems
> reasonable.  The input RequestedRegions are then just copies of "an"
> output RequestedRegion. I think the default pipeline implementations
> should handle this appropriately (meaning the filter probably does not
> need a GenerateInputRequestedRegion method or an
> EnlargeOutputRequestedRegion
> method).

I think that the default pipeline mechanism basically sets the input 
requested regions to the output requested region -- is this correct? 
This seems to be a problem when the input and output requested regions 
are the same size, but with different start indices. Then, after the 
superclass's GenerateInputRequestedRegion, then the inputs have an 
inconsistency where the requested region (pasted in from the output) 
isn't actually in the buffered region...

So I think that it is necessary to do something in a custom 
GenerateInputRequestedRegion, right? Because even if the user does all 
the proper cropping, etc, the cropped regions of their images will have 
different start indices. (This is actually how I came across this 
issue.)

Or am I missing something in how the pipelining works?

Zach


On May 17, 2004, at 6:48 AM, Miller, James V (Research) wrote:

> Zachary,
>
> The RequestedRegion is what filters need to operate on. The pipeline
> (and filters) are designed so that the RequestedRegion should always
> be a subset of the BufferedRegion. Since your 
> GenerateInputRequestedRegion
> sets the RequestedRegion to the LargestPossibleRegion, it
> should be safe to use the RequestedRegion (and not the BufferedRegion
> in the CalculateInnerProducts).
>
> What your estimator needs is for the calculation of the PCA to occur
> over regions of the inputs that are the same size.  This means the
> GenerateInputRequestedRegion method needs to guarentee the inputs have
> the same RequestedRegion size.
>
> Currently, you are driving this from the "first" input.  This is a
> reasonable choice.  Another option is to scan all the inputs to find 
> the
> smallest input and make that the master. Then it becomes a question of
> how to how to change the start indices if you end up changing the size.
>
> The cleanest thing to do, however, is to probably drive this off an
> output requested region. The outputs should be images so this seems
> reasonable.  The input RequestedRegions are then just copies of "an"
> output RequestedRegion. I think the default pipeline implementations
> should handle this appropriately (meaning the filter probably does not
> need a GenerateInputRequestedRegion method or an
> EnlargeOutputRequestedRegion
> method).  The PCA decomposition will be on whatever RequestedRegion
> is asked for on output.  If someone calls UpdateLargestPossibleRegion()
> on the estimator, then the PCA decomposition will be over the entire 
> image.
>
> This will displace the complexity to the user.  Where they will use a
> series of ExtractImageFilters, RegionOfInterestImageFilters, and
> ChangeInformationFilters to get all the inputs a consistent size... If
> we do not displace the complexity to the user, then the filter needs
> to know which portions of each input to use in the PCA.  For instance,
> lets say I have a number of images, each having a small object that
> I want to model.  In medical image analysis, it is rare that the object
> of interest will appear at the same spot in each  image.  Therefore, I 
> would
>
> expect to have to align and crop a block around the object to send it 
> to the
> PCA.
> Adding this complexity to the PCA filter seems unnecessary.  The PCA 
> filter
> should probably just check the inputs are the same size.
>
>
> Jim
>
>
> -----Original Message-----
> From: Zachary Pincus [mailto:zpincus at stanford.edu]
> Sent: Sunday, May 16, 2004 7:02 AM
> To: Luis Ibanez; insight-developers at itk.org
> Subject: [Insight-developers] Re: [Insight-users] One error and one
> issue with itkImagePCAShapeModelEstimator
>
>
>> 1) It seems reasonable to allow the ImagePCAShapeModelEstimator
>>    to accept images of different origin, different StartIndex
>>    and only enforce the pixel spacing and the image size (in
>>    pixel along every dimension) to be the same among all the
>>    input images.
>>
>>    Please send us a patch...
>
> I've included a new implementation of the GenerateInputRequestedRegion
> method of itkPCAShapeModelEstimatorClass so images with regions with
> different indices, but the same size (and spacing) can work.
>
> Now, the original behavior (which I did not change) is to set all input
> requested regions to the largest possible region, and claim to use
> that. However, elsewhere in the code (CalculateInnerProducts), the
> buffered region of the inputs is what is actually used...
>
> Perhaps it would be better if this were all done with the requested
> region? If the user bothered to set them, why blow them away? Or would
> that break too much code that relies on not having to set a requested
> region?
>
> Anhyow, the diff is pretty messy since this is basically a different
> function, so I've just pasted in the new function.
>
> Also attached is a modified test case that exercises this new
> functionality, and diffs to the old test.
>
>
> Zach Pincus
>
> Department of Biochemistry and Program in Biomedical Informatics
> Stanford University School of Medicine
>
>
> New GenerateInputRequestedRegion:
>
> /**
>   * Requires all of the inputs to have a LargestPosibleRegion and
> Spacing the of
>   * same size.
>   */
> template<class TInputImage, class TOutputImage>
> void
> ImagePCAShapeModelEstimator<TInputImage,TOutputImage>
> ::GenerateInputRequestedRegion()
> {
>    Superclass::GenerateInputRequestedRegion();
>    // Calling this causes problems because it sets the input requested
> regions
>    // to various output requested regions, which might not overlap,
> since the inputs
>    // and outputs aren't very closely linked in the PCA case.
>    // If we REALLY want to call this, then some heroics are necessary 
> to
> undo
>    // the damage it does. Specifically, we will have to set all the
> inputs'
>    // requested regions back to *their* LargestPossibleRegion, and not
> that of
>    // some random output.
> 	
>    if ( this->GetInput(0) )
>      {
>
>      // Get the requested region and spacing of the first input
> 	this->GetInput(0)->SetRequestedRegionToLargestPossibleRegion();
> 	typename TInputImage::RegionType masterRequestedRegion =
> 	  this->GetInput(0)->GetRequestedRegion();
>      typename TInputImage::SpacingType masterSpacing =
>        this->GetInput(0)->GetSpacing();
>
>      // Set the requested region of the remaining input to their 
> largest
> possible
>      // regions, and make sure the sizes and spacings are proper.
>      unsigned int idx;
>      for (idx = 1; idx < this->GetNumberOfInputs(); ++idx)
>        {
>        if ( this->GetInput(idx) )
>          {
> 		
>
> this->GetInput(idx)->SetRequestedRegionToLargestPossibleRegion();
> 		
> 		typename TInputImage::RegionType requestedRegion =
>            this->GetInput(idx)->GetRequestedRegion();
>          typename TInputImage::SpacingType spacing =
> 		  this->GetInput(0)->GetSpacing();
>          if( masterRequestedRegion.GetSize() !=
> requestedRegion.GetSize() ||
> 			masterSpacing != spacing)
>            {
>            itkExceptionMacro("Size and spacing of input " << idx <<
>              " is not the same as that of input 0" );
>            }
>
>          } // if ( this->GetIntput(idx))
>        } // for idx
>      } // if( this->GetInput(0) )
>
> }
>
>
> Diffs for new and old test code
> (itkImagePCAShapeModelEstimatorTest.cxx):
> < Old
>> New
> 83c83
> <   InputImageType::IndexType index;
> ---
>>   InputImageType::IndexType index, index2;
> 85c85,87
> <   InputImageType::RegionType region;
> ---
>>   index2.Fill(4);
>>
>>   InputImageType::RegionType region, region2;
> 89a92,94
>>   region2.SetSize( inputImageSize );
>>   region2.SetIndex( index2 );
>>
> 105,106c110,111
> <   image2->SetLargestPossibleRegion( region );
> <   image2->SetBufferedRegion( region );
> ---
>>   image2->SetLargestPossibleRegion( region2 );
>>   image2->SetBufferedRegion( region2 );
>
>
> _______________________________________________
> Insight-developers mailing list
> Insight-developers at itk.org
> http://www.itk.org/mailman/listinfo/insight-developers
>