21 #ifndef otbLineDetectorImageFilterBase_hxx
22 #define otbLineDetectorImageFilterBase_hxx
26 #include "itkDataObject.h"
28 #include "itkConstantPadImageFilter.h"
29 #include "itkConstNeighborhoodIterator.h"
30 #include "itkNeighborhoodInnerProduct.h"
31 #include "itkImageRegionIterator.h"
32 #include "itkNeighborhoodAlgorithm.h"
33 #include "itkProgressReporter.h"
43 template <
class TInputImage,
class TOutputImage,
class TOutputImageDirection,
class InterpolatorType>
46 this->SetNumberOfRequiredOutputs(2);
47 this->SetNumberOfRequiredOutputs(1);
52 m_NumberOfDirections = 4;
60 template <
class TInputImage,
class TOutputImage,
class TOutputImageDirection,
class InterpolatorType>
64 Superclass::GenerateInputRequestedRegion();
67 typename Superclass::InputImagePointer inputPtr =
const_cast<TInputImage*
>(this->GetInput());
68 typename Superclass::OutputImagePointer outputPtr = this->GetOutput();
70 if (!inputPtr || !outputPtr)
77 typename TInputImage::RegionType inputRequestedRegion;
78 inputRequestedRegion = inputPtr->GetRequestedRegion();
81 m_Radius[1] =
static_cast<unsigned int>(3 * (2 * m_WidthLine + 1) + 2);
82 m_Radius[0] = 2 * m_LengthLine + 1;
85 m_FaceList[0] =
static_cast<unsigned int>(std::sqrt(
static_cast<double>((m_Radius[0] * m_Radius[0]) + (m_Radius[1] * m_Radius[1]))) + 1);
86 m_FaceList[1] = m_FaceList[0];
88 otbMsgDevMacro(<<
"Radius : " << m_Radius[0] <<
" " << m_Radius[1]);
89 otbMsgDevMacro(<<
"-> FaceList : " << m_FaceList[0] <<
" " << m_FaceList[1]);
92 inputRequestedRegion.PadByRadius(m_FaceList);
95 if (inputRequestedRegion.Crop(inputPtr->GetLargestPossibleRegion()))
97 inputPtr->SetRequestedRegion(inputRequestedRegion);
106 inputPtr->SetRequestedRegion(inputRequestedRegion);
109 itk::InvalidRequestedRegionError e(__FILE__, __LINE__);
110 std::ostringstream msg;
111 msg << static_cast<const char*>(this->GetNameOfClass()) <<
"::GenerateInputRequestedRegion()";
112 e.SetLocation(msg.str());
113 e.SetDescription(
"Requested region is (at least partially) outside the largest possible region.");
114 e.SetDataObject(inputPtr);
124 template <
class TInputImage,
class TOutputImage,
class TOutputImageDirection,
class InterpolatorType>
127 typename OutputImageType::Pointer output = this->GetOutput();
128 output->FillBuffer(0);
129 typename OutputImageType::Pointer outputDirection = this->GetOutputDirection();
130 outputDirection->FillBuffer(0);
133 template <
class TInputImage,
class TOutputImage,
class TOutputImageDirection,
class InterpolatorType>
138 typename InputImageType::ConstPointer input = this->GetInput();
141 interpolator2->SetInputImage(input);
143 itk::ZeroFluxNeumannBoundaryCondition<InputImageType> nbc;
144 itk::ConstNeighborhoodIterator<InputImageType> bit, cit;
145 typename itk::ConstNeighborhoodIterator<InputImageType>::OffsetType off;
146 itk::ImageRegionIterator<OutputImageType> it;
147 itk::ImageRegionIterator<OutputImageType> itdir;
150 typename OutputImageType::Pointer output = this->GetOutput();
151 typename OutputImageType::Pointer outputDir = this->GetOutputDirection();
154 typename itk::NeighborhoodAlgorithm::ImageBoundaryFacesCalculator<InputImageType>::FaceListType faceList;
155 typename itk::NeighborhoodAlgorithm::ImageBoundaryFacesCalculator<InputImageType>::FaceListType::iterator fit;
157 itk::NeighborhoodAlgorithm::ImageBoundaryFacesCalculator<InputImageType> bC;
158 faceList = bC(input, outputRegionForThread, m_FaceList);
161 itk::ProgressReporter progress(
this, threadId, outputRegionForThread.GetNumberOfPixels());
163 typename TInputImage::IndexType bitIndex;
164 typename InterpolatorType::ContinuousIndexType Index;
169 const unsigned int NB_DIR = this->GetNumberOfDirections();
171 const int NB_ZONE = 3;
175 double* Theta =
new double[NB_DIR];
178 for (
unsigned int i = 0; i < NB_DIR; ++i)
180 Theta[i] = (
CONST_PI * (i / double(NB_DIR)));
194 double Direction = 0.;
209 otbMsgDevMacro(<<
"Theta : " << Theta[0] <<
" " << Theta[1] <<
" " << Theta[2] <<
" " << Theta[3]);
216 for (fit = faceList.begin(); fit != faceList.end(); ++fit)
218 bit = itk::ConstNeighborhoodIterator<InputImageType>(m_Radius, input, *fit);
219 cit = itk::ConstNeighborhoodIterator<InputImageType>(m_FaceList, input, *fit);
221 it = itk::ImageRegionIterator<OutputImageType>(output, *fit);
222 itdir = itk::ImageRegionIterator<OutputImageType>(outputDir, *fit);
224 bit.OverrideBoundaryCondition(&nbc);
226 cit.OverrideBoundaryCondition(&nbc);
229 otbMsgDevMacro(<<
" ------------------- FaceList --------------------------");
231 while ((!bit.IsAtEnd()) && (!cit.IsAtEnd()))
236 bitIndex = bit.GetIndex(off);
250 typename InputImageType::RegionType tempRegion;
251 typename InputImageType::SizeType tempSize;
252 tempSize[0] = 2 * m_FaceList[0] + 1;
253 tempSize[1] = 2 * m_FaceList[1] + 1;
254 tempRegion.SetSize(tempSize);
255 typename itk::ConstNeighborhoodIterator<InputImageType>::OffsetType tempIndex;
256 tempIndex[0] = off[0] - m_FaceList[0];
257 tempIndex[1] = off[1] - m_FaceList[1];
258 tempRegion.SetIndex(cit.GetIndex(tempIndex));
259 typename InputImageType::Pointer tempImage = InputImageType::New();
260 tempImage->SetRegions(tempRegion);
261 tempImage->Allocate();
263 for (
unsigned int p = 0; p <= 2 * m_FaceList[0]; ++p)
265 for (
unsigned int q = 0; q <= 2 * m_FaceList[1]; q++)
267 typename itk::ConstNeighborhoodIterator<InputImageType>::OffsetType index;
268 index[0] = p - m_FaceList[0];
269 index[1] = q - m_FaceList[1];
270 tempImage->SetPixel(cit.GetIndex(index), cit.GetPixel(index));
273 interpolator->SetInputImage(tempImage);
277 Yc12 = Yc - m_WidthLine - 1;
280 Yc13 = Yc + m_WidthLine + 1;
285 std::vector<double>** PixelValues =
nullptr;
286 PixelValues =
new std::vector<double>*[NB_DIR];
287 for (
unsigned int i = 0; i < NB_DIR; ++i)
289 PixelValues[i] =
nullptr;
290 PixelValues[i] =
new std::vector<double>[NB_ZONE];
294 for (
unsigned int i = 0; i < m_Radius[0]; ++i)
295 for (
unsigned int j = 0; j < m_Radius[1]; ++j)
298 off[0] = i - m_Radius[0] / 2;
299 off[1] = j - m_Radius[1] / 2;
301 bitIndex = bit.GetIndex(off);
308 else if ((Yc12 < Y) && (Y < Yc13))
316 for (
unsigned int dir = 0; dir < NB_DIR; ++dir)
320 xout = (X - Xc) * std::cos(Theta[dir]) - (Y - Yc) * std::sin(Theta[dir]);
321 yout = (X - Xc) * std::sin(Theta[dir]) + (Y - Yc) * std::cos(Theta[dir]);
326 PixelValues[dir][zone].push_back(
static_cast<double>(interpolator->EvaluateAtContinuousIndex(Index)));
335 for (
unsigned int dir = 0; dir < NB_DIR; ++dir)
338 double Rtemp = this->ComputeMeasure(&PixelValues[dir][0], &PixelValues[dir][1], &PixelValues[dir][2]);
343 Direction = Theta[dir];
349 if (R >= this->GetThreshold())
361 it.Set(itk::NumericTraits<OutputPixelType>::Zero);
370 progress.CompletedPixel();
373 for (
unsigned int i = 0; i < NB_DIR; ++i)
375 delete[] PixelValues[i];
376 PixelValues[i] =
nullptr;
378 delete[] PixelValues;
379 PixelValues =
nullptr;
385 template <
class TInputImage,
class TOutputImage,
class TOutputImageDirection,
class InterpolatorType>
387 std::vector<double>* itkNotUsed(m2),
388 std::vector<double>* itkNotUsed(m3))
396 template <
class TInputImage,
class TOutputImage,
class TOutputImageDirection,
class InterpolatorType>
399 Superclass::PrintSelf(os, indent);
400 os << indent <<
"Length: " << m_LengthLine << std::endl;
401 os << indent <<
"Width: " << m_WidthLine << std::endl;