[Insight-users] ResampleImageFilter crashes in release mode
Luis Ibanez
luis.ibanez at kitware.com
Thu Jul 2 18:30:08 EDT 2009
Hi Michael,
Thanks for running these additional tests
and for reporting back.
0) You mentioned that you found an error in the Software Guide
in page 28.
Could you please let us know what it was, so we can fix it ?
(Thanks).
1) I have a less optimistic interpretation of the results from your test.
If I understand correctly from your email,
You inserted the two writers for saving the input images
before calling the resampling, and you say that this code
crashes in Release mode, while it works on Debug.
I would say that this clearly indicates that something is
going wrong *before* the resampling.
I common cause for code to work in Debug and not in Release,
is to have uninitialized variables. You may want to run your code
through a dynamic checker such ad Valgrind or Purify.
2) I'm not aware of any incompatibilities between ITK and wxWidgets,
and would be very surprised to learn that there is any.
GUI libraries should be totally independent.
3) Typical suspects at this point are:
- Unititialized variables
- ITK Classes that have been created in a certain scope
and that have been destroyed by the time you get them
to the code that performs the resampling. (e.g. check the
pointer to Transform). You may have SmartPointer that
are pointing to classes that have been already deallocated.
One way of debugging this is to connect an Observer to
the suspect objects. Upon destruction ITK classes invoke
an itk::DeleteEvent.
4) BTW: Why are you using GetPointer() in the calls:
resampler->SetTransform( transform.GetPointer() );
resampler->SetInterpolator( interpolator.GetPointer() );
That shouldn't be necessary.
It you did this in order to get around some compilation error,
it is likely that that compilation error was flagging a fundamental
problem with the code.
Could you please remove the GetPointer() calls ?
It should just be:
resampler->SetTransform( transform );
resampler->SetInterpolator( interpolator );
5) And... another big suspect....
Looking back at your first email, you told us that the crash
happens in the execution of the ProcessObject update at:
if ( m_Source ) // <---m_Source is valid,
but when i step over
here, it gets an invalid pointer
This is probably because when you generate the images
with the import filter, you are not disconnecting them from
the filter, so they get to the Resampling function believing
that they are still attached to a source filter, when in fact,
that import filter was destroyed when reached the end
of the scope in the function
dataInterface2itk()
Please, at the end of that function, replace the code
import->Update();
image = import->GetOutput();
image->Update();
// cout << image;
return image;
}
with
import->Update();
image = import->GetOutput();
image->Update();
image->DisconnectPipeline(); // IMPORTANT !
return image;
}
I'm suspecting that (5) is the real source of the problem.
Please try this and let us know what you find.
Thanks
Luis
----------------------------------------------------------------
On Thu, Jul 2, 2009 at 2:04 PM, Michael Schildt <
michael.schildt at ifn-magdeburg.de> wrote:
> Hello Luis,
>
> I checked the things, you mentioned:
>
>
> Luis Ibanez schrieb:
>
>>
>> Hi Michael,
>>
>> Thanks for adding the Print() statements
>> and posting the outcome to the mailing list.
>>
>> The image data look ok.
>> and so it does the filter metadata.
>>
>> It is good that you also added the code
>> that you are using for generating the images.
>>
>> A common suspect when you using the
>> import filter is to get wrong the ownership
>> of the image pixel buffer.
>>
>> You are using
>>
>> const unsigned int numberOfPixels = diImage->getSize();
>> dType* data = diImage->getData();
>> import->SetImportPointer( data, numberOfPixels, false );
>>
>> I'll strongly suggest that you verify that the
>> "numberOfPixels" is correct here, and also
>> reconsider whether the flag in SetImportPointer()
>> should be "false" or "true".
>>
> I did this intentionally after consulting documentation to save memory. I
> have the data sets already in memory and they are displayed correctly in the
> views of my wxWidgets application. So, i just borrow this memory to ITK to
> do the registration task, whch by the way give strange results even for
> registration of one replicated dataset. Afterwards datasets are further used
> in the program without assitance of ITK. For that reason i do not want ITK
> to own and release the memory. The number of byte i have verified it is
> 256x256x256=16777216 so it is correct too.
>
>>
>> When set to true, the import filter will own the memory
>> buffer, which means that it will deallocate it when the
>> importer is destroyed.
>>
>>
>> The process of importing the image is a lot more
>> suspicious than the resampling.
>> Please do the following:
>>
>> 1) Before the resampling code, instantiate two
>> ImageFileWriters, one for the fixed image,
>> and the other one for the moving image.
>> and write the images to a fileformat for which
>> you have a trusty image viewer.
>>
>> (you could use Slicer, VV, ParaView, SNAP...)
>>
> I have done this and included write just before resample stuff posted
> earlier in this thread:
>
> itk::ImageFileWriter<FloatImage3DType>::Pointer writerfixedImage;
> writerfixedImage = itk::ImageFileWriter<FloatImage3DType>::New();
> writerfixedImage->SetInput (fixedIm);
> writerfixedImage->SetFileName( "c:\\temp\\fixedImage.hdr" );
> writerfixedImage->Update();
>
> itk::ImageFileWriter<FloatImage3DType>::Pointer writermovingImage;
> writermovingImage = itk::ImageFileWriter<FloatImage3DType>::New();
> writermovingImage->SetInput (movingIm);
> writermovingImage->SetFileName( "c:\\temp\\movingImage.hdr" );
> writermovingImage->Update();
> By the way, i took the exampe from the ItkSoftwareGuide-2.4.0.pdf on page
> 28 but it contains several error. Maybe it can be noted for a update of the
> guide. In Debug mode i get out the data as Analyze and it looks exactly like
> the original data sets. In Release mode the application crashes already at
> writerfixedImage->Update(); So the good point is, it does seem to be the
> resampler.
> But it gets even more confusing. I wrote a short test programm using my
> code to load the data, resample and save via the source above. It runs in
> Debug and Release mode without crash! So, i copied this small piece into my
> application to be executed on button press. That crashs again. I copied the
> piece in the MyApp::OnInit() of my wxWidgets application, it crashes too.
> Then, I change the application type of the test programm from console to
> windows program and it still runs fine in Release and Debug. So the only
> difference seems to be that my application is using wxWidgets, but the test
> programm does not. In the debugger it looks like the ITK is executed on
> NULL-Pointer but this makes no sense and could be due to compiler
> optimizations. At that point i have no idea what to test further.
>
> Are there any issues or side effects known when using ITK together with
> wxWidgets?
>
> With best reguards,
> Michael Schildt
>
>>
>> 2) Run the code and save the images, no need
>> to run the resampler.
>>
> I did so.
>
>>
>> 3) Open the images with the viewer and let us
>> know if they are in good shape.
>>
>> 4) I would expect that the images are corrupted
>> at this point, but we will only know for sure
>> after you run this test.
>>
> At least they look exactly the way they should do, so this doesn't seem to
> be the point.
>
>>
>>
>> Please let us now what you find.
>>
>>
>> Thanks
>>
>>
>> Luis
>>
>>
>>
>> ----------------------------------------------------------
>> On Wed, Jul 1, 2009 at 8:28 AM, Michael Schildt <
>> michael.schildt at ifn-magdeburg.de <mailto:michael.schildt at ifn-magdeburg.de>>
>> wrote:
>>
>> Hello Luis,
>>
>> thank you for your suggestions.
>>
>> I inserted the Prints in my source code and here ist the output:
>> --------------------------- fixedIm -------------------------------
>> Image (00339668)
>> RTTI typeinfo: class itk::Image<float,3>
>> Reference Count: 3
>> Modified Time: 20
>> Debug: Off
>> Observers:
>> none
>> Source: (none)
>> Source output index: 0
>> Release Data: Off
>> Data Released: False
>> Global Release Data: Off
>> PipelineMTime: 13
>> UpdateMTime: 19
>> LargestPossibleRegion:
>> Dimension: 3
>> Index: [0, 0, 0]
>> Size: [256, 256, 256]
>> BufferedRegion:
>> Dimension: 3
>> Index: [0, 0, 0]
>> Size: [256, 256, 256]
>> RequestedRegion:
>> Dimension: 3
>> Index: [0, 0, 0]
>> Size: [256, 256, 256]
>> Spacing: [1, 1, 1]
>> Origin: [0, 0, 0]
>> Direction:
>> 1 0 0
>> 0 1 0
>> 0 0 1
>>
>> IndexToPointMatrix:
>> 1 0 0
>> 0 1 0
>> 0 0 1
>>
>> PointToIndexMatrix:
>> 1 0 0
>> 0 1 0
>> 0 0 1
>>
>> PixelContainer:
>> ImportImageContainer (01390EA8)
>> RTTI typeinfo: class itk::ImportImageContainer<unsigned
>> long,float>
>> Reference Count: 1
>> Modified Time: 17
>> Debug: Off
>> Observers:
>> none
>> Pointer: 034B0020
>> Container manages memory: false
>> Size: 16777216
>> Capacity: 16777216
>>
>> --------------------------- movingIm ------------------------------
>> Image (00337178)
>> RTTI typeinfo: class itk::Image<float,3>
>> Reference Count: 4
>> Modified Time: 40
>> Debug: Off
>> Observers:
>> none
>> Source: (none)
>> Source output index: 0
>> Release Data: Off
>> Data Released: False
>> Global Release Data: Off
>> PipelineMTime: 33
>> UpdateMTime: 39
>> LargestPossibleRegion:
>> Dimension: 3
>> Index: [0, 0, 0]
>> Size: [256, 256, 256]
>> BufferedRegion:
>> Dimension: 3
>> Index: [0, 0, 0]
>> Size: [256, 256, 256]
>> RequestedRegion:
>> Dimension: 3
>> Index: [0, 0, 0]
>> Size: [256, 256, 256]
>> Spacing: [1, 1, 1]
>> Origin: [0, 0, 0]
>> Direction:
>> 1 0 0
>> 0 1 0
>> 0 0 1
>>
>> IndexToPointMatrix:
>> 1 0 0
>> 0 1 0
>> 0 0 1
>>
>> PointToIndexMatrix:
>> 1 0 0
>> 0 1 0
>> 0 0 1
>>
>> PixelContainer:
>> ImportImageContainer (0033BE98)
>> RTTI typeinfo: class itk::ImportImageContainer<unsigned
>> long,float>
>> Reference Count: 1
>> Modified Time: 37
>> Debug: Off
>> Observers:
>> none
>> Pointer: 074C0020
>> Container manages memory: false
>> Size: 16777216
>> Capacity: 16777216
>>
>> --------------------------- resampler -----------------------------
>> ResampleImageFilter (00338A08)
>> RTTI typeinfo: class itk::ResampleImageFilter<class
>> itk::Image<float,3>,cla
>> s itk::Image<float,3>,double>
>> Reference Count: 2
>> Modified Time: 64
>> Debug: Off
>> Observers:
>> none
>> Number Of Required Inputs: 1
>> Number Of Required Outputs: 1
>> Number Of Threads: 1
>> ReleaseDataFlag: Off
>> ReleaseDataBeforeUpdateFlag: Off
>> Input 0: (00337178)
>> Output 0: (00338B88)
>> AbortGenerateData: Off
>> Progress: 0
>> Multithreader:
>> RTTI typeinfo: class itk::MultiThreader
>> Reference Count: 1
>> Modified Time: 49
>> Debug: Off
>> Observers:
>> none
>> Thread Count: 1
>> Global Maximum Number Of Threads: 128
>> Global Default Number Of Threads: 1
>> DefaultPixelValue: 0
>> Size: [256, 256, 256]
>> OutputStartIndex: [0, 0, 0]
>> OutputOrigin: [0, 0, 0]
>> OutputSpacing: [1, 1, 1]
>> OutputDirection: 1 0 0
>> 0 1 0
>> 0 0 1
>>
>> Transform: 00337350
>> Interpolator: 00338860
>> UseReferenceImage: Off
>>
>> I already call Update on the Images but after the Set..- commands. I'm
>> not sure about the order of commands to import the images to itk. Here
>> is my import method called to create fixedIm and movingIm, maybe this
>> helps to localize the problem (MRIScalarLayer is a custom class just
>> containing the image data and some infos):
>>
>> template<typename dType> typename itk::Image<dType,3>::Pointer
>> dataInterface2itk(MRIScalarLayer<dType> *diImage)
>> {
>> typedef itk::Image<dType,3> Image3DType;
>> typename Image3DType::Pointer image = Image3DType::New();
>> typedef itk::ImportImageFilter<dType,3> ImportFilterImage3DType;
>> typename ImportFilterImage3DType::Pointer import =
>> ImportFilterImage3DType::New();
>> typename ImportFilterImage3DType::SizeType size;
>> size[0] = diImage->getSize((unsigned char)0); // size along X
>> size[1] = diImage->getSize((unsigned char)1); // size along Y
>> size[2] = diImage->getSize((unsigned char)2); // size along Z
>> typename ImportFilterImage3DType::IndexType start;
>> start.Fill( 0 );
>> typename ImportFilterImage3DType::RegionType region;
>> region.SetIndex( start );
>> region.SetSize( size );
>> import->SetRegion( region );
>> double spacing[ 3 ];
>> // hier sollte noch das gap mit beachtet werden, welches es nicht in
>> itk gibt
>> spacing[0] = diImage->getSpacing((unsigned char)0); // along X
>> direction
>> spacing[1] = diImage->getSpacing((unsigned char)1); // along Y
>> direction
>> spacing[2] = diImage->getSpacing((unsigned char)2); // along Z
>> direction
>> import->SetSpacing( spacing );
>> double origin[ 3 ];
>> origin[0] = diImage->getOrigin((unsigned char)0); // X coordinate
>> origin[1] = diImage->getOrigin((unsigned char)1); // Y coordinate
>> origin[2] = diImage->getOrigin((unsigned char)2); // Z coordinate
>> import->SetOrigin( origin );
>>
>> const unsigned int numberOfPixels = diImage->getSize();
>> dType* data = diImage->getData();
>> import->SetImportPointer( data, numberOfPixels, false );
>> import->Update();
>> image = import->GetOutput();
>> image->Update();
>>
>> // cout << image;
>> return image;
>> }
>>
>> Best requards,
>> Michael Schildt
>>
>> Luis Ibanez schrieb:
>>
>>
>> Hi Michael,
>>
>>
>> This looks like a bug in your code :-(
>>
>>
>>
>> Typical suspects are:
>>
>>
>> A) The fixed image is not available yet at
>> the time you call GetLargestPossibleRegion(),
>> GetOrigin(), GetSpacing().
>>
>> You should call fixedIm->Update()
>>
>> before you call any of the above methods.
>>
>>
>> We will learn a lot about other possible causes if
>> you add to your code the following:
>>
>> fixedIm->Print( std::cout );
>> movingIm->Print( std::cout );
>> resampler->Print( std::cout );
>>
>> before the line
>>
>> resampler->Update();
>>
>> and if you post the resulting output text to the
>> mailing list.
>>
>>
>> Please let us know what you find.
>>
>>
>> Thanks
>>
>>
>> Luis
>>
>>
>> ----------------------------------------------------------------
>> On Fri, Jun 26, 2009 at 6:42 AM, Michael Schildt
>> <michael.schildt at ifn-magdeburg.de
>> <mailto:michael.schildt at ifn-magdeburg.de>
>> <mailto:michael.schildt at ifn-magdeburg.de
>> <mailto:michael.schildt at ifn-magdeburg.de>>> wrote:
>>
>> Hello!
>>
>> I have some trouble with ResampleImageFilter. I'm not sure
>> if it is a
>> bug in my program or in ITK. It works as expected in Debug
>> configuration
>> but crashes in Release mode. I traced to the source line in ITK
>> were it
>> appear in RelWithDebMode configuration. I attach some
>> information and
>> source.
>>
>> Best reguards,
>> Michael Schildt
>>
>> The method based on the example in the itkSoftwareGuide:
>>
>> ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
>> template <typename dataT, typename TrfType>
>> typename itk::Image<dataT,3>::Pointer transformImage(typename
>> itk::Image<dataT,3>::Pointer fixedIm,
>> typename
>> itk::Image<dataT,3>::Pointer movingIm,
>> typename
>> TrfType::ConstPointer transform)
>> {
>> typedef itk::Image<dataT, 3> ImageType;
>> typedef TrfType TransformType;
>> typedef itk::LinearInterpolateImageFunction<ImageType,double>
>> InterpolatorType;
>> //typedef
>> itk::WindowedSincInterpolateImageFunction<ImageType,3>
>> InterpolatorType;
>>
>> typedef itk::ResampleImageFilter<ImageType,ImageType>
>> ResamplerType;
>>
>> typename InterpolatorType::Pointer interpolator =
>> InterpolatorType::New();
>>
>> typename ResamplerType::Pointer resampler =
>> ResamplerType::New();
>> resampler->SetInput( movingIm );
>>
>> resampler->SetTransform( transform.GetPointer() );
>> resampler->SetInterpolator( interpolator.GetPointer() );
>> resampler->SetSize(
>> fixedIm->GetLargestPossibleRegion().GetSize() );
>> resampler->SetOutputOrigin( fixedIm->GetOrigin() );
>> resampler->SetOutputSpacing( fixedIm->GetSpacing() );
>> resampler->SetDefaultPixelValue( 0 );
>>
>> // resample the moving image
>> resampler->Update();
>>
>> return resampler->GetOutput();
>> }
>>
>> ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
>>
>> It appears in the Update() method of the resampler. While
>> debugging it
>> seems like a problem in itkDataObject.cxx at line marked
>> with **
>>
>>
>> //----------------------------------------------------------------------------
>> void
>> DataObject
>> ::UpdateOutputData()
>> {
>> // If we need to update due to PipelineMTime, or the fact
>> that our
>> // data was released, then propagate the UpdateOutputData
>> to the
>> source
>> // if there is one.
>> if ( m_UpdateMTime < m_PipelineMTime || m_DataReleased ||
>> this->RequestedRegionIsOutsideOfTheBufferedRegion() )
>> {
>> if ( m_Source ) // <---m_Source is valid, but when i
>> step over
>> here, it gets an invalid pointer
>> {
>> ** m_Source->UpdateOutputData(this); // maybe call on
>> invalid
>> pointer?
>> }
>> }
>> }
>>
>> //----------------------------------------------------------------------------
>>
>> Stack backtrace:
>>
>> BrainGUI.exe!std::_Vector_iterator<unsigned
>> int,std::allocator<unsigned int> >::operator+() + 0x17
>> Bytes C++
>>
>> BrainGUI.exe!std::vector<unsigned
>> int,std::allocator<unsigned int> ::resize(unsigned int
>> _Newsize=1, unsigned int _Val=0) Zeile 721 +
>>
>> 0x36 Bytes C++
>> BrainGUI.exe!std::vector<bool,std::allocator<bool>
>>
>> ::_Insert_x(std::_Vb_const_iterator<unsigned
>>
>> int,int,std::vector<bool,std::allocator<bool> > >
>> _Where=..., unsigned
>> int _Count=1) Zeile 2312 C++
>> BrainGUI.exe!std::vector<bool,std::allocator<bool>
>>
>> ::_Insert_n(std::_Vb_const_iterator<unsigned
>>
>> int,int,std::vector<bool,std::allocator<bool> > >
>> _Where=..., unsigned
>> int _Count=1, bool _Val=false) Zeile 2292 C++
>> BrainGUI.exe!std::vector<bool,std::allocator<bool>
>>
>> ::resize(unsigned int _Newsize=1, bool _Val=false)
>> Zeile 2044
>> C++
>>
>>
>> BrainGUI.exe!itk::ProcessObject::CacheInputReleaseDataFlags()
>> Zeile 1055 C++
>>
>> BrainGUI.exe!itk::ProcessObject::UpdateOutputData(itk::DataObject
>> *
>> __formal=0x02079270) Zeile 964 C++
>> BrainGUI.exe!itk::DataObject::UpdateOutputData() Zeile
>> 420 + 0x8
>> Bytes C++
>>
>>
>> BrainGUI.exe!transformImage<float,itk::VersorRigid3DTransform<double>
>>
>> (itk::SmartPointer<itk::Image<float,3> > fixedIm={...},
>>
>> itk::SmartPointer<itk::Image<float,3> > movingIm={...},
>> itk::SmartPointer<itk::VersorRigid3DTransform<double> const >
>> transform={...}) Zeile 123 C++
>> BrainGUI.exe!VersorRigid3DRegistration::doRegistration(bool
>> newVolume=true, void (const double &, const
>>
>> std::basic_string<char,std::char_traits<char>,std::allocator<char>
>> > &)*
>> progress=0x004029e1) Zeile 254 + 0x81 Bytes C++
>> BrainGUI.exe!RegThread::Entry() Zeile 273 + 0xf Bytes
>> C++
>> BrainGUI.exe!wxThreadInternal::DoThreadStart() + 0xa5
>> Bytes C++
>> BrainGUI.exe!wxThreadInternal::WinThreadStart() + 0x6a
>> Bytes C++
>> BrainGUI.exe!_callthreadstartex() Zeile 348 + 0x6 Bytes
>> C
>> BrainGUI.exe!_threadstartex(void * ptd=0x04ef1118)
>> Zeile 326 + 0x5
>> Bytes C
>>
>> System:
>> - Windows XP Prof SP3
>> - Visual Studio 2008 Express Edition
>> - ITK 3.14
>> - CMake 2.6.4
>> - wxWidgets 2.8.9 (wxPack Installer)
>> - Pentium 4
>> - 2GB Ram
>>
>>
>> _____________________________________
>> Powered by www.kitware.com <http://www.kitware.com>
>> <http://www.kitware.com>
>>
>>
>> Visit other Kitware open-source projects at
>> http://www.kitware.com/opensource/opensource.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
>>
>>
>>
>> _____________________________________
>> Powered by www.kitware.com <http://www.kitware.com>
>>
>> Visit other Kitware open-source projects at
>> http://www.kitware.com/opensource/opensource.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/20090702/b75b7494/attachment-0001.htm>
More information about the Insight-users
mailing list