Hi all,
It will take a lot of words to describe the issue. But I think it might be a bug.
Thank you for your time reading this.
Let me first specify the functions I used.
I’m doing image registration, translation first, then B-Spline.
Before using sampling, everything works fine.
In order to speed up the process, I use stochastic gradient descent.
by adding the following lines
registration_->SetMetricSamplingPercentage(0.1);
registration_->SetMetricSamplingStrategy(RegistrationType::RANDOM);
registration_->MetricSamplingReinitializeSeed(1);// if no para : random (take time as seed)
registration_->InPlaceOn();
between SetInitialTransform(transform_); and Update();
If there’s any problem with the code, please let me know.
If not, here’s the long story.
What I’m working on is doing pairwise registration on all image pairs of one video (~30000 frames).
I would like to reproduce the result, therefore I use “MetricSamplingReinitializeSeed(1)”
After test, the result is reproducible so I believe I’m using correct code.
However, the strange thing is, when I tried to process the same video 8 times in a single execution of program
It always throws exception at the 4th and 7th trial, but at different frame index. (this “semi-reproducible” behavior really confused me)
By tracing the dump file and also reading the exception message, there are 2 lines of code where exception occured.
-
itkObjectToObjectMetric.hxx, line 425. which means the ObjectToObjectMetric::m_VirtualImage is null.
If I understand correctly, this line (or this function) is for dense sampling, which means in principle, it should not be called. -
itkImageToImageMetricv4.hxx, line 532. which means ImageToImageMetricv4::m_FixedSampledPointSet is null.
This function is in normal function call routine. m_FixedSampledPointSet should not be null
Since most of the time, the result is reproducible, the only reason I know for these kinds of exception (wrong function call, pointer becomes null) is some part of the code writes to where it should not write (like out of array boundary)
Things are more complicated since I used 44 threads. Each thread calls its own itk registration,(for example, thread 0 processing frame 1~800, thread 2, 801~1600, … ,etc.)
Inside each thread, I have set
itk::MultiThreader::SetGlobalMaximumNumberOfThreads(1);
So there should not be multi-threading inside itk registration object
Since everything is fine before using the sampling method.
Either I used the function in a wrong way, or there might be some bug in these function.
(or it’s my other code having bug, but didn’t affect anything before using sampling)
I’m also trying to check the source code, I will report if I found any clue.