Medical Imaging Interaction Toolkit  2018.4.99-389bf124
Medical Imaging Interaction Toolkit
mitkRandomImageSampler.cpp
Go to the documentation of this file.
1 /*============================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center (DKFZ)
6 All rights reserved.
7 
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
10 
11 ============================================================================*/
12 
13 #include "mitkRandomImageSampler.h"
14 #include <itkBilateralImageFilter.h>
15 #include "mitkImageAccessByItk.h"
16 #include "mitkImageCast.h"
17 #include "itkUnaryFunctorImageFilter.h"
18 #include <itkImageRandomNonRepeatingIteratorWithIndex.h>
19 #include "itkImageDuplicator.h"
20 
21 mitk::RandomImageSampler::RandomImageSampler()
22  : m_AcceptanceRate(0.1), m_SamplingMode(RandomImageSamplerMode::SINGLE_ACCEPTANCE_RATE)
23 {
24  //default parameters DomainSigma: 2 , RangeSigma: 50, AutoKernel: true, KernelRadius: 1
25 }
26 
27 mitk::RandomImageSampler::~RandomImageSampler()
28 {
29 }
30 
31 template< class TInput, class TOutput>
32 class RandomlySampleFunctor
33 {
34 public:
35  RandomlySampleFunctor() {};
36  ~RandomlySampleFunctor() {};
37  bool operator!=(const RandomlySampleFunctor &) const
38  {
39  return false;
40  }
41  bool operator==(const RandomlySampleFunctor & other) const
42  {
43  return !(*this != other);
44  }
45  inline TOutput operator()(const TInput & A) const
46  {
47  if (rand() < RAND_MAX*m_AcceptanceRate)
48  return A;
49  else
50  return TOutput(0);
51  }
52 
53  double m_AcceptanceRate = 0.1;
54 };
55 
56 template< class TInput, class TOutput>
57 class RandomlySampleClassDependedFunctor
58 {
59 public:
60  RandomlySampleClassDependedFunctor() {};
61  ~RandomlySampleClassDependedFunctor() {};
62  bool operator!=(const RandomlySampleClassDependedFunctor &) const
63  {
64  return false;
65  }
66  bool operator==(const RandomlySampleClassDependedFunctor & other) const
67  {
68  return !(*this != other);
69  }
70  inline TOutput operator()(const TInput & A) const
71  {
72  std::size_t index = static_cast<std::size_t>(A + 0.5);
73  double samplingRate = 0;
74  if (index >= 0 && index < m_SamplingRateVector.size())
75  {
76  samplingRate = m_SamplingRateVector[index];
77  }
78 
79  if (rand() < RAND_MAX*samplingRate)
80  return A;
81  else
82  return TOutput(0);
83  }
84 
85  std::vector<double> m_SamplingRateVector;
86 };
87 
88 void mitk::RandomImageSampler::GenerateData()
89 {
90  mitk::Image::ConstPointer inputImage = this->GetInput(0);
91  switch (m_SamplingMode)
92  {
94  AccessByItk(inputImage.GetPointer(), ItkImageProcessing);
95  break;
97  AccessByItk(inputImage.GetPointer(), ItkImageProcessingClassDependendSampling);
98  break;
100  AccessByItk(inputImage.GetPointer(), ItkImageProcessingFixedNumberSampling);
101  break;
103  AccessByItk(inputImage.GetPointer(), ItkImageProcessingClassDependendNumberSampling);
104  break;
105  default:
106  AccessByItk(inputImage.GetPointer(), ItkImageProcessing);
107  break;
108  }
109 }
110 
111 template<typename TPixel, unsigned int VImageDimension>
112 void mitk::RandomImageSampler::ItkImageProcessing( const itk::Image<TPixel,VImageDimension>* itkImage )
113 {
114  //ITK Image type given from the input image
115  typedef itk::Image< TPixel, VImageDimension > ItkImageType;
116  //bilateral filter with same type
117  typedef RandomlySampleFunctor< typename ItkImageType::PixelType,
118  typename ItkImageType::PixelType> LocalSampleFunctorType;
119  typedef itk::UnaryFunctorImageFilter<ItkImageType, ItkImageType, LocalSampleFunctorType > RandomImageSamplerType;
120  typename RandomImageSamplerType::Pointer RandomImageSampler = RandomImageSamplerType::New();
121  RandomImageSampler->SetInput(itkImage);
122 
123  LocalSampleFunctorType functor;
124  functor.m_AcceptanceRate = m_AcceptanceRate;
125  RandomImageSampler->SetFunctor(functor);
126  RandomImageSampler->GetFunctor().m_AcceptanceRate = m_AcceptanceRate;
127  RandomImageSampler->Update();
128 
129 
130  //get Pointer to output image
131  mitk::Image::Pointer resultImage = this->GetOutput();
132  //write into output image
133  mitk::CastToMitkImage(RandomImageSampler->GetOutput(), resultImage);
134 }
135 
136 template<typename TPixel, unsigned int VImageDimension>
137 void mitk::RandomImageSampler::ItkImageProcessingClassDependendSampling(const itk::Image<TPixel, VImageDimension>* itkImage)
138 {
139  //ITK Image type given from the input image
140  typedef itk::Image< TPixel, VImageDimension > ItkImageType;
141  //bilateral filter with same type
142  typedef RandomlySampleClassDependedFunctor< typename ItkImageType::PixelType,
143  typename ItkImageType::PixelType> LocalSampleFunctorType;
144  typedef itk::UnaryFunctorImageFilter<ItkImageType, ItkImageType, LocalSampleFunctorType > RandomImageSamplerType;
145  typename RandomImageSamplerType::Pointer RandomImageSampler = RandomImageSamplerType::New();
146  RandomImageSampler->SetInput(itkImage);
147 
148  LocalSampleFunctorType functor;
149  functor.m_SamplingRateVector = m_AcceptanceRateVector;
150  RandomImageSampler->SetFunctor(functor);
151  RandomImageSampler->GetFunctor().m_SamplingRateVector = m_AcceptanceRateVector;
152  RandomImageSampler->Update();
153 
154 
155  //get Pointer to output image
156  mitk::Image::Pointer resultImage = this->GetOutput();
157  //write into output image
158  mitk::CastToMitkImage(RandomImageSampler->GetOutput(), resultImage);
159 }
160 
161 template<typename TPixel, unsigned int VImageDimension>
162 void mitk::RandomImageSampler::ItkImageProcessingFixedNumberSampling(const itk::Image<TPixel, VImageDimension>* itkImage)
163 {
164  //ITK Image type given from the input image
165  typedef itk::Image< TPixel, VImageDimension > ItkImageType;
166  typedef itk::ImageDuplicator< ItkImageType > DuplicatorType;
167  typedef itk::ImageRandomNonRepeatingIteratorWithIndex <ItkImageType> IteratorType;
168 
169  typename DuplicatorType::Pointer duplicator = DuplicatorType::New();
170  duplicator->SetInputImage(itkImage);
171  duplicator->Update();
172  typename ItkImageType::Pointer clonedImage = duplicator->GetOutput();
173 
174  //clonedImage->FillBuffer(0);
175  std::vector<unsigned int> counts;
176  IteratorType iter(clonedImage, clonedImage->GetLargestPossibleRegion());
177  iter.SetNumberOfSamples(clonedImage->GetLargestPossibleRegion().GetNumberOfPixels());
178  //iter.GoToBegin();
179  while (!iter.IsAtEnd())
180  {
181  std::size_t index = static_cast<std::size_t>(iter.Value() + 0.5);
182  while (index >= counts.size())
183  {
184  counts.push_back(0);
185  }
186  if (counts[index] < m_NumberOfSamples)
187  {
188  //clonedImage->SetPixel(iter.GetIndex(), iter.Value());
189  counts[index] += 1;
190  }
191  else
192  {
193  iter.Set(0.0);
194  //clonedImage->SetPixel(iter.GetIndex(), 0.0);
195  }
196 
197  ++iter;
198  }
199 
200  //get Pointer to output image
201  mitk::Image::Pointer resultImage = this->GetOutput();
202  //write into output image
203  mitk::CastToMitkImage(clonedImage, resultImage);
204 }
205 
206 template<typename TPixel, unsigned int VImageDimension>
207 void mitk::RandomImageSampler::ItkImageProcessingClassDependendNumberSampling(const itk::Image<TPixel, VImageDimension>* itkImage)
208 {
209  //ITK Image type given from the input image
210  typedef itk::Image< TPixel, VImageDimension > ItkImageType;
211  typedef itk::ImageDuplicator< ItkImageType > DuplicatorType;
212  typedef itk::ImageRandomNonRepeatingIteratorWithIndex<ItkImageType> IteratorType;
213 
214  typename DuplicatorType::Pointer duplicator = DuplicatorType::New();
215  duplicator->SetInputImage(itkImage);
216  duplicator->Update();
217  typename ItkImageType::Pointer clonedImage = duplicator->GetOutput();
218 
219  std::vector<unsigned int> counts;
220  IteratorType iter(clonedImage, clonedImage->GetLargestPossibleRegion());
221  iter.SetNumberOfSamples(clonedImage->GetLargestPossibleRegion().GetNumberOfPixels());
222  while (!iter.IsAtEnd())
223  {
224  std::size_t index = static_cast<std::size_t>(iter.Value() + 0.5);
225  if (index < m_NumberOfSamplesVector.size())
226  {
227  while (index >= counts.size())
228  {
229  counts.push_back(0);
230  }
231 
232  if (counts[index] < m_NumberOfSamplesVector[index])
233  {
234  counts[index] += 1;
235  }
236  else
237  {
238  iter.Set(0.0);
239  }
240  }
241  else
242  {
243  iter.Set(0.0);
244  }
245 
246  ++iter;
247  }
248 
249  //get Pointer to output image
250  mitk::Image::Pointer resultImage = this->GetOutput();
251  //write into output image
252  mitk::CastToMitkImage(clonedImage, resultImage);
253 }
254 
255 
256 void mitk::RandomImageSampler::GenerateOutputInformation()
257 {
258  mitk::Image::Pointer inputImage = (mitk::Image*) this->GetInput();
259  mitk::Image::Pointer output = this->GetOutput();
260  itkDebugMacro(<<"GenerateOutputInformation()");
261  if(inputImage.IsNull()) return;
262 }
MITKCORE_EXPORT bool operator!=(const InteractionEvent &a, const InteractionEvent &b)
MITKCORE_EXPORT bool operator==(const InteractionEvent &a, const InteractionEvent &b)
const BaseData * GetInput() const override
Get the input data set via SetInput().
Image class for storing images.
Definition: mitkImage.h:72
#define AccessByItk(mitkImage, itkImageTypeFunction)
Access a MITK image by an ITK image.
void CastToMitkImage(const itk::SmartPointer< ItkOutputImageType > &itkimage, itk::SmartPointer< mitk::Image > &mitkoutputimage)
Cast an itk::Image (with a specific type) to an mitk::Image.
Definition: mitkImageCast.h:74