17 #ifndef __itkBinaryMorphologyImageFilter_txx
18 #define __itkBinaryMorphologyImageFilter_txx
24 #include "itkConfigure.h"
26 #ifdef ITK_USE_CONSOLIDATED_MORPHOLOGY
45 template <
class TInputImage,
class TOutputImage,
class TKernel>
56 template <
class TInputImage,
class TOutputImage,
class TKernel>
62 Superclass::GenerateInputRequestedRegion();
66 const_cast< TInputImage *
>( this->GetInput() );
75 typename TInputImage::RegionType inputRequestedRegion;
76 inputRequestedRegion = inputPtr->GetRequestedRegion();
82 for (
unsigned int i=0; i < KernelDimension; ++i)
85 (padBy[i]>m_Kernel.GetRadius(i) ? padBy[i] : m_Kernel.GetRadius(i));
87 inputRequestedRegion.PadByRadius( padBy );
90 if ( inputRequestedRegion.Crop(inputPtr->GetLargestPossibleRegion()) )
92 inputPtr->SetRequestedRegion( inputRequestedRegion );
101 inputPtr->SetRequestedRegion( inputRequestedRegion );
104 InvalidRequestedRegionError e(__FILE__, __LINE__);
106 e.
SetDescription(
"Requested region is (at least partially) outside the largest possible region.");
113 template<
class TInputImage,
class TOutputImage,
class TKernel>
122 this->AnalyzeKernel();
126 template<
class TInputImage,
class TOutputImage,
class TKernel>
132 m_KernelDifferenceSets.clear();
133 m_KernelCCVector.clear();
135 std::vector<unsigned int> kernelOnElements;
145 unsigned long kernelSize = m_Kernel.Size();
146 unsigned long kernelCenter = kernelSize / 2;
148 for( i = kernelCenter + 1, k = kernelCenter - 1; i < kernelSize; ++i, --k )
150 typename TKernel::PixelType px = m_Kernel.GetBufferReference()[i];
151 m_Kernel.GetBufferReference()[i] = m_Kernel.GetBufferReference()[k];
152 m_Kernel.GetBufferReference()[k] = px;
162 for ( i=0, kernel_it=KernelBegin; kernel_it != KernelEnd; ++kernel_it, ++i)
166 kernelOnElements.push_back(i);
175 for( i = 0; i < TInputImage::ImageDimension; ++i )
178 centerElementPosition[i] = m_Kernel.GetSize(i) / 2;
189 typename BoolImageType::Pointer tmpSEImage = BoolImageType::New();
190 tmpSEImage->SetRegions( m_Kernel.GetSize() );
193 tmpSEImage->Allocate();
198 tmpSEImage->GetRequestedRegion());
201 kernel_it = KernelBegin;
203 while( !kernelImageIt.
IsAtEnd() )
205 kernelImageIt.
Set( *kernel_it ?
true :
false);
219 kernelImageItIndex(tmpSEImage, tmpSEImage->GetRequestedRegion());
223 SEoNeighbIt( m_Radius, tmpSEImage, tmpSEImage->GetRequestedRegion());
225 unsigned int neighborhoodSize = SEoNeighbIt.Size();
229 std::queue<IndexType> propagQueue;
232 m_KernelCCVector.clear();
237 kernel_it = KernelBegin;
238 kernelImageItIndex.GoToBegin();
239 while( !kernelImageItIndex.IsAtEnd() )
242 if( kernelImageItIndex.Get() )
245 kernelImageItIndex.Set(
false );
248 propagQueue.push( kernelImageItIndex.GetIndex() );
252 OffsetType offset = m_Kernel.GetOffset(kernel_it - KernelBegin);
253 m_KernelCCVector.push_back( offset );
256 while ( !propagQueue.empty() )
259 IndexType currentIndex = propagQueue.front();
263 SEoNeighbIt.GoToBegin();
264 SEoNeighbIt.SetLocation( currentIndex );
266 for (i = 0; i < neighborhoodSize; ++i)
269 if( SEoNeighbIt.GetPixel(i) )
273 SEoNeighbIt.SetPixel(i,
false, bIsBounds);
276 propagQueue.push( SEoNeighbIt.GetIndex(i) );
283 ++kernelImageItIndex;
288 tmpSEImage->Initialize();
306 m_KernelDifferenceSets.resize( adjNeigh.
Size() );
310 for( i = 0; i < adjNeigh.
Size(); ++i )
312 m_KernelDifferenceSets[i].clear();
315 std::vector<unsigned int>::const_iterator kernelOnElementsIt;
316 for( kernelOnElementsIt = kernelOnElements.begin();
317 kernelOnElementsIt != kernelOnElements.end(); ++kernelOnElementsIt )
320 k = *kernelOnElementsIt;
326 OffsetType currentOffset = m_Kernel.GetOffset(k);
327 IndexType currentShiftedPosition = centerElementPosition + currentOffset;
331 currentShiftedPosition += adjNeigh.
GetOffset(i);
338 bool bIsOutside =
false;
339 for(
unsigned int dimCount = 0;
340 dimCount < TInputImage::ImageDimension; ++dimCount )
342 if( currentShiftedPosition[dimCount] < 0
343 || currentShiftedPosition[dimCount] >=
344 (
int)m_Kernel.GetSize(dimCount) )
356 m_KernelDifferenceSets[i].push_back(currentOffset);
369 unsigned int currentRelativeIndexOffset
370 = m_Kernel.GetNeighborhoodIndex( adjNeigh.
GetOffset(i) )
371 - m_Kernel.GetCenterNeighborhoodIndex();
375 unsigned int currentShiftedIndex
376 = k + currentRelativeIndexOffset;
381 if( m_Kernel[currentShiftedIndex] <= 0 )
384 m_KernelDifferenceSets[i].push_back(currentOffset);
395 unsigned int centerKernelIndex = adjNeigh.
Size() / 2;
396 for ( k=0, kernel_it=KernelBegin; kernel_it != KernelEnd; ++kernel_it, ++k)
400 OffsetType currentOffset = m_Kernel.GetOffset(k);
401 m_KernelDifferenceSets[centerKernelIndex].push_back(currentOffset);
410 template <
class TInputImage,
class TOutput,
class TKernel>
415 Superclass::PrintSelf( os, indent );
416 os << indent <<
"Radius: " << m_Radius << std::endl;
417 os << indent <<
"Kernel: " << m_Kernel << std::endl;
420 os << indent <<
"BoundaryToForeground: " << m_BoundaryToForeground << std::endl;