[Insight-users] Memory leak in an edge detection filter

Massimo Esposito mass.esposito at gmail.com
Tue Sep 18 05:03:50 EDT 2007


Dear All,

I use an edge detection filter to preprocess medical images before of
segmentation.

Although the filter works, a huge memory leak is detected at line 247 of the
filter source code set at the queue of the mail text.

Could someone help me to overcome that problem?

Thank you in advance

Massimo

///FILTER SOURCE
CODE///////////////////////////////////////////////////////////////////////////////

0

1 #ifndef __EdgePreprocessingFilter_h_

2 #define __EdgePreprocessingFilter_h_

3

4

5

6

7

8 #include "stdafx.h"

9 #include "itkCommand.h"

10 #include "itkCastImageFilter.h"

11 #include "itkDiscreteGaussianImageFilter.h"

12 #include "itkGradientMagnitudeImageFilter.h"

13 #include "itkImageAdaptor.h"

14 #include "itkMinimumMaximumImageCalculator.h"

15 #include "itkProgressAccumulator.h"

16 #include "itkRescaleIntensityImageFilter.h"

17 #include "itkUnaryFunctorImageFilter.h"

18 #include "EdgePreprocessingSettings.h"

19

20

21 /**

22 * The g() function that remaps the gradient magnitude image to the

23 * range 0 to 1.

24 */

25 template<class TInput, class TOutput>

26 class EdgeRemappingFunctor

27 {

28 public:

29 typedef EdgeRemappingFunctor<TInput, TOutput> Self;

30

31 void SetParameters(float intensityMin, float intensityMax,

32 float exponent, float kappa)

33 {

34 m_KappaFactor = 1.0f / kappa;

35 m_Exponent = exponent;

36 m_IntensityBase = intensityMin;

37 m_IntensityScale = 1.0f / (intensityMax - intensityMin);

38 }

39

40 inline TOutput operator()(const TInput &x)

41 {

42 float xNorm = (static_cast<float>(x)-m_IntensityBase)*m_IntensityScale;

43 float y = 1.0f / (1.0f + pow(xNorm * m_KappaFactor,m_Exponent));

44 return static_cast<TOutput> (y);

45 }

46

47 bool operator ==(const Self &z)

48 {

49 return

50 m_KappaFactor == z.m_KappaFactor &&

51 m_IntensityBase == z.m_IntensityBase &&

52 m_IntensityScale == z.m_IntensityScale &&

53 m_Exponent == z.m_Exponent;

54 }

55

56 bool operator !=(const Self &z)

57 { return !(*this == z); }

58

59 private:

60

61 float m_KappaFactor;

62 float m_IntensityBase;

63 float m_IntensityScale;

64 float m_Exponent;

65 };

66

67 /**

68 * \class EdgePreprocessingImageFilter

69 * \brief A filter used for edge preprocessing of images.

70 *

71 * This functor implements a Gaussian blur, followed by a gradient
magnitude

72 * operator, followed by a 'contrast enhancement' intensity remapping
filter.

73 */

74 template <typename TInputImage,typename TOutputImage = TInputImage>

75 class EdgePreprocessingImageFilter:

76 public itk::ImageToImageFilter<TInputImage,TOutputImage>

