Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkImageSource.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,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 
17 #include "mitkImageSource.h"
18 
21 
23 {
24  // Create the output. We use static_cast<> here because we know the default
25  // output must be of type TOutputImage
26  OutputImageType::Pointer output = static_cast<OutputImageType *>(this->MakeOutput(0).GetPointer());
27  Superclass::SetNumberOfRequiredOutputs(1);
28  Superclass::SetNthOutput(0, output.GetPointer());
29 }
30 
31 itk::DataObject::Pointer mitk::ImageSource::MakeOutput(DataObjectPointerArraySizeType /*idx*/)
32 {
33  return static_cast<itk::DataObject *>(mitk::Image::New().GetPointer());
34 }
35 
37 {
38  itkDebugMacro("MakeOutput(" << name << ")");
39  if (this->IsIndexedOutputName(name))
40  {
41  return this->MakeOutput(this->MakeIndexFromOutputName(name));
42  }
43  return static_cast<itk::DataObject *>(mitk::Image::New().GetPointer());
44 }
45 
46 //----------------------------------------------------------------------------
47 unsigned int mitk::ImageSource::SplitRequestedRegion(unsigned int i,
48  unsigned int num,
49  OutputImageRegionType &splitRegion)
50 {
51  // Get the output pointer
52  OutputImageType *outputPtr = this->GetOutput();
53  const SlicedData::SizeType &requestedRegionSize = outputPtr->GetRequestedRegion().GetSize();
54 
55  int splitAxis;
56  SlicedData::IndexType splitIndex;
57  SlicedData::SizeType splitSize;
58 
59  // Initialize the splitRegion to the output requested region
60  splitRegion = outputPtr->GetRequestedRegion();
61  splitIndex = splitRegion.GetIndex();
62  splitSize = splitRegion.GetSize();
63 
64  // split on the outermost dimension available
65  splitAxis = outputPtr->GetDimension() - 1;
66  while (requestedRegionSize[splitAxis] == 1)
67  {
68  --splitAxis;
69  if (splitAxis < 0)
70  { // cannot split
71  itkDebugMacro(" Cannot Split");
72  return 1;
73  }
74  }
75 
76  // determine the actual number of pieces that will be generated
77  SlicedData::SizeType::SizeValueType range = requestedRegionSize[splitAxis];
78  unsigned int valuesPerThread = itk::Math::Ceil<unsigned int>(range / (double)num);
79  unsigned int maxThreadIdUsed = itk::Math::Ceil<unsigned int>(range / (double)valuesPerThread) - 1;
80 
81  // Split the region
82  if (i < maxThreadIdUsed)
83  {
84  splitIndex[splitAxis] += i * valuesPerThread;
85  splitSize[splitAxis] = valuesPerThread;
86  }
87  if (i == maxThreadIdUsed)
88  {
89  splitIndex[splitAxis] += i * valuesPerThread;
90  // last thread needs to process the "rest" dimension being split
91  splitSize[splitAxis] = splitSize[splitAxis] - i * valuesPerThread;
92  }
93 
94  // set the split region ivars
95  splitRegion.SetIndex(splitIndex);
96  splitRegion.SetSize(splitSize);
97 
98  itkDebugMacro(" Split Piece: " << splitRegion);
99 
100  return maxThreadIdUsed + 1;
101 }
102 
103 //----------------------------------------------------------------------------
104 
106 {
107  OutputImagePointer outputPtr;
108 
109  // Allocate the output memory
110  for (unsigned int i = 0; i < this->GetNumberOfOutputs(); i++)
111  {
112  outputPtr = this->GetOutput(i);
113  // outputPtr->SetBufferedRegion(outputPtr->GetRequestedRegion()); @FIXME???
114  // outputPtr->Allocate(); @FIXME???
115  }
116 }
117 
118 //----------------------------------------------------------------------------
119 
121 {
122  // Call a method that can be overriden by a subclass to allocate
123  // memory for the filter's outputs
124  this->AllocateOutputs();
125 
126  // Call a method that can be overridden by a subclass to perform
127  // some calculations prior to splitting the main computations into
128  // separate threads
129  this->BeforeThreadedGenerateData();
130 
131  // Set up the multithreaded processing
132  ThreadStruct str;
133  str.Filter = this;
134 
135  this->GetMultiThreader()->SetNumberOfThreads(this->GetNumberOfThreads());
136  this->GetMultiThreader()->SetSingleMethod(this->ThreaderCallback, &str);
137 
138  // multithread the execution
139  this->GetMultiThreader()->SingleMethodExecute();
140 
141  // Call a method that can be overridden by a subclass to perform
142  // some calculations after all the threads have completed
143  this->AfterThreadedGenerateData();
144 }
145 
146 //----------------------------------------------------------------------------
147 // The execute method created by the subclass.
148 
150 {
151  itkExceptionMacro("subclass should override this method!!!");
152 }
153 
154 // Callback routine used by the threading library. This routine just calls
155 // the ThreadedGenerateData method after setting the correct region for this
156 // thread.
157 
158 ITK_THREAD_RETURN_TYPE mitk::ImageSource::ThreaderCallback(void *arg)
159 {
160  ThreadStruct *str;
161  itk::ThreadIdType total, threadId, threadCount;
162 
163  threadId = ((itk::MultiThreader::ThreadInfoStruct *)(arg))->ThreadID;
164  threadCount = ((itk::MultiThreader::ThreadInfoStruct *)(arg))->NumberOfThreads;
165 
166  str = (ThreadStruct *)(((itk::MultiThreader::ThreadInfoStruct *)(arg))->UserData);
167 
168  // execute the actual method with appropriate output region
169  // first find out how many pieces extent can be split into.
170  SlicedData::RegionType splitRegion;
171  total = str->Filter->SplitRequestedRegion(threadId, threadCount, splitRegion);
172 
173  if (threadId < total)
174  {
175  str->Filter->ThreadedGenerateData(splitRegion, threadId);
176  }
177  // else
178  // {
179  // otherwise don't use this thread. Sometimes the threads dont
180  // break up very well and it is just as efficient to leave a
181  // few threads idle.
182  // }
183 
184  return ITK_THREAD_RETURN_VALUE;
185 }
186 
188 {
189  Superclass::PrepareOutputs();
190 }
191 
193 {
194  Update();
195  return GetOutput()->GetVtkImageData();
196 }
197 
198 const vtkImageData *mitk::ImageSource::GetVtkImageData() const
199 {
200  return GetOutput()->GetVtkImageData();
201 }
202 
Superclass of all classes generating Images (instances of class Image) as output. ...
itk::DataObject::DataObjectIdentifierType DataObjectIdentifierType
itk::SmartPointer< Self > Pointer
static ITK_THREAD_RETURN_TYPE ThreaderCallback(void *arg)
Static function used as a "callback" by the MultiThreader.
virtual itk::DataObject::Pointer MakeOutput(DataObjectPointerArraySizeType idx) override
Make a DataObject of the correct type to used as the specified output.
virtual vtkImageData * GetVtkImageData()
virtual const RegionType & GetRequestedRegion() const
static void Update(vtkPolyData *)
Definition: mitkSurface.cpp:35
virtual void PrepareOutputs() override
This method is intentionally left blank.
SlicedData::RegionType OutputImageRegionType
virtual void ThreadedGenerateData(const OutputImageRegionType &outputRegionForThread, itk::ThreadIdType threadId)
If an imaging filter can be implemented as a multithreaded algorithm, the filter will provide an impl...
virtual void GenerateData() override
A version of GenerateData() specific for image processing filters.
itk::Size< RegionDimension > SizeType
virtual unsigned int SplitRequestedRegion(unsigned int i, unsigned int num, OutputImageRegionType &splitRegion)
Split the output's RequestedRegion into "num" pieces, returning region "i" as "splitRegion".
Internal structure used for passing image data into the threading library.
itk::ImageRegion< RegionDimension > RegionType
Image class for storing images.
Definition: mitkImage.h:76
static Pointer New()
virtual void AllocateOutputs()
The GenerateData method normally allocates the buffers for all of the outputs of a filter...
unsigned int GetDimension() const
Get dimension of the image.
Definition: mitkImage.cpp:110
#define mitkBaseDataSourceGetOutputDefinitions(className)