1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
|
/*=========================================================================
Program: Insight Segmentation & Registration Toolkit
Module: $RCSfile: itkMaskNeighborhoodOperatorImageFilter.txx,v $
Language: C++
Date: $Date: 2006-01-11 19:43:31 $
Version: $Revision: 1.4 $
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 _itkMaskNeighborhoodOperatorImageFilter_txx
#define _itkMaskNeighborhoodOperatorImageFilter_txx
#include "itkMaskNeighborhoodOperatorImageFilter.h"
#include "itkNeighborhoodAlgorithm.h"
#include "itkImageRegionIterator.h"
#include "itkImageRegionConstIterator.h"
#include "itkConstNeighborhoodIterator.h"
#include "itkProgressReporter.h"
namespace itk
{
template< class TInputImage, class TMaskImage, class TOutputImage, class TOperatorValueType>
void
MaskNeighborhoodOperatorImageFilter<TInputImage, TMaskImage, TOutputImage, TOperatorValueType>
::SetMaskImage( const TMaskImage *mask )
{
this->ProcessObject::SetNthInput( 1, const_cast<TMaskImage *>(mask) );
}
template< class TInputImage, class TMaskImage, class TOutputImage, class TOperatorValueType>
const TMaskImage *
MaskNeighborhoodOperatorImageFilter<TInputImage, TMaskImage, TOutputImage, TOperatorValueType>
::GetMaskImage() const
{
return static_cast<MaskImageType*>(const_cast<DataObject *>(this->ProcessObject::GetInput(1)));
}
template <class TInputImage, class TMaskImage, class TOutputImage, class TOperatorValueType>
void
MaskNeighborhoodOperatorImageFilter<TInputImage, TMaskImage, TOutputImage, TOperatorValueType>
::GenerateInputRequestedRegion() throw (InvalidRequestedRegionError)
{
// call the superclass' implementation of this method
Superclass::GenerateInputRequestedRegion();
// Superclass handled the input image, now we just need to handle
// the mask image is any.
InputImagePointer inputPtr =
const_cast< TInputImage * >( this->GetInput() );
MaskImagePointer maskPtr =
const_cast< TMaskImage * >( this->GetMaskImage() );
if ( !inputPtr || !maskPtr )
{
return;
}
// get a copy of the input requested region which was set up by the
// superclass (NeighborhoodOperatorImageFilter)
typename TInputImage::RegionType inputRequestedRegion;
inputRequestedRegion = inputPtr->GetRequestedRegion();
// set the mask requested region to match the input requested region
if ( maskPtr->GetLargestPossibleRegion().IsInside( inputRequestedRegion ) )
{
maskPtr->SetRequestedRegion( inputRequestedRegion );
}
else
{
// Couldn't make the masked region match the input region.
// Throw an exception.
// store what we tried to request
maskPtr->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 of the mask image.");
e.SetDataObject(maskPtr);
throw e;
}
}
template< class TInputImage, class TMaskImage, class TOutputImage, class TOperatorValueType>
void
MaskNeighborhoodOperatorImageFilter<TInputImage, TMaskImage, TOutputImage, TOperatorValueType>
::ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread,
int threadId)
{
// get output/inputs
OutputImageType *output = this->GetOutput();
const InputImageType *input = this->GetInput();
const MaskImageType *mask = this->GetMaskImage();
// If mask is not specified, called the superclass...
if (!mask)
{
Superclass::ThreadedGenerateData(outputRegionForThread, threadId);
return;
}
// Define the inner product algorithm
NeighborhoodInnerProduct<InputImageType, OperatorValueType> smartInnerProduct;
// Break the input into a series of regions. The first region is free
// of boundary conditions, the rest with boundary conditions. Note,
// we pass in the input image and the OUTPUT requested region. We are
// only concerned with centering the neighborhood operator at the
// pixels that correspond to output pixels.
typedef NeighborhoodAlgorithm::ImageBoundaryFacesCalculator<InputImageType>
BFC;
typedef typename BFC::FaceListType FaceListType;
BFC faceCalculator;
FaceListType faceList;
faceList = faceCalculator(input, outputRegionForThread,
this->GetOperator().GetRadius());
// support progress methods/callbacks
ProgressReporter progress(this, threadId,
outputRegionForThread.GetNumberOfPixels());
// Get the operator
OutputNeighborhoodType noperator = this->GetOperator();
// Process non-boundary region and each of the boundary faces.
// These are N-d regions which border the edge of the buffer.
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;
++it;
++mit;
progress.CompletedPixel();
}
}
}
template< class TInputImage, class TMaskImage, class TOutputImage, class TOperatorValueType>
void
MaskNeighborhoodOperatorImageFilter<TInputImage, TMaskImage, TOutputImage, TOperatorValueType>
::PrintSelf(std::ostream& os, Indent indent) const
{
Superclass::PrintSelf(os,indent);
os << indent << "Default value : "
<< static_cast<typename NumericTraits<OutputPixelType>::PrintType>( m_DefaultValue )<< std::endl;
os << indent << "UseDefaultValue : " << m_UseDefaultValue << std::endl;
}
} // end namespace itk
#endif
|