# Some thing slow down itkMaskNeighborhoodOperatorImageFilter

**URL:** <https://discourse.itk.org/t/some-thing-slow-down-itkmaskneighborhoodoperatorimagefilter/537>\
**Category:** Algorithms\
**Created:** [December 18, 2017, 10:06am UTC](https://discourse.itk.org/t/some-thing-slow-down-itkmaskneighborhoodoperatorimagefilter/537 "2017-12-18T10:06:06Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Rock\_Lin](https://discourse.itk.org/letter_avatar_proxy/v4/letter/r/c0e974/32.png) [@Rock\_Lin](https://discourse.itk.org/u/Rock_Lin)\
**Post date:** [December 18, 2017, 10:06am UTC](https://discourse.itk.org/t/some-thing-slow-down-itkmaskneighborhoodoperatorimagefilter/537/1 "2017-12-18T10:06:07Z")

</div>

Hi, ITK developers,

I am working for implementing a fast convolution process and I found some thing seems incorrect in the itkMaskNeighborhoodOperatorImageFilter . I made a MaskConvolutionImageFilter using itkMaskNeighborhoodOperatorImageFilter, so that convolution process is able to be faster by applying a small mask as a input. However, regarding my testing results, I found the process still requires 8 to 11 sec to finish convolution even I input only a blank mask. After I trace source code of MaskNeighborhoodOperatorImageFilter. The behavior of the source code does really confuse me, because itk::ConstNeighborhoodIterator do check boundary hitting for each dimension when every time iterator moving. This check action seems very expensive and slow down entire convolution process because it is performed even the target pixel isn’t belong to mask. I have appiled some modification to improve performance of convolution process. Both original code and modified code are shown as follows:

Original code:

ConstNeighborhoodIterator\< InputImageType \> bit;  
typename FaceListType::iterator fit;  
ImageRegionIterator\< OutputImageType \> it;  
ImageRegionConstIterator\< MaskImageType \> mit;

for ( fit = faceList.begin(); fit != faceList.end(); ++fit )  
{  
bit =  
ConstNeighborhoodIterator\< InputImageType \>(noperator.GetRadius(),  
input, \*fit);  
bit.OverrideBoundaryCondition( this-\>GetBoundaryCondition() );  
bit.GoToBegin();  
it = ImageRegionIterator\< OutputImageType \>(output, \*fit);  
mit = ImageRegionConstIterator\< MaskImageType \>(mask, \*fit);  
while ( !bit.IsAtEnd() )  
{  
if ( mit.Get() )  
{  
// Compute the inner product at this pixel  
it.Value() = static\_cast\< typename OutputImageType::PixelType \>( smartInnerProduct(bit, noperator) );  
}  
else  
{  
// Use the default value or the input value  
it.Value() = m\_UseDefaultValue ? m\_DefaultValue : bit.GetCenterPixel();  
}  
++bit; // This movement cause the performance issue  
++it;  
++mit;  
progress.CompletedPixel();  
}  
}

The small modification:

itk::ConstNeighborhoodIterator bit;  
itk::ImageRegionConstIterator light\_bit;  
typename FaceListType::iterator fit;  
itk::ImageRegionIterator it;  
itk::ImageRegionConstIteratorWithIndex mit;

for(fit = faceList.begin(); fit != faceList.end(); ++fit)  
{  
bit =  
itk::ConstNeighborhoodIterator(noperator.GetRadius(),  
input, \*fit);  
bit.OverrideBoundaryCondition(this-\>GetBoundaryCondition());  
bit.GoToBegin();  
light\_bit = itk::ImageRegionConstIterator(input, \*fit);  
it = itk::ImageRegionIterator(output, \*fit);  
mit = itk::ImageRegionConstIteratorWithIndex(mask, \*fit);

for(mit = mit.Begin(); mit != mit.End(); ++mit)  
{  
if (mit.Get())  
{  
// Compute the inner product at this pixel  
bit.SetLocation( mit.GetIndex() ); // Only check boundary hitting and warp offset when pixels belong to mask area  
it.Value() = static\_cast(smartInnerProduct(bit, noperator));  
}  
else  
{  
// Use the default value or the input value  
it.Value() = Superclass::GetUseDefaultValue() ? Superclass::GetDefaultValue() : light\_bit.Value();  
}  
++light\_bit;  
++it;  
}  
}

---

<div class="post-metadata">

**Author:** ![Niels\_Dekker](https://discourse.itk.org/letter_avatar_proxy/v4/letter/n/9d8465/32.png) [@Niels\_Dekker](https://discourse.itk.org/u/Niels_Dekker)\
**Post date:** [December 18, 2017, 11:21am UTC](https://discourse.itk.org/t/some-thing-slow-down-itkmaskneighborhoodoperatorimagefilter/537/2 "2017-12-18T11:21:11Z")

</div>

FYI, Coincidentally, I’m currently also looking into ways to improve the performance of ConstNeighborhoodIterator. I proposed the following improvement: “PERF: Improved speed of copying and resizing NeighborhoodAllocator”, [http://review.source.kitware.com/#/c/22862/](http://review.source.kitware.com/#/c/22862/) I hope to see it being merged onto the master very soon, then I can continue and submit some more performance patches in this area 🙂

---

<div class="post-metadata">

**Author:** ![dzenanz](https://discourse.itk.org/user_avatar/discourse.itk.org/dzenanz/32/1093_2.png) [@dzenanz](https://discourse.itk.org/u/dzenanz)\
**Post date:** [December 18, 2017, 2:56pm UTC](https://discourse.itk.org/t/some-thing-slow-down-itkmaskneighborhoodoperatorimagefilter/537/3 "2017-12-18T14:56:08Z")

</div>

Thanks for sharing your code @Rock_Lin! If you submit your code to [Gerrit](http://review.source.kitware.com/), following these [instructions](https://itk.org/Wiki/ITK/Git/Develop), we can do a review of your code easier and probably integrate it into ITK after version 4.13 is released (scheduled for Wednesday this week).

---

<div class="post-metadata">

**Author:** ![Rock\_Lin](https://discourse.itk.org/letter_avatar_proxy/v4/letter/r/c0e974/32.png) [@Rock\_Lin](https://discourse.itk.org/u/Rock_Lin)\
**Post date:** [December 18, 2017, 2:59pm UTC](https://discourse.itk.org/t/some-thing-slow-down-itkmaskneighborhoodoperatorimagefilter/537/4 "2017-12-18T14:59:28Z")

</div>

Thank you for info me this. It seems great.

---

<div class="post-metadata">

**Author:** ![Niels\_Dekker](https://discourse.itk.org/letter_avatar_proxy/v4/letter/n/9d8465/32.png) [@Niels\_Dekker](https://discourse.itk.org/u/Niels_Dekker)\
**Post date:** [January 8, 2018, 4:13pm UTC](https://discourse.itk.org/t/some-thing-slow-down-itkmaskneighborhoodoperatorimagefilter/537/5 "2018-01-08T16:13:10Z")

</div>

@Rock_Lin After you started this topic, two “neighborhood related” performance improvements that I proposed were merged to the master branch of ITK:

_PERF: Improved speed of copying and resizing NeighborhoodAllocator_  
[https://itk.org/gitweb?p=ITK.git;a=commit;h=b53983fab4a8fdb434717e13351875a6db9d1b26](https://itk.org/gitweb?p=ITK.git;a=commit;h=b53983fab4a8fdb434717e13351875a6db9d1b26)

_PERF: NeighborhoodOperatorImageFunction avoids copy ConstNeighborhoodIterator_  
[https://itk.org/gitweb?p=ITK.git;a=commit;h=c37bd4e74fa2390309502cfc1eedf59dcc4c4f0e](https://itk.org/gitweb?p=ITK.git;a=commit;h=c37bd4e74fa2390309502cfc1eedf59dcc4c4f0e)

Do these two improvements actually fix your problem? Can you please have a look at them?
