[Insight-users] BUG in MattesMI (FixedImageMask, UseAllPixelsOn)
Luis Ibanez
luis.ibanez at kitware.com
Tue Sep 5 13:29:55 EDT 2006
Hi Christoph,
You are right, This is indeed a bug.
I missed to notice that the while loop was controlled by
the end() of the samples container instead of the IsAtEnd()
of the region iterator.
Karthik already has a fix for it and it will be committed
before ITK 3.0.
Regards,
Luis
----------------------------
Christoph Niedermayr wrote:
> Am Montag, den 04.09.2006, 14:54 -0400 schrieb Luis Ibanez:
>
>
>> This is not a bug.
>
>
> i still believe it is :)
>
>
>>The RandomImageIterator that is used in the implementation
>>of MattesMutualInformation does not move in an orderly manner
>>across the Image Buffer, but it never gets out of the region
>>that it was defined to walk.
>
>
> this is correct, but only applies to SampleFixedDomain().
> As i said, i use UseAllPixelsOn(), which causes SampleFullFixedDomain()
> to be called instead.
> if you take a look at [1], you will see that SampleFullFixedDomain()
> uses a ImageRegionConstIteratorWithIndex.
>
> thanks for the detailed explanation though.
>
> best regards,
> chris
>
>
> [1] itkMattesMutualInformationImageToImageMetric.txx, line 487
> template < class TFixedImage, class TMovingImage >
> void
> MattesMutualInformationImageToImageMetric<TFixedImage,TMovingImage>
> ::SampleFullFixedImageDomain( FixedImageSpatialSampleContainer&
> samples )
> {
>
> // Set up a region interator within the user specified fixed image
> region.
> typedef ImageRegionConstIteratorWithIndex<FixedImageType>
> RegionIterator;
> RegionIterator regionIter( this->m_FixedImage,
> this->GetFixedImageRegion() );
>
>
>
>>Every invocation of the itr++ operator is simply equivalent
>>to rolling a dice for each one of the index components in the
>>iterator position.
>>
>>Calling the operator++ many times will never result in the
>>index to go out of the image domain. The reason is that the
>>dice rolling is done by taking the image buffer as a continuous
>>linear array, and then every call to ++ generates a number between
>>zero and the number of pixels in the image. The result is used
>>for computing the index of the pixel that correspond to that
>>offset position from the origin of the image buffer.
>>
>>You may find interesting to look at the code of the
>>
>> Insight/Code/Common/
>> itkImageRandomConstIteratorWithIndex.h
>> itkImageRandomConstIteratorWithIndex.txx
>>
>>where the operator++() is implemented.
>>
>>You will find that it calls the RandomJump method, that in turn
>>uses the MersenneTwisterRandomVariateGenerator for generating a
>>random position *inside* the range of the image region.
>>
>>
>>Please take a look at this code and let us know if you have
>>further questions,
>>
>>
>>
>> Thanks
>>
>>
>> Luis
>>
>>
>>--------------------------
>>Christoph Niedermayr wrote:
>>
>>>Hi all!
>>>
>>>I wanted to use the MattesMutualInformationImageToImageMetric with a
>>>fixed (and moving) image masks.
>>>The metric should use all pixels in the mask so i set UseAllPixelsOn().
>>>After some hours of debugging :( i found the following bug:
>>>
>>>in [1], the metric prepares for taking as much samples as the size of
>>>the fixed image region
>>>in [2], the whole fixed image is sampled, but "bad" samples outside the
>>>mask are skipped (thats ok). the sample iterator only steps forward when
>>>a "good" sample has been found. the loop only stops when the sample
>>>container is full (thats bad).
>>>
>>>this means that for each sample outside the mask, the iterator will step
>>>one index *outside* the image buffer!
>>>
>>>i hope i'm not mistaken!
>>>chris
>>>
>>>
>>>[1]
>>>itkMattesMutualInformationImageToImageMetric.txx, line 237:
>>> if( m_UseAllPixels )
>>> {
>>> m_NumberOfSpatialSamples =
>>> this->GetFixedImageRegion().GetNumberOfPixels();
>>> }
>>>
>>> /**
>>> * Allocate memory for the fixed image sample container.
>>> */
>>> m_FixedImageSamples.resize( m_NumberOfSpatialSamples );
>>>
>>>
>>>
>>>[2]
>>>itkMattesMutualInformationImageToImageMetric.txx, line 501:
>>> if( this->m_FixedImageMask )
>>> {
>>>
>>> typename Superclass::InputPointType inputPoint;
>>>
>>> iter=samples.begin();
>>>
>>> while( iter <= end )
>>> {
>>> // Get sampled index
>>> FixedImageIndexType index = regionIter.GetIndex();
>>> // Check if the Index is inside the mask, translate index to point
>>> this->m_FixedImage->TransformIndexToPhysicalPoint( index,
>>>inputPoint );
>>>
>>> // If not inside the mask, ignore the point
>>> if( !this->m_FixedImageMask->IsInside( inputPoint ) )
>>> {
>>> ++regionIter; // jump to next pixel
>>> continue;
>>> }
>>>
>>> // Get sampled fixed image value
>>> (*iter).FixedImageValue = regionIter.Value();
>>> // Translate index to point
>>> (*iter).FixedImagePointValue = inputPoint;
>>>
>>> // Jump to random position
>>> ++regionIter;
>>> ++iter;
>>> }
>>> }
>>>
>>>_______________________________________________
>>>Insight-users mailing list
>>>Insight-users at itk.org
>>>http://www.itk.org/mailman/listinfo/insight-users
>>>
>>>
>>
>>
>
> _______________________________________________
> Insight-users mailing list
> Insight-users at itk.org
> http://www.itk.org/mailman/listinfo/insight-users
>
>
More information about the Insight-users
mailing list