77 {

78 public:

79 //typedef vnl_vector_fixed<float,3> Vector3f;

80

81 /** Standard class typedefs. */

82 typedef EdgePreprocessingImageFilter Self;

83 typedef itk::ImageToImageFilter<TInputImage,TOutputImage> Superclass;

84 typedef itk::SmartPointer<Self> Pointer;

85 typedef itk::SmartPointer<const Self> ConstPointer;

86

87 /** Pixel Type of the input image */

88 typedef TInputImage InputImageType;

89 typedef typename InputImageType::PixelType InputPixelType;

90 typedef itk::SmartPointer<InputImageType> InputImagePointer;

91

92 /** Pixel Type of the output image */

93 typedef TOutputImage OutputImageType;

94 typedef typename OutputImageType::PixelType OutputPixelType;

95 typedef itk::SmartPointer<OutputImageType> OutputImagePointer;

96

97 /** Type used for internal calculations */

98 typedef float RealType;

99 typedef itk::Image<RealType,3> InternalImageType;

100 typedef itk::SmartPointer<InternalImageType> InternalImagePointer;

101

102 /** Functor type used for thresholding */

103 typedef EdgeRemappingFunctor<RealType,OutputPixelType> FunctorType;

104

105 /** Method for creation through the object factory. */

106 itkNewMacro(Self)

107

108 /** Image dimension. */

109 itkStaticConstMacro(ImageDimension, unsigned int,

110 TInputImage::ImageDimension);

111

112 /** Assign new edge processing settings */

113 void SetEdgePreprocessingSettings(const EdgePreprocessingSettings
&settings);

114

115

116 protected:

117

118 EdgePreprocessingImageFilter();

119 virtual ~EdgePreprocessingImageFilter() {};

120 void PrintSelf(std::ostream& os, itk::Indent indent) const;

121

122 /** Generate Data */

123 void GenerateData( void );

124

125 /**

126 * This method maps an input region to an output region. It's necessary
to

127 * reflect the way this filter pads the requested region

128 */

129 void GenerateInputRequestedRegion();

130

131 private:

132

133 /** The unary functor filter type used for remapping */

134 typedef itk::UnaryFunctorImageFilter<

135 InternalImageType,TOutputImage,FunctorType> RemappingFilterType;

136 typedef typename RemappingFilterType::Pointer RemappingFilterPointer;

137

138 /** The min / max calculator used to compute gradient range */

139 typedef itk::MinimumMaximumImageCalculator<

140 InternalImageType> CalculatorType;

141 typedef typename CalculatorType::Pointer CalculatorPointer;

142

143 /** Adaptor used to cast to float */

144 typedef itk::CastImageFilter<

145 InputImageType,InternalImageType> CastFilterType;

146 typedef typename CastFilterType::Pointer CastFilterPointer;

147

148 /** Gaussian smoothing filter */

149 typedef itk::DiscreteGaussianImageFilter<

150 InternalImageType,InternalImageType> GaussianFilterType;

151 typedef typename GaussianFilterType::Pointer GaussianFilterPointer;

152

153 /** Gradient magnitude filter */

154 typedef itk::GradientMagnitudeImageFilter<

155 InternalImageType,InternalImageType> GradientFilterType;

156 typedef typename GradientFilterType::Pointer GradientFilterPointer;

157

158 /** Intensity rescaling filter */

159 typedef itk::RescaleIntensityImageFilter<

160 InternalImageType,InternalImageType> RescaleFilterType;

161 typedef typename RescaleFilterType::Pointer RescaleFilterPointer;

162

163 /** Progress accumulator object */

164 typedef itk::ProgressAccumulator::Pointer AccumulatorPointer;

165

166 CastFilterPointer m_CastFilter;

167 RemappingFilterPointer m_RemappingFilter;

168 GaussianFilterPointer m_GaussianFilter;

169 GradientFilterPointer m_GradientFilter;

170 CalculatorPointer m_Calculator;

171 RescaleFilterPointer m_RescaleFilter;

172

173 EdgePreprocessingSettings m_EdgePreprocessingSettings;

174

175 /** Progress tracking object */

176 AccumulatorPointer m_ProgressAccumulator;

177

178 };

179

180 #ifndef ITK_MANUAL_INSTANTIATION

181 //#include "EdgePreprocessingImageFilter.txx"

182

183 using namespace itk;

184

185 template<typename TInputImage,typename TOutputImage>

186 EdgePreprocessingImageFilter<TInputImage,TOutputImage>

187 ::EdgePreprocessingImageFilter()

