ITK  4.8.0
Insight Segmentation and Registration Toolkit
itkBoxUtilities.h
Go to the documentation of this file.
1 /*=========================================================================
2  *
3  * Copyright Insight Software Consortium
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0.txt
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *=========================================================================*/
18 #ifndef itkBoxUtilities_h
19 #define itkBoxUtilities_h
20 #include "itkProgressReporter.h"
22 #include "itkImageRegionIterator.h"
25 #include "itkImageRegionIterator.h"
26 #include "itkOffset.h"
30 
31 /*
32  *
33  * This code was contributed in the Insight Journal paper:
34  * "Efficient implementation of kernel filtering"
35  * by Beare R., Lehmann G
36  * http://hdl.handle.net/1926/555
37  * http://www.insight-journal.org/browse/publication/160
38  *
39  */
40 
41 
42 namespace itk
43 {
44 template< typename TIterator >
45 TIterator *
46 setConnectivityEarlyBox(TIterator *it, bool fullyConnected = false)
47 {
48  // activate the "previous" neighbours
49  typename TIterator::OffsetType offset;
50  it->ClearActiveList();
51  if ( !fullyConnected )
52  {
53  // only activate the neighbors that are face connected
54  // to the current pixel. do not include the center pixel
55  offset.Fill(0);
56  for ( unsigned int d = 0; d < TIterator::Dimension; ++d )
57  {
58  offset[d] = -1;
59  it->ActivateOffset(offset);
60  offset[d] = 0;
61  }
62  }
63  else
64  {
65  // activate all neighbors that are face+edge+vertex
66  // connected to the current pixel. do not include the center pixel
67  unsigned int centerIndex = it->GetCenterNeighborhoodIndex();
68  for ( unsigned int d = 0; d < centerIndex; d++ )
69  {
70  offset = it->GetOffset(d);
71  // check for positives in any dimension
72  bool keep = true;
73  for ( unsigned int i = 0; i < TIterator::Dimension; i++ )
74  {
75  if ( offset[i] > 0 )
76  {
77  keep = false;
78  break;
79  }
80  }
81  if ( keep )
82  {
83  it->ActivateOffset(offset);
84  }
85  }
86  offset.Fill(0);
87  it->DeactivateOffset(offset);
88  }
89  return it;
90 }
91 
92 template< typename TInputImage, typename TOutputImage >
93 void
94 BoxAccumulateFunction(const TInputImage *inputImage,
95  const TOutputImage *outputImage,
96  typename TInputImage::RegionType inputRegion,
97  typename TOutputImage::RegionType outputRegion,
98  ProgressReporter & progress)
99 {
100  // typedefs
101  typedef TInputImage InputImageType;
102  typedef typename TInputImage::OffsetType OffsetType;
103  typedef TOutputImage OutputImageType;
104  typedef typename TOutputImage::PixelType OutputPixelType;
105 
106  typedef ImageRegionConstIterator< TInputImage > InputIterator;
107 
108  typedef ShapedNeighborhoodIterator< TOutputImage > NOutputIterator;
109  InputIterator inIt(inputImage, inputRegion);
110  typename TInputImage::SizeType kernelRadius;
111  kernelRadius.Fill(1);
112 
113  NOutputIterator noutIt(kernelRadius, outputImage, outputRegion);
114  // this iterator is fully connected
115  setConnectivityEarlyBox(&noutIt, true);
116 
119  noutIt.OverrideBoundaryCondition(&oBC);
120  // This uses several iterators. An alternative and probably better
121  // approach would be to copy the input to the output and convolve
122  // with the following weights (in 2D)
123  // -(dim - 1) 1
124  // 1 1
125  // The result of each convolution needs to get written back to the
126  // image being convolved so that the accumulation propagates
127  // This should be implementable with neighborhood operators.
128 
129  std::vector< int > Weights;
130  typename NOutputIterator::ConstIterator sIt;
131  for ( typename NOutputIterator::IndexListType::const_iterator idxIt = noutIt.GetActiveIndexList().begin();
132  idxIt != noutIt.GetActiveIndexList().end();
133  idxIt++ )
134  {
135  OffsetType offset = noutIt.GetOffset(*idxIt);
136  int w = -1;
137  for ( unsigned int k = 0; k < InputImageType::ImageDimension; k++ )
138  {
139  if ( offset[k] != 0 )
140  {
141  w *= offset[k];
142  }
143  }
144 // std::cout << offset << " " << w << std::endl;
145  Weights.push_back(w);
146  }
147 
148  for ( inIt.GoToBegin(), noutIt.GoToBegin(); !noutIt.IsAtEnd(); ++inIt, ++noutIt )
149  {
150  OutputPixelType Sum = 0;
151  int k;
152  for ( k = 0, sIt = noutIt.Begin(); !sIt.IsAtEnd(); ++sIt, ++k )
153  {
154  Sum += sIt.Get() * Weights[k];
155  }
156  noutIt.SetCenterPixel( Sum + inIt.Get() );
157  progress.CompletedPixel();
158  }
159 }
160 
161 // a function to generate corners of arbitrary dimension box
162 template< typename ImType >
163 std::vector< typename ImType::OffsetType > CornerOffsets(const ImType *im)
164 {
165  typedef ShapedNeighborhoodIterator< ImType > NIterator;
166  typename ImType::SizeType unitradius;
167  unitradius.Fill(1);
168  NIterator N1( unitradius, im, im->GetRequestedRegion() );
169  unsigned int centerIndex = N1.GetCenterNeighborhoodIndex();
170  typename NIterator::OffsetType offset;
171  std::vector< typename ImType::OffsetType > result;
172  for ( unsigned int d = 0; d < centerIndex * 2 + 1; d++ )
173  {
174  offset = N1.GetOffset(d);
175  // check whether this is a corner - corners have no zeros
176  bool corner = true;
177  for ( unsigned int k = 0; k < ImType::ImageDimension; k++ )
178  {
179  if ( offset[k] == 0 )
180  {
181  corner = false;
182  break;
183  }
184  }
185  if ( corner )
186  {
187  result.push_back(offset);
188  }
189  }
190  return ( result );
191 }
192 
193 template< typename TInputImage, typename TOutputImage >
194 void
195 BoxMeanCalculatorFunction(const TInputImage *accImage,
196  TOutputImage *outputImage,
197  typename TInputImage::RegionType inputRegion,
198  typename TOutputImage::RegionType outputRegion,
199  typename TInputImage::SizeType Radius,
200  ProgressReporter & progress)
201 {
202  // typedefs
203  typedef TInputImage InputImageType;
204  typedef typename TInputImage::RegionType RegionType;
205  typedef typename TInputImage::SizeType SizeType;
206  typedef typename TInputImage::IndexType IndexType;
207  typedef typename TInputImage::OffsetType OffsetType;
208  typedef TOutputImage OutputImageType;
209  typedef typename TOutputImage::PixelType OutputPixelType;
210  // use the face generator for speed
212  typedef typename FaceCalculatorType::FaceListType FaceListType;
213  typedef typename FaceCalculatorType::FaceListType::iterator FaceListTypeIt;
214  FaceCalculatorType faceCalculator;
215 
216  FaceListType faceList;
217  FaceListTypeIt fit;
219 
220  // this process is actually slightly asymmetric because we need to
221  // subtract rectangles that are next to our kernel, not overlapping it
222  SizeType kernelSize;
223  SizeType internalRadius;
224  SizeType RegionLimit;
225 
226  IndexType RegionStart = inputRegion.GetIndex();
227  for ( unsigned int i = 0; i < TInputImage::ImageDimension; i++ )
228  {
229  kernelSize[i] = Radius[i] * 2 + 1;
230  internalRadius[i] = Radius[i] + 1;
231  RegionLimit[i] = inputRegion.GetSize()[i] + RegionStart[i] - 1;
232  }
233 
234  typedef typename NumericTraits< OutputPixelType >::RealType AccPixType;
235  // get a set of offsets to corners for a unit hypercube in this image
236  std::vector< OffsetType > UnitCorners = CornerOffsets< TInputImage >(accImage);
237  std::vector< OffsetType > RealCorners;
238  std::vector< AccPixType > Weights;
239  // now compute the weights
240  for ( unsigned int k = 0; k < UnitCorners.size(); k++ )
241  {
242  int prod = 1;
243  OffsetType ThisCorner;
244  for ( unsigned int i = 0; i < TInputImage::ImageDimension; i++ )
245  {
246  prod *= UnitCorners[k][i];
247  if ( UnitCorners[k][i] > 0 )
248  {
249  ThisCorner[i] = Radius[i];
250  }
251  else
252  {
253  ThisCorner[i] = -( Radius[i] + 1 );
254  }
255  }
256  Weights.push_back( (AccPixType)prod );
257  RealCorners.push_back(ThisCorner);
258  }
259 
260  faceList = faceCalculator(accImage, outputRegion, internalRadius);
261  // start with the body region
262  for ( fit = faceList.begin(); fit != faceList.end(); ++fit )
263  {
264  if ( fit == faceList.begin() )
265  {
266  // this is the body region. This is meant to be an optimized
267  // version that doesn't use neighborhood regions
268  // compute the various offsets
269  AccPixType pixelscount = 1;
270  for ( unsigned int i = 0; i < TInputImage::ImageDimension; i++ )
271  {
272  pixelscount *= (AccPixType)( 2 * Radius[i] + 1 );
273  }
274 
275  typedef ImageRegionIterator< OutputImageType > OutputIteratorType;
276  typedef ImageRegionConstIterator< InputImageType > InputIteratorType;
277 
278  typedef std::vector< InputIteratorType > CornerItVecType;
279  CornerItVecType CornerItVec;
280  // set up the iterators for each corner
281  for ( unsigned int k = 0; k < RealCorners.size(); k++ )
282  {
283  typename InputImageType::RegionType tReg = ( *fit );
284  tReg.SetIndex(tReg.GetIndex() + RealCorners[k]);
285  InputIteratorType tempIt(accImage, tReg);
286  tempIt.GoToBegin();
287  CornerItVec.push_back(tempIt);
288  }
289  // set up the output iterator
290  OutputIteratorType oIt(outputImage, *fit);
291  // now do the work
292  for ( oIt.GoToBegin(); !oIt.IsAtEnd(); ++oIt )
293  {
294  AccPixType Sum = 0;
295  // check each corner
296  for ( unsigned int k = 0; k < CornerItVec.size(); k++ )
297  {
298  Sum += Weights[k] * CornerItVec[k].Get();
299  // increment each corner iterator
300  ++( CornerItVec[k] );
301  }
302  oIt.Set( static_cast< OutputPixelType >( Sum / pixelscount ) );
303  progress.CompletedPixel();
304  }
305  }
306  else
307  {
308  // now we need to deal with the border regions
309  typedef ImageRegionIteratorWithIndex< OutputImageType > OutputIteratorType;
310  OutputIteratorType oIt(outputImage, *fit);
311  // now do the work
312  for ( oIt.GoToBegin(); !oIt.IsAtEnd(); ++oIt )
313  {
314  // figure out the number of pixels in the box by creating an
315  // equivalent region and cropping - this could probably be
316  // included in the loop below.
317  RegionType currentKernelRegion;
318  currentKernelRegion.SetSize(kernelSize);
319  // compute the region's index
320  IndexType kernelRegionIdx = oIt.GetIndex();
321  IndexType CentIndex = kernelRegionIdx;
322  for ( unsigned int i = 0; i < TInputImage::ImageDimension; i++ )
323  {
324  kernelRegionIdx[i] -= Radius[i];
325  }
326  currentKernelRegion.SetIndex(kernelRegionIdx);
327  currentKernelRegion.Crop(inputRegion);
328  OffsetValueType edgepixelscount = currentKernelRegion.GetNumberOfPixels();
329  AccPixType Sum = 0;
330  // rules are : for each corner,
331  // for each dimension
332  // if dimension offset is positive -> this is
333  // a leading edge. Crop if outside the input
334  // region
335  // if dimension offset is negative -> this is
336  // a trailing edge. Ignore if it is outside
337  // image region
338  for ( unsigned int k = 0; k < RealCorners.size(); k++ )
339  {
340  IndexType ThisCorner = CentIndex + RealCorners[k];
341  bool IncludeCorner = true;
342  for ( unsigned int j = 0; j < TInputImage::ImageDimension; j++ )
343  {
344  if ( UnitCorners[k][j] > 0 )
345  {
346  // leading edge - crop it
347  if ( ThisCorner[j] > static_cast< OffsetValueType >( RegionLimit[j] ) )
348  {
349  ThisCorner[j] = static_cast< OffsetValueType >( RegionLimit[j] );
350  }
351  }
352  else
353  {
354  // trailing edge - check bounds
355  if ( ThisCorner[j] < RegionStart[j] )
356  {
357  IncludeCorner = false;
358  break;
359  }
360  }
361  }
362  if ( IncludeCorner )
363  {
364  Sum += accImage->GetPixel(ThisCorner) * Weights[k];
365  }
366  }
367 
368  oIt.Set( static_cast< OutputPixelType >( Sum / (AccPixType)edgepixelscount ) );
369  progress.CompletedPixel();
370  }
371  }
372  }
373 }
374 
375 template< typename TInputImage, typename TOutputImage >
376 void
377 BoxSigmaCalculatorFunction(const TInputImage *accImage,
378  TOutputImage *outputImage,
379  typename TInputImage::RegionType inputRegion,
380  typename TOutputImage::RegionType outputRegion,
381  typename TInputImage::SizeType Radius,
382  ProgressReporter & progress)
383 {
384  // typedefs
385  typedef TInputImage InputImageType;
386  typedef typename TInputImage::RegionType RegionType;
387  typedef typename TInputImage::SizeType SizeType;
388  typedef typename TInputImage::IndexType IndexType;
389  typedef typename TInputImage::OffsetType OffsetType;
390  typedef TOutputImage OutputImageType;
391  typedef typename TOutputImage::PixelType OutputPixelType;
392  typedef typename TInputImage::PixelType InputPixelType;
393  // use the face generator for speed
395  typedef typename FaceCalculatorType::FaceListType FaceListType;
396  typedef typename FaceCalculatorType::FaceListType::iterator FaceListTypeIt;
397  FaceCalculatorType faceCalculator;
398 
399  FaceListType faceList;
400  FaceListTypeIt fit;
402 
403  // this process is actually slightly asymmetric because we need to
404  // subtract rectangles that are next to our kernel, not overlapping it
405  SizeType kernelSize;
406  SizeType internalRadius;
407  SizeType RegionLimit;
408  IndexType RegionStart = inputRegion.GetIndex();
409  for ( unsigned int i = 0; i < TInputImage::ImageDimension; i++ )
410  {
411  kernelSize[i] = Radius[i] * 2 + 1;
412  internalRadius[i] = Radius[i] + 1;
413  RegionLimit[i] = inputRegion.GetSize()[i] + RegionStart[i] - 1;
414  }
415 
416  typedef typename NumericTraits< OutputPixelType >::RealType AccPixType;
417  // get a set of offsets to corners for a unit hypercube in this image
418  std::vector< OffsetType > UnitCorners = CornerOffsets< TInputImage >(accImage);
419  std::vector< OffsetType > RealCorners;
420  std::vector< AccPixType > Weights;
421  // now compute the weights
422  for ( unsigned int k = 0; k < UnitCorners.size(); k++ )
423  {
424  int prod = 1;
425  OffsetType ThisCorner;
426  for ( unsigned int i = 0; i < TInputImage::ImageDimension; i++ )
427  {
428  prod *= UnitCorners[k][i];
429  if ( UnitCorners[k][i] > 0 )
430  {
431  ThisCorner[i] = Radius[i];
432  }
433  else
434  {
435  ThisCorner[i] = -( Radius[i] + 1 );
436  }
437  }
438  Weights.push_back( (AccPixType)prod );
439  RealCorners.push_back(ThisCorner);
440  }
441 
442  faceList = faceCalculator(accImage, outputRegion, internalRadius);
443  // start with the body region
444  for ( fit = faceList.begin(); fit != faceList.end(); ++fit )
445  {
446  if ( fit == faceList.begin() )
447  {
448  // this is the body region. This is meant to be an optimized
449  // version that doesn't use neighborhood regions
450  // compute the various offsets
451  AccPixType pixelscount = 1;
452  for ( unsigned int i = 0; i < TInputImage::ImageDimension; i++ )
453  {
454  pixelscount *= (AccPixType)( 2 * Radius[i] + 1 );
455  }
456 
457  typedef ImageRegionIterator< OutputImageType > OutputIteratorType;
458  typedef ImageRegionConstIterator< InputImageType > InputIteratorType;
459 
460  typedef std::vector< InputIteratorType > CornerItVecType;
461  CornerItVecType CornerItVec;
462  // set up the iterators for each corner
463  for ( unsigned int k = 0; k < RealCorners.size(); k++ )
464  {
465  typename InputImageType::RegionType tReg = ( *fit );
466  tReg.SetIndex(tReg.GetIndex() + RealCorners[k]);
467  InputIteratorType tempIt(accImage, tReg);
468  tempIt.GoToBegin();
469  CornerItVec.push_back(tempIt);
470  }
471  // set up the output iterator
472  OutputIteratorType oIt(outputImage, *fit);
473  // now do the work
474  for ( oIt.GoToBegin(); !oIt.IsAtEnd(); ++oIt )
475  {
476  AccPixType Sum = 0;
477  AccPixType SquareSum = 0;
478  // check each corner
479  for ( unsigned int k = 0; k < CornerItVec.size(); k++ )
480  {
481  const InputPixelType & i = CornerItVec[k].Get();
482  Sum += Weights[k] * i[0];
483  SquareSum += Weights[k] * i[1];
484  // increment each corner iterator
485  ++( CornerItVec[k] );
486  }
487 
488  oIt.Set( static_cast< OutputPixelType >( std::sqrt( ( SquareSum - Sum * Sum / pixelscount ) / ( pixelscount - 1 ) ) ) );
489  progress.CompletedPixel();
490  }
491  }
492  else
493  {
494  // now we need to deal with the border regions
495  typedef ImageRegionIteratorWithIndex< OutputImageType > OutputIteratorType;
496  OutputIteratorType oIt(outputImage, *fit);
497  // now do the work
498  for ( oIt.GoToBegin(); !oIt.IsAtEnd(); ++oIt )
499  {
500  // figure out the number of pixels in the box by creating an
501  // equivalent region and cropping - this could probably be
502  // included in the loop below.
503  RegionType currentKernelRegion;
504  currentKernelRegion.SetSize(kernelSize);
505  // compute the region's index
506  IndexType kernelRegionIdx = oIt.GetIndex();
507  IndexType CentIndex = kernelRegionIdx;
508  for ( unsigned int i = 0; i < TInputImage::ImageDimension; i++ )
509  {
510  kernelRegionIdx[i] -= Radius[i];
511  }
512  currentKernelRegion.SetIndex(kernelRegionIdx);
513  currentKernelRegion.Crop(inputRegion);
514  SizeValueType edgepixelscount = currentKernelRegion.GetNumberOfPixels();
515  AccPixType Sum = 0;
516  AccPixType SquareSum = 0;
517  // rules are : for each corner,
518  // for each dimension
519  // if dimension offset is positive -> this is
520  // a leading edge. Crop if outside the input
521  // region
522  // if dimension offset is negative -> this is
523  // a trailing edge. Ignore if it is outside
524  // image region
525  for ( unsigned int k = 0; k < RealCorners.size(); k++ )
526  {
527  IndexType ThisCorner = CentIndex + RealCorners[k];
528  bool IncludeCorner = true;
529  for ( unsigned int j = 0; j < TInputImage::ImageDimension; j++ )
530  {
531  if ( UnitCorners[k][j] > 0 )
532  {
533  // leading edge - crop it
534  if ( ThisCorner[j] > static_cast< OffsetValueType >( RegionLimit[j] ) )
535  {
536  ThisCorner[j] = static_cast< OffsetValueType >( RegionLimit[j] );
537  }
538  }
539  else
540  {
541  // trailing edge - check bounds
542  if ( ThisCorner[j] < RegionStart[j] )
543  {
544  IncludeCorner = false;
545  break;
546  }
547  }
548  }
549  if ( IncludeCorner )
550  {
551  const InputPixelType & i = accImage->GetPixel(ThisCorner);
552  Sum += Weights[k] * i[0];
553  SquareSum += Weights[k] * i[1];
554  }
555  }
556 
557  oIt.Set( static_cast< OutputPixelType >( std::sqrt( ( SquareSum - Sum * Sum
558  / edgepixelscount ) / ( edgepixelscount - 1 ) ) ) );
559  progress.CompletedPixel();
560  }
561  }
562  }
563 }
564 
565 template< typename TInputImage, typename TOutputImage >
566 void
567 BoxSquareAccumulateFunction(const TInputImage *inputImage,
568  TOutputImage *outputImage,
569  typename TInputImage::RegionType inputRegion,
570  typename TOutputImage::RegionType outputRegion,
571  ProgressReporter & progress)
572 {
573  // typedefs
574  typedef TInputImage InputImageType;
575  typedef typename TInputImage::OffsetType OffsetType;
576  typedef TOutputImage OutputImageType;
577  typedef typename TOutputImage::PixelType OutputPixelType;
578  typedef typename OutputPixelType::ValueType ValueType;
579  typedef typename TInputImage::PixelType InputPixelType;
580 
581  typedef ImageRegionConstIterator< TInputImage > InputIterator;
582 
583  typedef ShapedNeighborhoodIterator< TOutputImage > NOutputIterator;
584  InputIterator inIt(inputImage, inputRegion);
585  typename TInputImage::SizeType kernelRadius;
586  kernelRadius.Fill(1);
587 
588  NOutputIterator noutIt(kernelRadius, outputImage, outputRegion);
589  // this iterator is fully connected
590  setConnectivityEarlyBox(&noutIt, true);
591 
594  noutIt.OverrideBoundaryCondition(&oBC);
595  // This uses several iterators. An alternative and probably better
596  // approach would be to copy the input to the output and convolve
597  // with the following weights (in 2D)
598  // -(dim - 1) 1
599  // 1 1
600  // The result of each convolution needs to get written back to the
601  // image being convolved so that the accumulation propagates
602  // This should be implementable with neighborhood operators.
603 
604  std::vector< int > Weights;
605  typename NOutputIterator::ConstIterator sIt;
606  for ( typename NOutputIterator::IndexListType::const_iterator idxIt = noutIt.GetActiveIndexList().begin();
607  idxIt != noutIt.GetActiveIndexList().end();
608  idxIt++ )
609  {
610  OffsetType offset = noutIt.GetOffset(*idxIt);
611  int w = -1;
612  for ( unsigned int k = 0; k < InputImageType::ImageDimension; k++ )
613  {
614  if ( offset[k] != 0 )
615  {
616  w *= offset[k];
617  }
618  }
619  Weights.push_back(w);
620  }
621 
622  for ( inIt.GoToBegin(), noutIt.GoToBegin(); !noutIt.IsAtEnd(); ++inIt, ++noutIt )
623  {
624  ValueType Sum = 0;
625  ValueType SquareSum = 0;
626  int k;
627  for ( k = 0, sIt = noutIt.Begin(); !sIt.IsAtEnd(); ++sIt, ++k )
628  {
629  const OutputPixelType & v = sIt.Get();
630  Sum += v[0] * Weights[k];
631  SquareSum += v[1] * Weights[k];
632  }
633  OutputPixelType o;
634  const InputPixelType & i = inIt.Get();
635  o[0] = Sum + i;
636  o[1] = SquareSum + i * i;
637  noutIt.SetCenterPixel(o);
638  progress.CompletedPixel();
639  }
640 }
641 } //namespace itk
642 
643 #endif
void BoxSquareAccumulateFunction(const TInputImage *inputImage, TOutputImage *outputImage, typename TInputImage::RegionType inputRegion, typename TOutputImage::RegionType outputRegion, ProgressReporter &progress)
void SetConstant(const OutputPixelType &c)
void BoxSigmaCalculatorFunction(const TInputImage *accImage, TOutputImage *outputImage, typename TInputImage::RegionType inputRegion, typename TOutputImage::RegionType outputRegion, typename TInputImage::SizeType Radius, ProgressReporter &progress)
std::vector< typename ImType::OffsetType > CornerOffsets(const ImType *im)
void SetIndex(const IndexType &ind) override
signed long OffsetValueType
Definition: itkIntTypes.h:154
void BoxMeanCalculatorFunction(const TInputImage *accImage, TOutputImage *outputImage, typename TInputImage::RegionType inputRegion, typename TOutputImage::RegionType outputRegion, typename TInputImage::SizeType Radius, ProgressReporter &progress)
This boundary condition returns a constant value for out-of-bounds image pixels.
unsigned long SizeValueType
Definition: itkIntTypes.h:143
A neighborhood iterator which can take on an arbitrary shape.
Splits an image into a main region and several &quot;face&quot; regions which are used to handle computations o...
A multi-dimensional iterator templated over image type that walks a region of pixels.
A multi-dimensional iterator templated over image type that walks pixels within a region and is speci...
Implements progress tracking for a filter.
TIterator * setConnectivityEarlyBox(TIterator *it, bool fullyConnected=false)
Define additional traits for native types such as int or float.
void BoxAccumulateFunction(const TInputImage *inputImage, const TOutputImage *outputImage, typename TInputImage::RegionType inputRegion, typename TOutputImage::RegionType outputRegion, ProgressReporter &progress)
A multi-dimensional iterator templated over image type that walks a region of pixels.