-
Notifications
You must be signed in to change notification settings - Fork 22
WIP: PERF: Use NeighborhoodRange for metric image computation #98
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -23,10 +23,14 @@ | |
| #include "itkConstantBoundaryCondition.h" | ||
| #include "itkConstNeighborhoodIterator.h" | ||
| #include "itkImageKernelOperator.h" | ||
| #include "itkImageRegionConstIterator.h" | ||
| #include "itkImageRegionConstIteratorWithIndex.h" | ||
| #include "itkImageRegionIterator.h" | ||
| #include "itkNeighborhoodAlgorithm.h" | ||
| #include "itkNeighborhoodInnerProduct.h" | ||
| #include "itkConstantBoundaryImageNeighborhoodPixelAccessPolicy.h" | ||
| #include "itkShapedImageNeighborhoodRange.h" | ||
| #include "itkImageNeighborhoodOffsets.h" | ||
| #include <numeric> | ||
|
|
||
| namespace itk | ||
| { | ||
|
|
@@ -88,7 +92,8 @@ NormalizedCrossCorrelationNeighborhoodIteratorMetricImageFilter< TFixedImage, TM | |
| typedef ImageRegionIterator< MetricImageType > MetricIteratorType; | ||
| MetricImageRegionType metricRegion; | ||
| typename MovingImageType::IndexType fitIndex; | ||
| typedef ImageRegionConstIterator< MetricImageType > MetricConstIteratorType; | ||
| //typedef ImageRegionConstIterator< MetricImageType > MetricConstIteratorType; | ||
| typedef ImageRegionConstIteratorWithIndex< MetricImageType > MetricConstIteratorType; | ||
| typedef ConstantBoundaryCondition< MetricImageType > BoundaryConditionType; | ||
| BoundaryConditionType boundaryCondition; | ||
| boundaryCondition.SetConstant( NumericTraits< MetricImagePixelType >::Zero ); | ||
|
|
@@ -116,9 +121,10 @@ NormalizedCrossCorrelationNeighborhoodIteratorMetricImageFilter< TFixedImage, TM | |
| typename FaceCalculatorType::FaceListType faceList = faceCalculator( | ||
| movingPtr, this->m_MovingImageRegion, radius ); | ||
| typename FaceCalculatorType::FaceListType::iterator fit; | ||
| const MetricImagePixelType negativeOne = -1 * NumericTraits< MetricImagePixelType >::One; | ||
| const MetricImagePixelType positiveOne = NumericTraits< MetricImagePixelType >::One; | ||
| MetricImagePixelType normXcorr; | ||
| constexpr MetricImagePixelType negativeOne = -1 * NumericTraits< MetricImagePixelType >::One; | ||
| constexpr MetricImagePixelType positiveOne = NumericTraits< MetricImagePixelType >::One; | ||
| const std::vector<Offset<ImageDimension>> offsets = | ||
| Experimental::GenerateRectangularImageNeighborhoodOffsets(radius); | ||
| for( fit = faceList.begin(); fit != faceList.end(); ++fit ) | ||
| { | ||
| (*fit).Crop( outputRegion ); | ||
|
|
@@ -136,24 +142,60 @@ NormalizedCrossCorrelationNeighborhoodIteratorMetricImageFilter< TFixedImage, TM | |
| MetricIteratorType metricIt( metricPtr, metricRegion ); | ||
|
|
||
| MetricConstIteratorType denomIt( denom, *fit ); | ||
| NeighborhoodIteratorType movingNeighborIt( radius, movingMinusMean, *fit ); | ||
| movingNeighborIt.OverrideBoundaryCondition( &boundaryCondition ); | ||
|
|
||
|
|
||
| // for every pixel in the output | ||
| for( metricIt.GoToBegin(), denomIt.GoToBegin(), movingNeighborIt.GoToBegin(); | ||
| //NeighborhoodIteratorType movingNeighborIt( radius, movingMinusMean, *fit ); | ||
| //movingNeighborIt.OverrideBoundaryCondition( &boundaryCondition ); | ||
| //for( metricIt.GoToBegin(), denomIt.GoToBegin(), movingNeighborIt.GoToBegin(); | ||
| //!metricIt.IsAtEnd(); | ||
| //++metricIt, ++denomIt, ++movingNeighborIt ) | ||
| //{ | ||
| //if( !(denomIt.Get() == NumericTraits< MetricImagePixelType >::Zero) ) | ||
| //{ | ||
| //const MetricImagePixelType normXcorr = innerProduct( movingNeighborIt, fixedKernelOperator ) / denomIt.Get(); | ||
|
|
||
| //// Why does this happen? Bug? Funky floating point behavior? | ||
| //if( normXcorr < negativeOne ) | ||
| //{ | ||
| //metricIt.Set( negativeOne ); | ||
| //} | ||
| //else if ( normXcorr > positiveOne ) | ||
| //{ | ||
| //metricIt.Set( positiveOne ); | ||
| //} | ||
| //else | ||
| //{ | ||
| //metricIt.Set( normXcorr ); | ||
| //} | ||
| //} | ||
| //} | ||
| for( metricIt.GoToBegin(), denomIt.GoToBegin(); | ||
| !metricIt.IsAtEnd(); | ||
| ++metricIt, ++denomIt, ++movingNeighborIt ) | ||
| ++metricIt, ++denomIt) | ||
| { | ||
| if( !(denomIt.Get() == NumericTraits< MetricImagePixelType >::Zero) ) | ||
| { | ||
| normXcorr = innerProduct( movingNeighborIt, fixedKernelOperator ) / denomIt.Get(); | ||
| using RangeType = Experimental::ShapedImageNeighborhoodRange<const MetricImageType, | ||
| Experimental::ConstantBoundaryImageNeighborhoodPixelAccessPolicy<const MetricImageType> >; | ||
| const RangeType movingRange{ *movingMinusMean, denomIt.GetIndex(), offsets }; | ||
| const RangeType kernelRange{ *fixedMinusMean, denomIt.GetIndex(), offsets }; | ||
|
|
||
| const MetricImagePixelType normXcorr = std::inner_product( movingRange.begin(), movingRange.end(), kernelRange.begin(), 0.0 ) / denomIt.Get(); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have to admit I could not get optimal performance when using std::inner_product at https://github.com/InsightSoftwareConsortium/ITK/blob/master/Modules/Core/ImageFunction/include/itkGaussianDerivativeImageFunction.hxx#L219, so instead I just manually wrote the inner product calculation in a few lines of code. In this case, it might look as follows: |
||
|
|
||
| // Why does this happen? Bug? Funky floating point behavior? | ||
| if( normXcorr < negativeOne ) | ||
| { | ||
| metricIt.Set( negativeOne ); | ||
| } | ||
| else if ( normXcorr > positiveOne ) | ||
| { | ||
| metricIt.Set( positiveOne ); | ||
| } | ||
| else | ||
| { | ||
| metricIt.Set( normXcorr ); | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it really intended that the kernel is set on a new location (denomIt.GetIndex()) with every iteration?