[Insight-users] CastImageFilter BUG???

Luis Ibanez luis.ibanez at kitware.com
Sun Apr 18 12:16:02 EDT 2010


Hi Lars,

It looks like this is a case in which:


1) The documentation incorrectly recommended a misuse of the class.
2) The misuse was later detected as a buggy behavior
3) The buggy behavior has been identified and fixed.


The "feature" of reducing 3D to 2D dimensions only
works in this filter due to a happy coincidence resulting
from the way in which the image iterators are implemented.

Note for example, that the extracted slice can only be the
one corresponding to the slowest changing index.


Instead of using the CastImageFilter, you should use the

                          ExtractImageFilter

which is explicitly designed for dealing with dimensionality
reduction between the input image and the output image.

For example, extracting one 2D slice from a 3D image,
as illustrated in the Example:

    Insight/Examples/IO/ImageReadExtractWrite.cxx

Note that the ExtractImageFilter will do both the pixel
casting and the dimensionality reduction.

In the meantime we have fixed the documentation
of the itkCastImageFilter.
http://public.kitware.com/cgi-bin/viewcvs.cgi/Code/BasicFilters/itkCastImageFilter.h?root=Insight&view=log

with the following diff:
http://public.kitware.com/cgi-bin/viewcvs.cgi/Code/BasicFilters/itkCastImageFilter.h?root=Insight&r1=1.16&r2=1.17



      Regards,


           Luis


----------------------------------------------------------------------------------------------------
On Sun, Apr 18, 2010 at 10:52 AM, Lars Friedrich Lars <
lars-friedrich at gmx.net> wrote:

> Hello,
>
> as can be retrieved from itk::CastImageFilter's Doxygen-entry, this filter
> can obviously be used for casting a 3D-volume to a 2D-slice
> (dimension-reduction).
>
> "... If you attempt to cast an image to a lower dimension, the first
> "slice" (or line or volume) will be extracted. ..."
>
> I've been using this functionality for a while in an application. However,
> today I changed something in the code (at completely different
> code-fragment) and from this point my application started to throw segfaults
> when executing it.
> I traced the bug (in current ITK-CVS-version) and found out that casting
> from a 3D-slice to a 2D-image causes the segfault. Inspecting the code of
> itk::CastImageFilter and its superclass itk::UnaryFunctorImageFilter showed
> me that the code lines 97-112 of itkUnaryFunctorImageFilter.txx seem to
> cause the segfault:
>
>  for (i=0; i < Superclass::InputImageDimension; ++i)
>      {
>      outputSpacing[i] = inputSpacing[i];
>      outputOrigin[i] = inputOrigin[i];
>      for (j=0; j < Superclass::OutputImageDimension; j++)
>        {
>        if (j < Superclass::InputImageDimension)
>          {
>          outputDirection[j][i] = inputDirection[j][i];
>          }
>        else
>          {
>          outputDirection[j][i] = 0.0;
>          }
>        }
>      }
>
> When casting from 3D to 2D the InputImageDimension=3, but the
> OutputImageDimension=2. Writing to the 3rd elements of outputSpacing,
> outputOrigin and outputDirection causes the memory-violation.
>
> Please correct me if I am wrong.
>
> However, it is scary and funny at the same time that my application has
> worked without throwing segfaults and without any obvious errors for a few
> weeks ...
>
> The example program below shows the bug (if it is a bug).
>
> regards,
>
> lars
>
>
> // TestReductionCasting.cxx
>
> #include <iostream>
> #include <stdlib.h>
> #include <time.h>
>
> #include <itkCastImageFilter.h>
> #include <itkImage.h>
> #include <itkImageRegionIterator.h>
>
> int main(int argc, char *argv[])
> {
>  std::cerr << "Constructing 3D image ...";
>  typedef itk::Image<float, 3> Image3DType;
>  typedef itk::ImageRegionIterator<Image3DType> IteratorType;
>
>  Image3DType::RegionType region;
>  Image3DType::SizeType size;
>  Image3DType::IndexType start;
>  Image3DType::SpacingType spacing;
>  Image3DType::PointType origin;
>  Image3DType::DirectionType orientation;
>
>  size[0] = 100; size[1] = 200; size[2] = 1;
>  start.Fill(0);
>  region.SetIndex(start);
>  region.SetSize(size);
>  spacing[0] = 0.25; spacing[1] = 0.5; spacing[2] = 1;
>  origin[0] = 100; origin[1] = 200; origin[2] = -50;
>  orientation.SetIdentity();
>  Image3DType::Pointer image = Image3DType::New();
>  image->SetRegions(region);
>  image->SetSpacing(spacing);
>  image->SetOrigin(origin);
>  image->SetDirection(orientation);
>  image->Allocate();
>
>  srand(time(NULL));
>  IteratorType it(image, region);
>  for (it.GoToBegin(); !it.IsAtEnd(); ++it)
>  {
>    it.Set(static_cast<float>(rand() % 100));
>  }
>  std::cerr << " DONE\n";
>
>  std::cerr << "Casting to 2D image (cast image filter) ...";
>  typedef itk::Image<unsigned char, 2> Image2DType;
>  typedef itk::CastImageFilter<Image3DType, Image2DType> CasterType;
>
>  CasterType::Pointer caster = CasterType::New();
>  caster->SetInput(image);
>  try
>  {
>    caster->Update(); // CAUSES SEGFAULT!!!
>    std::cerr << " DONE\n";
>  }
>  catch (itk::ExceptionObject &e)
>  {
>    std::cerr << " ERROR\n";
>  }
>
>  return EXIT_SUCCESS;
> }
>
> --
> GRATIS für alle GMX-Mitglieder: Die maxdome Movie-FLAT!
> Jetzt freischalten unter http://portal.gmx.net/de/go/maxdome01
> _____________________________________
> Powered by www.kitware.com
>
> Visit other Kitware open-source projects at
> http://www.kitware.com/opensource/opensource.html
>
> Kitware offers ITK Training Courses, for more information visit:
> http://www.kitware.com/products/protraining.html
>
> Please keep messages on-topic and check the ITK FAQ at:
> http://www.itk.org/Wiki/ITK_FAQ
>
> Follow this link to subscribe/unsubscribe:
> http://www.itk.org/mailman/listinfo/insight-users
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.itk.org/pipermail/insight-users/attachments/20100418/872d0c30/attachment.htm>


More information about the Insight-users mailing list