Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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)