21 #ifndef otbTouziEdgeDetectorImageFilter_hxx
22 #define otbTouziEdgeDetectorImageFilter_hxx
26 #include "itkDataObject.h"
27 #include "itkConstNeighborhoodIterator.h"
28 #include "itkNeighborhoodInnerProduct.h"
29 #include "itkImageRegionIterator.h"
30 #include "itkNeighborhoodAlgorithm.h"
31 #include "itkProgressReporter.h"
41 template <
class TInputImage,
class TOutputImage,
class TOutputImageDirection>
47 template <
class TInputImage,
class TOutputImage,
class TOutputImageDirection>
51 Superclass::GenerateInputRequestedRegion();
57 if (!inputPtr || !outputPtr)
64 typename TInputImage::RegionType inputRequestedRegion;
65 inputRequestedRegion = inputPtr->GetRequestedRegion();
68 inputRequestedRegion.PadByRadius(m_Radius);
71 if (inputRequestedRegion.Crop(inputPtr->GetLargestPossibleRegion()))
73 inputPtr->SetRequestedRegion(inputRequestedRegion);
82 inputPtr->SetRequestedRegion(inputRequestedRegion);
85 itk::InvalidRequestedRegionError e(__FILE__, __LINE__);
86 std::ostringstream msg;
87 msg << static_cast<const char*>(this->GetNameOfClass()) <<
"::GenerateInputRequestedRegion()";
88 e.SetLocation(msg.str());
89 e.SetDescription(
"Requested region is (at least partially) outside the largest possible region.");
90 e.SetDataObject(inputPtr);
100 template <
class TInputImage,
class TOutputImage,
class TOutputImageDirection>
104 typename OutputImageDirectionType::RegionType region;
105 typename OutputImageType::Pointer output = this->GetOutput();
109 region.SetSize(output->GetRequestedRegion().GetSize());
110 region.SetIndex(output->GetRequestedRegion().GetIndex());
111 direction->SetRegions(region);
112 direction->SetOrigin(output->GetOrigin());
113 direction->SetSignedSpacing(output->GetSignedSpacing());
114 direction->Allocate();
117 template <
class TInputImage,
class TOutputImage,
class TOutputImageDirection>
119 itk::ThreadIdType threadId)
122 itk::ZeroFluxNeumannBoundaryCondition<InputImageType> nbc;
123 itk::ConstNeighborhoodIterator<InputImageType> bit;
124 itk::ImageRegionIterator<OutputImageType> it;
125 itk::ImageRegionIterator<OutputImageType> it_dir;
128 typename OutputImageType::Pointer output = this->GetOutput();
129 typename InputImageType::ConstPointer input = this->GetInput();
130 typename OutputImageDirectionType::Pointer outputDir = this->GetOutputDirection();
133 typename itk::NeighborhoodAlgorithm::ImageBoundaryFacesCalculator<InputImageType>::FaceListType faceList;
134 typename itk::NeighborhoodAlgorithm::ImageBoundaryFacesCalculator<InputImageType>::FaceListType::iterator fit;
136 itk::NeighborhoodAlgorithm::ImageBoundaryFacesCalculator<InputImageType> bC;
137 faceList = bC(input, outputRegionForThread, m_Radius);
140 itk::ProgressReporter progress(
this, threadId, outputRegionForThread.GetNumberOfPixels());
142 typename TInputImage::IndexType bitIndex;
147 const int NB_DIR = 4;
149 const int NB_REGION = 2;
151 double Theta[NB_DIR];
159 double Sum[NB_DIR][NB_REGION];
165 double R_theta[NB_DIR];
166 double Sum_R_theta = 0.;
170 double Dir_contour = 0.;
185 for (fit = faceList.begin(); fit != faceList.end(); ++fit)
190 bit = itk::ConstNeighborhoodIterator<InputImageType>(m_Radius, input, *fit);
191 unsigned int neighborhoodSize = bit.Size();
193 it = itk::ImageRegionIterator<OutputImageType>(output, *fit);
194 it_dir = itk::ImageRegionIterator<OutputImageDirectionType>(outputDir, *fit);
196 bit.OverrideBoundaryCondition(&nbc);
199 while (!bit.IsAtEnd())
203 bitIndex = bit.GetIndex();
209 for (
int dir = 0; dir < NB_DIR; ++dir)
211 for (
int m = 0; m < NB_REGION; m++)
220 for (i = 0; i < neighborhoodSize; ++i)
223 bitIndex = bit.GetIndex(i);
231 Sum[0][0] +=
static_cast<double>(bit.GetPixel(i));
233 Sum[0][1] +=
static_cast<double>(bit.GetPixel(i));
236 if ((y - yc) < (x - xc))
237 Sum[1][0] +=
static_cast<double>(bit.GetPixel(i));
238 else if ((y - yc) > (x - xc))
239 Sum[1][1] +=
static_cast<double>(bit.GetPixel(i));
243 Sum[2][0] +=
static_cast<double>(bit.GetPixel(i));
245 Sum[2][1] +=
static_cast<double>(bit.GetPixel(i));
248 if ((y - yc) > -(x - xc))
249 Sum[3][0] +=
static_cast<double>(bit.GetPixel(i));
250 else if ((y - yc) < -(x - xc))
251 Sum[3][1] +=
static_cast<double>(bit.GetPixel(i));
256 for (
int dir = 0; dir < NB_DIR; ++dir)
259 M1 = Sum[dir][0] /
static_cast<double>(m_Radius[0] * (2 * m_Radius[0] + 1));
260 M2 = Sum[dir][1] /
static_cast<double>(m_Radius[0] * (2 * m_Radius[0] + 1));
263 if ((M1 != 0) && (M2 != 0))
264 R_theta[dir] =
static_cast<double>(1 - std::min((M1 / M2), (M2 / M1)));
269 R_contour =
static_cast<double>(std::max(R_contour, R_theta[dir]));
277 Dir_contour += sign * Theta[dir] * R_theta[dir];
278 Sum_R_theta += R_theta[dir];
286 if (Sum_R_theta != 0.)
287 Dir_contour = Dir_contour / Sum_R_theta;
295 progress.CompletedPixel();
303 template <
class TInputImage,
class TOutputImage,
class TOutputImageDirection>
306 Superclass::PrintSelf(os, indent);
307 os << indent <<
"Radius: " << m_Radius << std::endl;