[Insight-users] Inconsistent registration result.

Bradley Lowekamp blowekamp at mail.nih.gov
Fri Mar 1 07:38:41 EST 2013


Hello,

How many threads are you running? Have you tried setting the environment variable ITK_GLOBAL_DEFAULT_NUMBER_OF_THREADS to 1, to see of the results then become consistent?

Brad

On Feb 28, 2013, at 5:52 PM, lien lee <lienlee at gmail.com> wrote:

> Hi itk-users,
> 
> I took a further step today.  I derived a class from MattesMutualInformationImageToImageMetric, and made it being the metric, so that, I could sneak into itk and visit the protected member ImageToImageMetric< TFixedImage, TMovingImage >::m_FixedImageSamples. I printed out a couple of sample points (their coordinates and image values), and I also printed out the seed value of the random number generator, which I set as ReinitializeSeed(76926294).  I get the seed value by calling Statistics::MersenneTwisterRandomVariateGenerator::GetInstance()->GetSeed();
> In different runs, I do see same seed were used, but I also do see different sample points.  I tried this on two different computers, at both of which I saw the inconsistent results. Seems to be the random number generator is non-deterministic even with same seed.  However, the weird thing is if I do not use the image mask, it would be consistent. 
> 
> Any thoughts?
> 
> 
> 2013/2/26 lien lee <lienlee at gmail.com>
> Hi Seth,
> 
> By clicking the link you provided, the code I saw there is as partly attached, which is different from what I have with ITK 4.2 on my computer.  
> 
> I do not have experience with this code, and I am not exactly sure how it works.  But, looks to me, optimizer would call the function during each iteration, and the function would rebuild all the sample points again and again for all the iterations.  If my understanding were correct, this would be quite different from what I have with ITK 4.2 on my computer, where all the samples were created in MattesMutualInformationImageToImageMetric::Initialize() as a one time thing, and the counted points would be determined for each iteration using the current transform by checking whether the mapped points were inside the moving image mask. Therefore, for the code I am working on, to my understanding, if I called ReinitializeSeed(76926294) before generating all the sample points in MattesMutualInformationImageToImageMetric::Initialize(), the results should be deterministic, no matter whether I applied the image masks or not. But, the testing results with image mask applied does NOT support my understanding.
> 
> BTW, to your question, my moving image mask may not be "restrictive" because it occupied pretty much about 80% of the whole moving image.
> 
> Thanks again for your inputs.
> 
> 
>  106 template <class TFixedImage, class TMovingImage>
>  107 void
>  108 MutualInformationImageToImageMetric<TFixedImage, TMovingImage>
>  109 ::SampleFixedImageDomain(
>  110   SpatialSampleContainer & samples) const
>  111 {
>  112   typedef ImageRandomConstIteratorWithIndex<FixedImageType> RandomIterator;
>  113   RandomIterator randIter( this->m_FixedImage, this->GetFixedImageRegion() );
>  114 
>  115   randIter.SetNumberOfSamples(m_NumberOfSpatialSamples);
>  116   randIter.GoToBegin();
>  117 
>  118   typename SpatialSampleContainer::iterator iter;
>  119   typename SpatialSampleContainer::const_iterator end = samples.end();
>  120 
>  121   bool allOutside = true;
>  122 
>  123   this->m_NumberOfPixelsCounted = 0;    // Number of pixels that map into the
>  124                                         // fixed and moving image mask, if
>  125                                         // specified
>  126                                         // and the resampled fixed grid after
>  127                                         // transformation.
>  128 
>  129   // Number of random picks made from the portion of fixed image within the
>  130   // fixed mask
>  131   SizeValueType numberOfFixedImagePixelsVisited = 0;
>  132   SizeValueType dryRunTolerance = this->GetFixedImageRegion().GetNumberOfPixels();
>  133   for( iter = samples.begin(); iter != end; ++iter )
>  134     {
>  135     // Get sampled index
>  136     FixedImageIndexType index = randIter.GetIndex();
>  137     // Get sampled fixed image value
>  138     ( *iter ).FixedImageValue = randIter.Get();
>  139     // Translate index to point
>  140     this->m_FixedImage->TransformIndexToPhysicalPoint(index,
>  141                                                       ( *iter ).FixedImagePointValue);
>  142 
>  143     // If not inside the fixed mask, ignore the point
>  144     if( this->m_FixedImageMask
>  145         && !this->m_FixedImageMask->IsInside( ( *iter ).FixedImagePointValue ) )
>  146       {
>  147       ++randIter; // jump to another random position
>  148       continue;
>  149       }
>  150 
>  151     if( allOutside )
>  152       {
>  153       ++numberOfFixedImagePixelsVisited;
>  154       if( numberOfFixedImagePixelsVisited > dryRunTolerance )
>  155         {
>  156         // We randomly visited as many points as is the size of the fixed image
>  157         // region.. Too may samples mapped ouside.. go change your transform
>  158         itkExceptionMacro(<< "Too many samples mapped outside the moving buffer");
>  159         }
>  160       }
>  161 
>  162     MovingImagePointType mappedPoint =
>  163       this->m_Transform->TransformPoint( ( *iter ).FixedImagePointValue );
>  164 
>  165     // If the transformed point after transformation does not lie within the
>  166     // MovingImageMask, skip it.
>  167     if( this->m_MovingImageMask
>  168         && !this->m_MovingImageMask->IsInside(mappedPoint) )
>  169       {
>  170       ++randIter;
>  171       continue;
>  172       }
>  173 
>  
> 
> 2013/2/26 Seth Gilchrist <seth at mech.ubc.ca>
> Hi Lien,
> Unfortunately I have not used masks when performing registrations, so can't help you with this specific problem.
> 
> I took a look at the git blob for the MattesMutual...Metric and was examining how the decision to keep or reject a give point is handled. If you are setting a mask on both the fixed and moving images, this will change what points are used because a check is done to see if a point is in the fixed mask and if it is in the moving mask after applying the current transform. Could your moving image mask be too restrictive for the early stages of the registration?
> 
> You can read the code at:
> http://itk.org/gitweb?p=ITK.git;a=blob;f=Modules/Registration/Common/include/itkMutualInformationImageToImageMetric.hxx;h=1244e5c0be768696cf042f6f39739f4b2bdcbba6;hb=HEAD
> 
> Starting on line 108, specifically on line 162.
> 
> Cheers,
> Seth
> 
> Seth Gilchrist, MASc, PhD Candidate
> +---------------------------------------+
> Orthopaedic and Injury Biomechanics Group
> UBC Department of Mechanical Engineering
> 6th Floor-2635 Laurel Street
> Vancouver, BC V5Z-1M9
> +---------------------------------------+
> seth at mech.ubc.ca
> Fax 604-675-2576
> 
> 
> 
> _____________________________________
> 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.php
> 
> 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/20130301/2d9b0493/attachment.htm>


More information about the Insight-users mailing list