/*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile: itkCountImageFilter.txx,v $ Language: C++ Date: $Date: 2006/01/11 19:43:31 $ Version: $Revision: 1.14 $ Copyright (c) Insight Software Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _itkCountImageFilter_txx #define _itkCountImageFilter_txx #include "itkCountImageFilter.h" #include "itkConstNeighborhoodIterator.h" #include "itkNeighborhoodInnerProduct.h" #include "itkImageRegionIterator.h" #include "itkNeighborhoodAlgorithm.h" #include "itkZeroFluxNeumannBoundaryCondition.h" #include "itkOffset.h" #include "itkProgressReporter.h" namespace itk { template CountImageFilter ::CountImageFilter() { m_Radius.Fill(1); } template void CountImageFilter ::GenerateInputRequestedRegion() throw (InvalidRequestedRegionError) { // call the superclass' implementation of this method Superclass::GenerateInputRequestedRegion(); // get pointers to the input and output typename Superclass::InputImagePointer inputPtr = const_cast< TInputImage * >( this->GetInput() ); typename Superclass::OutputImagePointer outputPtr = this->GetOutput(); if ( !inputPtr || !outputPtr ) { return; } // get a copy of the input requested region (should equal the output // requested region) typename TInputImage::RegionType inputRequestedRegion; inputRequestedRegion = inputPtr->GetRequestedRegion(); // pad the input requested region by the operator radius inputRequestedRegion.PadByRadius( m_Radius ); // crop the input requested region at the input's largest possible region if ( inputRequestedRegion.Crop(inputPtr->GetLargestPossibleRegion()) ) { inputPtr->SetRequestedRegion( inputRequestedRegion ); return; } else { // Couldn't crop the region (requested region is outside the largest // possible region). Throw an exception. // store what we tried to request (prior to trying to crop) inputPtr->SetRequestedRegion( inputRequestedRegion ); // build an exception InvalidRequestedRegionError e(__FILE__, __LINE__); e.SetLocation(ITK_LOCATION); e.SetDescription("Requested region is (at least partially) outside the largest possible region."); e.SetDataObject(inputPtr); throw e; } } template< class TInputImage, class TOutputImage> void CountImageFilter< TInputImage, TOutputImage> ::ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread, int threadId) { unsigned int i; ZeroFluxNeumannBoundaryCondition nbc; ConstNeighborhoodIterator bit; ImageRegionIterator it; // Allocate output typename OutputImageType::Pointer output = this->GetOutput(); typename InputImageType::ConstPointer input = this->GetInput(); // Find the data-set boundary "faces" typename NeighborhoodAlgorithm::ImageBoundaryFacesCalculator::FaceListType faceList; NeighborhoodAlgorithm::ImageBoundaryFacesCalculator bC; faceList = bC(input, outputRegionForThread, m_Radius); typename NeighborhoodAlgorithm::ImageBoundaryFacesCalculator::FaceListType::iterator fit; // support progress methods/callbacks ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels()); InputRealType sum; // Process each of the boundary faces. These are N-d regions which border // the edge of the buffer. for (fit=faceList.begin(); fit != faceList.end(); ++fit) { bit = ConstNeighborhoodIterator(m_Radius, input, *fit); unsigned int neighborhoodSize = bit.Size(); it = ImageRegionIterator(output, *fit); bit.OverrideBoundaryCondition(&nbc); bit.GoToBegin(); while ( ! bit.IsAtEnd() ) { sum = NumericTraits::Zero; for (i = 0; i < neighborhoodSize; ++i) { if(bit.GetPixel(i)) sum++; //sum += static_cast( bit.GetPixel(i) ); } // get the Count value it.Set( static_cast(sum)); ++bit; ++it; progress.CompletedPixel(); } } } /** * Standard "PrintSelf" method */ template void CountImageFilter ::PrintSelf( std::ostream& os, Indent indent) const { Superclass::PrintSelf( os, indent ); os << indent << "Radius: " << m_Radius << std::endl; } } // end namespace itk #endif