188 {

189

190 // Construct the adaptor

191 m_CastFilter = CastFilterType::New();

192 m_CastFilter->ReleaseDataFlagOn();

193 m_CastFilter->SetInput(this->GetInput());

194

195 // Construct the Gaussian filter

196 m_GaussianFilter = GaussianFilterType::New();

197 m_GaussianFilter->SetUseImageSpacing(false);

198 m_GaussianFilter->ReleaseDataFlagOn();

199 m_GaussianFilter->SetInput(m_CastFilter->GetOutput());

200

201 // The gradient magnitude filter

202 m_GradientFilter = GradientFilterType::New();

203 m_GradientFilter->ReleaseDataFlagOn();

204 m_GradientFilter->SetInput(m_GaussianFilter->GetOutput());

205

206 // The normalization filter

207 m_RescaleFilter = RescaleFilterType::New();

208 m_RescaleFilter->ReleaseDataFlagOn();

209 m_RescaleFilter->SetOutputMinimum(0.0f);

210 m_RescaleFilter->SetOutputMaximum(1.0f);

211 m_RescaleFilter->SetInput(m_GradientFilter->GetOutput());

212

213 // Construct the Remapping filter

214 m_RemappingFilter = RemappingFilterType::New();

215 m_RemappingFilter->ReleaseDataFlagOn();

216 m_RemappingFilter->SetInput(m_RescaleFilter->GetOutput());

217

218 // Create the progress accumulator

219 m_ProgressAccumulator = itk::ProgressAccumulator::New();

220 m_ProgressAccumulator->SetMiniPipelineFilter(this);

221

222 // Register the filters with the progress accumulator

223 m_ProgressAccumulator->RegisterInternalFilter(m_CastFilter,0.1f);

224 m_ProgressAccumulator->RegisterInternalFilter(m_GaussianFilter,0.6f);

225 m_ProgressAccumulator->RegisterInternalFilter(m_GradientFilter,0.1f);

226 m_ProgressAccumulator->RegisterInternalFilter(m_RescaleFilter,0.1f);

227 m_ProgressAccumulator->RegisterInternalFilter(m_RemappingFilter,0.1f);

228 }

229

230 template<typename TInputImage,typename TOutputImage>

231 void

232 EdgePreprocessingImageFilter<TInputImage,TOutputImage>

233 ::GenerateData()

234 {

235 // Get the input and output pointers

236 const typename InputImageType::ConstPointer inputImage =
this->GetInput();

237 typename OutputImageType::Pointer outputImage = this->GetOutput();

238

239 // Initialize the progress counter

240 m_ProgressAccumulator->ResetProgress();

241

242 // Allocate the output image

243 outputImage->SetBufferedRegion(outputImage->GetRequestedRegion());

244 outputImage->Allocate();

245

246 // Pipe in the input image

247 m_CastFilter->SetInput(inputImage); //Here the memory leak is detected!!

248

249

250 // Set the variance

251 Vector3f variance(

252 m_EdgePreprocessingSettings.GetGaussianBlurScale() *

253 m_EdgePreprocessingSettings.GetGaussianBlurScale());

254 m_GaussianFilter->SetVariance(variance.data_block());

255

256 // Construct the functor

257 FunctorType functor;

258 functor.SetParameters(0.0f,1.0f,

259 m_EdgePreprocessingSettings.GetRemappingExponent(),

260 m_EdgePreprocessingSettings.GetRemappingSteepness());

261

262 // Assign the functor to the filter

263 m_RemappingFilter->SetFunctor(functor);

264

265 // Call the filter's GenerateData()

266 m_RemappingFilter->GraftOutput(outputImage);

267 m_RemappingFilter->Update();

268

269 // graft the mini-pipeline output back onto this filter's output.

270 // this is needed to get the appropriate regions passed back.

271 GraftOutput( m_RemappingFilter->GetOutput() );

272

273 }

274

275 template<typename TInputImage,typename TOutputImage>

276 void

277 EdgePreprocessingImageFilter<TInputImage,TOutputImage>

278 ::PrintSelf(std::ostream& os, Indent indent) const

279 {

280 Superclass::PrintSelf(os,indent);

281 }

282

283 template<typename TInputImage,typename TOutputImage>

284 void

285 EdgePreprocessingImageFilter<TInputImage,TOutputImage>

286 ::SetEdgePreprocessingSettings(const EdgePreprocessingSettings
&settings)

287 {

288 if(!(settings == m_EdgePreprocessingSettings))

289 {

290 m_EdgePreprocessingSettings = settings;

291 this->Modified();

292 }

293 }

294

295 template<typename TInputImage,typename TOutputImage>

296 void

297 EdgePreprocessingImageFilter<TInputImage,TOutputImage>

298 ::GenerateInputRequestedRegion()

299 {

300 // Make sure we call the parent's implementation

301 Superclass::GenerateInputRequestedRegion();

302

303 // Get pointers to the input and output

304 InputImagePointer inputPtr =

305 const_cast< TInputImage * >( this->GetInput() );

306 OutputImagePointer outputPtr = this->GetOutput();

307

308 // Use the largest possible region (hack)

309 inputPtr->SetRequestedRegion(

310 inputPtr->GetLargestPossibleRegion());

311 }

312

313 #endif

314

315 #endif // __EdgePreprocessingFilter_h_

316
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://public.kitware.com/pipermail/insight-users/attachments/20070918/b995bb94/attachment.htm


More information about the Insight-users mailing list