00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef __itkCannyEdgeDetectionImageFilter_h
00018 #define __itkCannyEdgeDetectionImageFilter_h
00019
00020 #include "itkImageToImageFilter.h"
00021 #include "itkImage.h"
00022 #include "itkConstNeighborhoodIterator.h"
00023 #include "itkConstSmartNeighborhoodIterator.h"
00024 #include "itkZeroFluxNeumannBoundaryCondition.h"
00025 #include "itkMultiThreader.h"
00026 #include "itkDerivativeOperator.h"
00027
00028 namespace itk
00029 {
00070 template<class TInputImage, class TOutputImage>
00071 class ITK_EXPORT CannyEdgeDetectionImageFilter
00072 : public ImageToImageFilter<TInputImage, TOutputImage>
00073 {
00074 public:
00076 typedef CannyEdgeDetectionImageFilter Self;
00077 typedef ImageToImageFilter<TInputImage, TOutputImage> Superclass;
00078
00080 typedef TInputImage InputImageType;
00081 typedef TOutputImage OutputImageType;
00082
00084 typedef SmartPointer<Self> Pointer;
00085 typedef SmartPointer<const Self> ConstPointer;
00086
00088 typedef typename TInputImage::PixelType InputImagePixelType;
00089 typedef typename TOutputImage::PixelType OutputImagePixelType;
00090
00093 typedef ZeroFluxNeumannBoundaryCondition<OutputImageType>
00094 DefaultBoundaryConditionType;
00095
00099 typedef ConstNeighborhoodIterator<OutputImageType> NeighborhoodType;
00100
00103 typedef ConstSmartNeighborhoodIterator<OutputImageType,
00104 DefaultBoundaryConditionType> BoundaryNeighborhoodType;
00105
00107 itkNewMacro(Self);
00108
00110 typedef typename TOutputImage::RegionType OutputImageRegionType;
00111
00113 itkTypeMacro(CannyEdgeDetectionImageFilter, ImageToImageFilter);
00114
00116 itkStaticConstMacro(ImageDimension, unsigned int,
00117 TInputImage::ImageDimension);
00118
00120 itkSetVectorMacro(Variance, double, ImageDimension);
00121 itkGetVectorMacro(Variance, const double, ImageDimension);
00122 itkSetVectorMacro(MaximumError, double, ImageDimension);
00123 itkGetVectorMacro(MaximumError, const double, ImageDimension);
00124
00127 void SetVariance(const double v)
00128 {
00129 double vArray[ImageDimension];
00130 for (unsigned int i = 0; i<ImageDimension; ++i) { vArray[i] = v; }
00131 this->SetVariance(vArray);
00132 }
00133
00136 void SetMaximumError(const double v)
00137 {
00138 double vArray[ImageDimension];
00139 for (unsigned int i = 0; i<ImageDimension; ++i) { vArray[i] = v; }
00140 this->SetMaximumError(vArray);
00141 }
00142
00143
00144 itkSetMacro(Threshold, OutputImagePixelType );
00145 itkGetMacro(Threshold, OutputImagePixelType);
00146
00147
00148 itkSetMacro(OutsideValue, OutputImagePixelType);
00149 itkGetMacro(OutsideValue, OutputImagePixelType);
00150
00158 virtual void GenerateInputRequestedRegion() throw(InvalidRequestedRegionError);
00159
00160 protected:
00161 CannyEdgeDetectionImageFilter();
00162 CannyEdgeDetectionImageFilter(const Self&) {}
00163 void PrintSelf(std::ostream& os, Indent indent) const;
00164
00165 void GenerateData();
00166
00167 private:
00168 virtual ~CannyEdgeDetectionImageFilter(){};
00169
00171 struct CannyThreadStruct
00172 {
00173 CannyEdgeDetectionImageFilter *Filter;
00174 };
00175
00177 void AllocateUpdateBuffer();
00178
00179
00183 void Compute2ndDerivative();
00184
00193
00194
00195
00201 void ThreadedCompute2ndDerivative(const OutputImageRegionType&
00202 outputRegionForThread, int threadId);
00203
00207 static ITK_THREAD_RETURN_TYPE
00208 Compute2ndDerivativeThreaderCallback( void * arg );
00209
00213 OutputImagePixelType ComputeCannyEdge(const NeighborhoodType &it,
00214 void *globalData );
00215
00219 OutputImagePixelType ComputeCannyEdge(const BoundaryNeighborhoodType &bit,
00220 void *globalData );
00221
00226 void Compute2ndDerivativePos();
00227
00233 void ThreadedCompute2ndDerivativePos(const OutputImageRegionType&
00234 outputRegionForThread, int threadId);
00235
00239 static ITK_THREAD_RETURN_TYPE
00240 Compute2ndDerivativePosThreaderCallback( void *arg );
00241
00243 double m_Variance[ImageDimension];
00244
00247 double m_MaximumError[ImageDimension];
00248
00250 OutputImagePixelType m_Threshold;
00251
00253 OutputImagePixelType m_OutsideValue;
00254
00256 typename OutputImageType::Pointer m_UpdateBuffer;
00257 typename OutputImageType::Pointer m_UpdateBuffer1;
00258
00261 DerivativeOperator<OutputImagePixelType,itkGetStaticConstMacro(ImageDimension)>
00262 m_ComputeCannyEdge1stDerivativeOper;
00263 DerivativeOperator<OutputImagePixelType,itkGetStaticConstMacro(ImageDimension)>
00264 m_ComputeCannyEdge2ndDerivativeOper;
00265
00266 std::slice m_ComputeCannyEdgeSlice[ImageDimension];
00267
00268 unsigned long m_Stride[ImageDimension];
00269 unsigned long m_Center;
00270 };
00271
00272 }
00273
00274 #ifndef ITK_MANUAL_INSTANTIATION
00275 #include "itkCannyEdgeDetectionImageFilter.txx"
00276 #endif
00277
00278 #endif
00279