MITK-IGT
IGT Extension of MITK
Loading...
Searching...
No Matches
mitkThreadedToFRawDataReconstruction.cpp
Go to the documentation of this file.
1/*============================================================================
2
3The Medical Imaging Interaction Toolkit (MITK)
4
5Copyright (c) German Cancer Research Center (DKFZ)
6All rights reserved.
7
8Use of this source code is governed by a 3-clause BSD license that can be
9found in the LICENSE file.
10
11============================================================================*/
12// mitk includes
14#include "mitkITKImageImport.h"
15#include "mitkImageDataItem.h"
16
17// stl includes
18#include <iostream>
19#include <string>
20#include <algorithm>
21
22// vtk includes
23#include <vtkLookupTable.h>
24#include <vtkFieldData.h>
25#include <vtkSmartPointer.h>
26
27// itk includes
28#include <itkMultiThreader.h>
29#include <itksys/SystemTools.hxx>
30
31#ifdef WIN32
32#include <winsock2.h>
33#else
34#include <arpa/inet.h>
35#endif
36#include <new>
37
38#define cAir 299704944;
39#define fMod 20000000;
40
41namespace mitk
42{
43
45 m_CISDist(0), m_CISAmpl(0), m_CISInten(0),
46 m_ThreadedCISDist(0), m_ThreadedCISAmpl(0), m_ThreadedCISInten(0),
47 m_Init(0), m_Width(0), m_Height(0), m_SourceDataSize(0), m_ImageSize(0), m_SourceData(0)
48 {
51
52 m_ThreadData->m_ImageDataMutex = itk::FastMutexLock::New();
53 m_ThreadData->m_ThreadDataMutex = itk::FastMutexLock::New();
54
55 m_StackSize = 1;
56 }
57
59 {
60 if(m_ThreadData != nullptr)
61 delete m_ThreadData;
62
63 if(m_CISDist != nullptr)
64 delete[] m_CISDist;
65
66 if(m_CISAmpl != nullptr)
67 delete[] m_CISAmpl;
68
69 if(m_CISInten != nullptr)
70 delete[] m_CISInten;
71
72 if(m_ThreadedCISInten != nullptr)
73 delete[] m_ThreadedCISInten;
74
75 if(m_ThreadedCISAmpl != nullptr)
76 delete[] m_ThreadedCISAmpl;
77
78 if(m_ThreadedCISDist != nullptr)
79 delete[] m_ThreadedCISDist;
80
81 }
82
83void ThreadedToFRawDataReconstruction::Initialize(int width, int height, int modulationFrequency,
84 int sourceDataSize )
85{
86 m_Width = width;
87 m_Height = height;
88 m_SourceDataSize = sourceDataSize;
89 m_ImageSize = width * height;
90 m_ThreadData->m_ModulationFrequency = modulationFrequency * 1e6;
91
92 if(!m_Init)
93 {
94 m_SourceData = vtkShortArray::New();
95 m_SourceData->SetNumberOfComponents(m_SourceDataSize);
96 m_SourceData->SetNumberOfTuples(4);
97 m_SourceData->Allocate(1);
98
99 m_CISDist = new float[m_ImageSize];
100 m_CISAmpl = new float[m_ImageSize];
101 m_CISInten = new float[m_ImageSize];
102 m_ThreadedCISDist = new float[m_ImageSize];
103 m_ThreadedCISAmpl = new float[m_ImageSize];
104 m_ThreadedCISInten = new float[m_ImageSize];
105
109
110 m_Init = true;
111 }
112}
113
115{
116 m_SourceData->DeepCopy(sourceData);
117}
118
120{
121 memcpy(dist, m_CISDist, m_ImageSize*sizeof(float) );
122}
123
125{
126 memcpy(ampl, m_CISAmpl, m_ImageSize*sizeof(float));
127}
128
130{
131 memcpy(inten, m_CISInten, m_ImageSize*sizeof(float));
132}
133
134void ThreadedToFRawDataReconstruction::GetAllData(float* dist, float* ampl, float* inten)
135{
136 memcpy(dist, m_CISDist, m_ImageSize*sizeof(float) );
137 memcpy(ampl, m_CISAmpl, m_ImageSize*sizeof(float));
138 memcpy(inten, m_CISInten, m_ImageSize*sizeof(float));
139}
140
142 {
143 if(m_Init)
144 {
146 }
147 }
148
150 {
151 int sourceDataSize = m_SourceDataSize;
152 int lineWidth = m_Width;
153 int frameHeight = m_Height;
154 int channelSize = lineWidth*frameHeight << 1;
155 int quadChannelSize = channelSize * 0.25;
156
157 std::vector<short> quad = std::vector<short>(quadChannelSize);
158
159 // clean the thread data array
161
162 int channelNo = 0;
163 while(channelNo < m_SourceData->GetNumberOfTuples())
164 {
165 short* sourceData = new short[channelSize];
166 m_SourceData->GetTupleValue(channelNo, sourceData);
167 quad.insert(quad.begin(), sourceData, sourceData+channelSize);
168 m_ThreadData->m_InputData.push_back(quad);
169 delete[]sourceData;
170 ++channelNo;
171 }
172
173 if(m_Threader.IsNull())
174 {
175 m_Threader = this->GetMultiThreader();
176 }
177 int maxThreadNr = 0;
178
179 if(m_Threader->GetGlobalDefaultNumberOfThreads()> 5)
180 {
181 maxThreadNr = 5;
182 }
183 else if(m_Threader->GetGlobalMaximumNumberOfThreads()>5)
184 {
185 maxThreadNr = 5;
186 }
187 else
188 {
189 maxThreadNr = m_Threader->GetGlobalMaximumNumberOfThreads();
190 }
191
192 if ( m_ThreadData->m_Barrier.IsNull())
193 {
194 m_ThreadData->m_Barrier = itk::Barrier::New();
195 m_ThreadData->m_Barrier->Initialize(maxThreadNr);
196 }
197 m_ThreadData->m_DataSize = quadChannelSize;
198 m_ThreadData->m_LineWidth = lineWidth;
199 m_ThreadData->m_FrameHeight = frameHeight * 0.25;
200 std::vector<int> threadIDVector;
201 int threadcounter = 0;
202 while(threadcounter != maxThreadNr-1)
203 {
204 if (m_Threader->GetNumberOfThreads() < m_Threader->GetGlobalMaximumNumberOfThreads())
205 {
206 int threadID = m_Threader->SpawnThread(this->ThreadedGenerateDataCallbackFunction, m_ThreadData);
207 threadIDVector.push_back(threadID);
208 threadcounter++;
209 }
210 }
211 m_ThreadData->m_Barrier->Wait();
212
213 int count = 0;
214 while(count != threadIDVector.size())
215 {
216 m_Threader->TerminateThread(threadIDVector.at(count));
217 count++;
218 }
220 memcpy(m_CISDist, m_ThreadData->m_OutputData.at(0), (channelSize * 0.5)*sizeof(float));
221 memcpy(m_CISAmpl, m_ThreadData->m_OutputData.at(1), (channelSize * 0.5)*sizeof(float));
222 memcpy(m_CISInten, m_ThreadData->m_OutputData.at(2), (channelSize * 0.5)*sizeof(float));
224
225 }
226
228 {
229 /* extract this pointer from Thread Info structure */
230 struct itk::MultiThreader::ThreadInfoStruct * pInfo = (struct itk::MultiThreader::ThreadInfoStruct*)data;
231 if (pInfo == nullptr)
232 {
233 return ITK_THREAD_RETURN_VALUE;
234 }
235 if (pInfo->UserData == nullptr)
236 {
237 return ITK_THREAD_RETURN_VALUE;
238 }
239 int quadrant = pInfo->ThreadID;
240 ThreadDataStruct* threadData = (ThreadDataStruct*) pInfo->UserData;
241
242 // some needed variables
243 int x = 0;
244 double phi = 0;
245 double phi2 = 0;
246 double A1 = 0;
247 double A2 = 0;
248 double A3 = 0;
249 double A4 = 0;
250 double A5 = 0;
251 double A6 = 0;
252 double A7 = 0;
253 double A8 = 0;
254 double A3m1 = 0;
255 double A4m2 = 0;
256 double A7m5 = 0;
257 double A8m6 = 0;
258 double cair = cAir;
259 double twoPi = itk::Math::pi + itk::Math::pi;
260 long modFreq = fMod;
261
262 threadData->m_ThreadDataMutex->Lock();
263 std::vector<short> quad1 = threadData->m_InputData.at(0);
264 std::vector<short> quad2 = threadData->m_InputData.at(1);
265 std::vector<short> quad3 = threadData->m_InputData.at(2);
266 std::vector<short> quad4 = threadData->m_InputData.at(3);
267 int index = quadrant << 1;
268 int index2 = 3-quadrant;
269 modFreq = threadData->m_ModulationFrequency;
270 int linewidth = threadData->m_LineWidth;
271 int frameheight = threadData->m_FrameHeight;
272 threadData->m_ThreadDataMutex->Unlock();
273
274 double intermed1 = cair/(itk::Math::pi*(modFreq << 2));
275 double intermed2 = intermed1*500;
276 int doubleLwidth = linewidth << 1;
277 int datasize = doubleLwidth*frameheight << 2;
278
279
280 do
281 {
282 index += doubleLwidth;
283 x++;
284 do
285 {
286 index -= 8;
287 A1 = htons(quad1.at(index));
288 A2 = htons(quad2.at(index));
289 A3 = htons(quad3.at(index));
290 A4 = htons(quad4.at(index));
291 A5 = htons(quad1.at(index+1));
292 A6 = htons(quad2.at(index+1));
293 A7 = htons(quad3.at(index+1));
294 A8 = htons(quad4.at(index+1));
295
296 phi = atan2((A3 - A1),(A2 - A4)) + itk::Math::pi;
297 phi2 = atan2((A7 - A5),(A6 - A8));
298 if(phi2<0) phi2 +=twoPi;
299
300 A3m1 = A3*A3 - 2*A3*A1 + A1*A1;
301 A4m2 = A4*A4 - 2*A4*A2 + A2*A2;
302 A7m5 = A7*A7 - 2*A7*A5 + A5*A5;
303 A8m6 = A8*A8 - 2*A8*A6 + A6*A6;
304 threadData->m_ImageDataMutex->Lock();
305 threadData->m_OutputData.at(0)[index2] = (phi+phi2)*intermed2; //(((phi*intermed1) + (phi2*intermed1))/2)*1000;
306 threadData->m_OutputData.at(1)[index2] = (sqrt(A3m1 + A4m2)+sqrt(A7m5 + A8m6))*0.5; //(sqrt(A3m1 + A4m2)/2) + (sqrt(A7m5 + A8m6)/2);
307 threadData->m_OutputData.at(2)[index2] = (A1+A2+A3+A4+A5+A6+A7+A8)*0.125;
308 threadData->m_ImageDataMutex->Unlock();
309
310 index2 += 4;
311 }while(index2 <= (x*linewidth) - (1+quadrant));
312
313 index += doubleLwidth;
314
315 }while(index < datasize);
316
317 threadData->m_Barrier->Wait();
318
319 return ITK_THREAD_RETURN_VALUE;
320 }
321
326
327} // end mitk namespace
virtual void BeforeThreadedGenerateData()
method configures the camera output and prepares the thread data struct for threaded data generation
void Initialize(int width, int height, int modulationFrequency, int sourceDataSize)
void GetAllData(float *dist, float *ampl, float *inten)
float * m_CISInten
holds the intensity information from for one intensity image slice
virtual void GenerateData()
method generating the outputs of this filter. Called in the updated process of the pipeline....
static ITK_THREAD_RETURN_TYPE ThreadedGenerateDataCallbackFunction(void *data)
threader callback function for multi threaded data generation
float * m_CISDist
holds the distance information from for one distance image slice
float * m_CISAmpl
holds the amplitude information from for one amplitude image slice
IGT Exceptions.
itk::FastMutexLock::Pointer m_ImageDataMutex
mutex for coordinated access to image data
std::vector< std::vector< short > > m_InputData
itk::FastMutexLock::Pointer m_ThreadDataMutex
mutex to control access to images
itk::Barrier::Pointer m_Barrier
barrier to synchronize ends of threads