ANIMA  4.0
animaLowMemNLMeansPatientToGroupComparisonBridge.cxx
Go to the documentation of this file.
4 
5 namespace anima
6 {
7 
9 {
10  m_NbSplits = 2;
11  m_NumThreads = itk::MultiThreaderBase::GetGlobalDefaultNumberOfThreads();
12 
13  m_DatabaseImages = new ImageSplitterType;
14  m_TestImage = new ImageSplitterType;
15 
16  m_DatabaseCovarianceDistanceAverage = new ScalarImageSplitterType;
17  m_DatabaseCovarianceDistanceStd = new ScalarImageSplitterType;
18  m_DatabaseMeanDistanceAverage = new ScalarImageSplitterType;
19  m_DatabaseMeanDistanceStd = new ScalarImageSplitterType;
20 
21  m_ComputationMask = NULL;
22 
23  m_WeightThreshold = 0.0;
24  m_MeanThreshold = 10.0;
25  m_VarianceThreshold = 10.0;
26  m_BetaParameter = 1;
27  m_PatchHalfSize = 1;
28  m_SearchStepSize = 2;
29  m_SearchNeighborhood = 4;
30 }
31 
33 {
34  if (m_DatabaseImages)
35  delete m_DatabaseImages;
36 
37  if (m_TestImage)
38  delete m_TestImage;
39 
40  if (m_DatabaseCovarianceDistanceAverage)
41  delete m_DatabaseCovarianceDistanceAverage;
42 
43  if (m_DatabaseCovarianceDistanceStd)
44  delete m_DatabaseCovarianceDistanceStd;
45 
46  if (m_DatabaseMeanDistanceAverage)
47  delete m_DatabaseMeanDistanceAverage;
48 
49  if (m_DatabaseMeanDistanceStd)
50  delete m_DatabaseMeanDistanceStd;
51 }
52 
54 {
55  m_ComputationMask = anima::readImage <MaskImageType> (cMask);
56 
57  m_DatabaseImages->SetComputationMask(m_ComputationMask);
58  m_TestImage->SetComputationMask(m_ComputationMask);
59 
60  m_DatabaseCovarianceDistanceAverage->SetComputationMask(m_ComputationMask);
61  m_DatabaseCovarianceDistanceStd->SetComputationMask(m_ComputationMask);
62  m_DatabaseMeanDistanceAverage->SetComputationMask(m_ComputationMask);
63  m_DatabaseMeanDistanceStd->SetComputationMask(m_ComputationMask);
64 }
65 
66 void LowMemoryNLMeansPatientToGroupComparisonBridge::Update(int specificSplitToDo, bool genOutputDescriptionData)
67 {
68  if (!m_ComputationMask)
69  itkExceptionMacro("No computation mask... Exiting...");
70 
72  for (unsigned int i = 0;i < MaskImageType::GetImageDimension();++i)
73  tmpInd[i] = m_NbSplits;
74 
76 
77  // 4 is here to ensure we have enough space to compute local noise
78  for (unsigned int i = 0;i < MaskImageType::GetImageDimension();++i)
79  marginBlock[i] = std::max(m_SearchNeighborhood + m_PatchHalfSize,(unsigned int)4);
80 
81  m_DatabaseImages->SetBlockMargin(marginBlock);
82  m_TestImage->SetBlockMargin(marginBlock);
83  m_DatabaseCovarianceDistanceAverage->SetBlockMargin(marginBlock);
84  m_DatabaseCovarianceDistanceStd->SetBlockMargin(marginBlock);
85  m_DatabaseMeanDistanceAverage->SetBlockMargin(marginBlock);
86  m_DatabaseMeanDistanceStd->SetBlockMargin(marginBlock);
87 
88  m_DatabaseImages->SetNumberOfBlocks(tmpInd);
89  m_TestImage->SetNumberOfBlocks(tmpInd);
90  m_DatabaseCovarianceDistanceAverage->SetNumberOfBlocks(tmpInd);
91  m_DatabaseCovarianceDistanceStd->SetNumberOfBlocks(tmpInd);
92  m_DatabaseMeanDistanceAverage->SetNumberOfBlocks(tmpInd);
93  m_DatabaseMeanDistanceStd->SetNumberOfBlocks(tmpInd);
94 
95  std::vector < ImageSplitterType::TInputIndexType > splitIndexesToProcess;
96 
97  if (specificSplitToDo != -1)
98  {
99  tmpInd[0] = (unsigned int)floor((double)(specificSplitToDo/(m_NbSplits*m_NbSplits)));
100  unsigned int tmpVal = specificSplitToDo - tmpInd[0]*m_NbSplits*m_NbSplits;
101  tmpInd[1] = (unsigned int)floor((double)(tmpVal/m_NbSplits));
102  tmpInd[2] = tmpVal - tmpInd[1]*m_NbSplits;
103 
104  if (!m_DatabaseImages->EmptyMask(tmpInd))
105  splitIndexesToProcess.push_back(tmpInd);
106  }
107  else
108  {
109  for (unsigned int i = 0;i < m_NbSplits;++i)
110  {
111  tmpInd[0] = i;
112  for (unsigned int j = 0;j < m_NbSplits;++j)
113  {
114  tmpInd[1] = j;
115  for (unsigned int k = 0;k < m_NbSplits;++k)
116  {
117  tmpInd[2] = k;
118 
119  if (!m_DatabaseImages->EmptyMask(tmpInd))
120  splitIndexesToProcess.push_back(tmpInd);
121  }
122  }
123  }
124  }
125 
126  for (unsigned int i = 0;i < splitIndexesToProcess.size();++i)
127  {
128  std::cout << "Processing block : " << splitIndexesToProcess[i][0] << " "
129  << splitIndexesToProcess[i][1] << " " << splitIndexesToProcess[i][2] << std::endl;
130 
131  m_DatabaseImages->SetBlockIndex(splitIndexesToProcess[i]);
132  m_DatabaseImages->Update();
133 
134  m_TestImage->SetBlockIndex(splitIndexesToProcess[i]);
135  m_TestImage->Update();
136 
137  m_DatabaseCovarianceDistanceAverage->SetBlockIndex(splitIndexesToProcess[i]);
138  m_DatabaseCovarianceDistanceAverage->Update();
139 
140  m_DatabaseCovarianceDistanceStd->SetBlockIndex(splitIndexesToProcess[i]);
141  m_DatabaseCovarianceDistanceStd->Update();
142 
143  m_DatabaseMeanDistanceAverage->SetBlockIndex(splitIndexesToProcess[i]);
144  m_DatabaseMeanDistanceAverage->Update();
145 
146  m_DatabaseMeanDistanceStd->SetBlockIndex(splitIndexesToProcess[i]);
147  m_DatabaseMeanDistanceStd->Update();
148 
150 
151  for (unsigned int j = 0;j < m_DatabaseImages->GetNbImages();++j)
152  mainFilter->AddDatabaseInput(m_DatabaseImages->GetOutput(j));
153 
154  mainFilter->SetComputationMask(m_DatabaseImages->GetSmallMaskWithMargin());
155  mainFilter->SetNumberOfWorkUnits(m_NumThreads);
156 
157  mainFilter->SetDatabaseMeanDistanceAverage(m_DatabaseMeanDistanceAverage->GetOutput(0));
158  mainFilter->SetDatabaseMeanDistanceStd(m_DatabaseMeanDistanceStd->GetOutput(0));
159  mainFilter->SetDatabaseCovarianceDistanceAverage(m_DatabaseCovarianceDistanceAverage->GetOutput(0));
160  mainFilter->SetDatabaseCovarianceDistanceStd(m_DatabaseCovarianceDistanceStd->GetOutput(0));
161 
162  mainFilter->SetPatchHalfSize(m_PatchHalfSize);
163  mainFilter->SetSearchNeighborhood(m_SearchNeighborhood);
164  mainFilter->SetSearchStepSize(m_SearchStepSize);
165  mainFilter->SetWeightThreshold(m_WeightThreshold);
166  mainFilter->SetMeanThreshold(m_MeanThreshold);
167  mainFilter->SetVarianceThreshold(m_VarianceThreshold);
168  mainFilter->SetBetaParameter(m_BetaParameter);
169 
170  mainFilter->SetInput(0,m_TestImage->GetOutput(0));
171 
172  mainFilter->Update();
173 
174  std::cout << "Results computed... Writing output parcel..." << std::endl;
175 
176  char numSplit[2048];
177  sprintf(numSplit,"_%ld_%ld_%ld.nrrd",splitIndexesToProcess[i][0],splitIndexesToProcess[i][1],splitIndexesToProcess[i][2]);
178 
179  //Write outputs
180  std::string outputScoreName = m_OutputScoreName + numSplit;
181  std::string outputPValName = m_OutputPValName + numSplit;
182  std::string outputNPatchesName = m_OutputNPatchesName + numSplit;
183  this->BuildAndWrite(mainFilter->GetOutput(0),outputPValName,m_DatabaseImages->GetBlockRegionInsideMargin());
184 
185  if (m_OutputScoreName != "")
186  this->BuildAndWrite(mainFilter->GetOutput(1),outputScoreName,m_DatabaseImages->GetBlockRegionInsideMargin());
187 
188  if (m_OutputNPatchesName != "")
189  this->BuildAndWrite(mainFilter->GetOutput(2),outputNPatchesName,m_DatabaseImages->GetBlockRegionInsideMargin());
190  }
191 
192  if (genOutputDescriptionData)
193  {
194  std::vector <std::ofstream> mainOutFiles;
195 
196  std::string tmpOutScoreName = m_OutputScoreName + ".txt";
197  std::ofstream tmpFileScoreOut;
198 
199  if (m_OutputScoreName != "")
200  tmpFileScoreOut.open(tmpOutScoreName.c_str());
201 
202  std::string tmpOutNPatchesName = m_OutputNPatchesName + ".txt";
203  std::ofstream tmpFileNPatchesOut;
204 
205  if (m_OutputNPatchesName != "")
206  tmpFileNPatchesOut.open(tmpOutNPatchesName.c_str());
207 
208  std::string tmpOutPValName = m_OutputPValName + ".txt";
209  std::ofstream tmpFilePValOut(tmpOutPValName.c_str());
210 
211  for (unsigned int i = 0;i < m_NbSplits;++i)
212  {
213  tmpInd[0] = i;
214  for (unsigned int j = 0;j < m_NbSplits;++j)
215  {
216  tmpInd[1] = j;
217  for (unsigned int k = 0;k < m_NbSplits;++k)
218  {
219  tmpInd[2] = k;
220 
221  if (!m_DatabaseImages->EmptyMask(tmpInd))
222  {
223  OutputImageType::RegionType tmpBlRegion = m_DatabaseImages->GetSpecificBlockRegion(tmpInd);
224  char numSplit[2048];
225  sprintf(numSplit,"_%ld_%ld_%ld.nrrd",tmpInd[0],tmpInd[1],tmpInd[2]);
226 
227  if (tmpFileScoreOut.is_open())
228  {
229  tmpFileScoreOut << "<BLOCK>" << std::endl;
230  tmpFileScoreOut << "BLOCK_FILE=" << m_OutputScoreName + numSplit << std::endl;
231  tmpFileScoreOut << "STARTING_INDEX=" << tmpBlRegion.GetIndex()[0] << " "
232  << tmpBlRegion.GetIndex()[1] << " " << tmpBlRegion.GetIndex()[2] << std::endl;
233  tmpFileScoreOut << "</BLOCK>" << std::endl;
234  }
235 
236  if (tmpFileNPatchesOut.is_open())
237  {
238  tmpFileNPatchesOut << "<BLOCK>" << std::endl;
239  tmpFileNPatchesOut << "BLOCK_FILE=" << m_OutputNPatchesName + numSplit << std::endl;
240  tmpFileNPatchesOut << "STARTING_INDEX=" << tmpBlRegion.GetIndex()[0] << " "
241  << tmpBlRegion.GetIndex()[1] << " " << tmpBlRegion.GetIndex()[2] << std::endl;
242  tmpFileNPatchesOut << "</BLOCK>" << std::endl;
243  }
244 
245  tmpFilePValOut << "<BLOCK>" << std::endl;
246  tmpFilePValOut << "BLOCK_FILE=" << m_OutputPValName + numSplit << std::endl;
247  tmpFilePValOut << "STARTING_INDEX=" << tmpBlRegion.GetIndex()[0] << " "
248  << tmpBlRegion.GetIndex()[1] << " " << tmpBlRegion.GetIndex()[2] << std::endl;
249  tmpFilePValOut << "</BLOCK>" << std::endl;
250  }
251  }
252  }
253  }
254 
255  tmpFileNPatchesOut.close();
256  tmpFileScoreOut.close();
257  tmpFilePValOut.close();
258  }
259 }
260 
262  OutputImageType::RegionType finalROI)
263 {
264  OutputImageType::RegionType tmpRegion = finalROI;
265  for (unsigned int i = 0;i < OutputImageType::GetImageDimension();++i)
266  tmpRegion.SetIndex(i,0);
267 
268  OutputImageType::Pointer tmpRes = OutputImageType::New();
269  tmpRes->Initialize();
270 
271  tmpRes->SetOrigin(m_ComputationMask->GetOrigin());
272  tmpRes->SetRegions(tmpRegion);
273  tmpRes->SetDirection(m_ComputationMask->GetDirection());
274  tmpRes->SetSpacing(m_ComputationMask->GetSpacing());
275 
276  tmpRes->Allocate();
277 
278  itk::ImageRegionIterator <OutputImageType> tmpImIt (tmpIm,finalROI);
279  itk::ImageRegionIterator <OutputImageType> tmpResIt (tmpRes,tmpRegion);
280 
281  while (!tmpImIt.IsAtEnd())
282  {
283  tmpResIt.Set(tmpImIt.Get());
284 
285  ++tmpImIt;
286  ++tmpResIt;
287  }
288 
289  anima::writeImage <OutputImageType> (resName,tmpRes);
290 }
291 
292 void LowMemoryNLMeansPatientToGroupComparisonBridge::PrepareNoiseEstimates()
293 {
294  if (!m_ComputationMask)
295  itkExceptionMacro("No computation mask... Exiting...");
296 
297  //m_NoiseSigma.clear();
298 
299  OutputImageRegionType largestRegion = m_ComputationMask->GetLargestPossibleRegion();
300  vnl_matrix <double> noiseCov;
301 
302  for (unsigned int k = 0;k < m_DatabaseImages->GetNbImages();++k)
303  {
304  itk::ImageFileReader <InputImageType>::Pointer inReader = itk::ImageFileReader <InputImageType>::New();
305  inReader->SetFileName(m_DatabaseImages->GetFileName(k));
306  inReader->Update();
307 
308  anima::computeAverageLocalCovariance(noiseCov,inReader->GetOutput(),m_ComputationMask.GetPointer(),
309  largestRegion,2);
310  //m_NoiseSigma.push_back(vnl_matrix_inverse<double>(noiseCov));
311  }
312 }
313 
314 } // end of namesapce anima
TInputRegionType GetBlockRegionInsideMargin()
MaskImageType * GetSmallMaskWithMargin()
NLMeansPatientToGroupComparisonImageFilter< double >::OutputImageType OutputImageType
void BuildAndWrite(OutputImageType *tmpIm, std::string resName, OutputImageType::RegionType finalROI)
void SetComputationMask(MaskImageType::Pointer &maskIm)
void SetBlockMargin(TInputIndexType &bMargin)
void Update(int specificSplitToDo=-1, bool genOutputDescriptionData=false)
void SetBlockIndex(TInputIndexType &bIndex)
void SetNumberOfBlocks(TInputIndexType &bNumBlocks)
TInputImage * GetOutput(unsigned int i)
TInputRegionType GetSpecificBlockRegion(TInputIndexType &block)
NLMeansPatientToGroupComparisonImageFilter< double >::OutputImageRegionType OutputImageRegionType
std::string GetFileName(unsigned int i)
bool EmptyMask(TInputIndexType &bIndex)
void computeAverageLocalCovariance(vnl_matrix< T2 > &resVariance, itk::VectorImage< T1, Dimension > *inputImage, itk::Image< unsigned char, Dimension > *maskImage, const itk::ImageRegion< Dimension > &averagingRegion, int localNeighborhood)
Noise estimation for a patch of a vector image.
TInputImage::IndexType TInputIndexType