8 template <
typename TInput,
typename TOutput>
11 this->SetNthInput(0, const_cast<TInput*>(image));
13 m_ListImages.push_back(image);
16 template <
typename TInput,
typename TOutput>
19 this->SetNthInput(1, const_cast<TSeedProba*>(proba));
22 template <
typename TInput,
typename TOutput>
25 this->SetNthInput(2, const_cast<TSeedProba*>(proba));
28 template <
typename TInput,
typename TOutput>
31 this->SetNthInput(3, const_cast<TMask*>(mask));
34 template <
typename TInput,
typename TOutput>
37 this->SetNthInput(m_NbInputs, const_cast<TInput*>(image));
38 m_IndexImage2 = m_NbInputs;
41 m_ListImages.push_back(image);
44 template <
typename TInput,
typename TOutput>
47 this->SetNthInput(m_NbInputs, const_cast<TInput*>(image));
48 m_IndexImage3 = m_NbInputs;
51 m_ListImages.push_back(image);
54 template <
typename TInput,
typename TOutput>
57 this->SetNthInput(m_NbInputs, const_cast<TInput*>(image));
58 m_IndexImage4 = m_NbInputs;
61 m_ListImages.push_back(image);
64 template <
typename TInput,
typename TOutput>
67 this->SetNthInput(m_NbInputs, const_cast<TInput*>(image));
68 m_IndexImage5 = m_NbInputs;
71 m_ListImages.push_back(image);
75 template <
typename TInput,
typename TOutput>
78 return static_cast< const TInput *
> 79 ( this->itk::ProcessObject::GetInput(0) );
82 template <
typename TInput,
typename TOutput>
86 ( this->itk::ProcessObject::GetInput(1) );
89 template <
typename TInput,
typename TOutput>
93 ( this->itk::ProcessObject::GetInput(2) );
96 template <
typename TInput,
typename TOutput>
99 return static_cast< const TMask *
> 100 ( this->itk::ProcessObject::GetInput(3) );
103 template <
typename TInput,
typename TOutput>
106 return static_cast< const TInput *
> 107 ( this->itk::ProcessObject::GetInput(m_IndexImage2) );
110 template <
typename TInput,
typename TOutput>
113 return static_cast< const TInput *
> 114 ( this->itk::ProcessObject::GetInput(m_IndexImage3) );
117 template <
typename TInput,
typename TOutput>
120 return static_cast< const TInput *
> 121 ( this->itk::ProcessObject::GetInput(m_IndexImage4) );
124 template <
typename TInput,
typename TOutput>
127 return static_cast< const TInput *
> 128 ( this->itk::ProcessObject::GetInput(m_IndexImage5) );
132 template <
typename TInputImage,
typename TOutput>
135 itk::DataObject::Pointer output;
140 output = ( TOutput::New() ).GetPointer();
143 output = ( TOutput::New() ).GetPointer();
146 std::cerr <<
"No output " << idx << std::endl;
150 return output.GetPointer();
153 template <
typename TInputImage,
typename TOutput>
156 return dynamic_cast< TOutput*
>( this->itk::ProcessObject::GetOutput(0) );
158 template <
typename TInputImage,
typename TOutput>
161 return dynamic_cast< TOutput*
>( this->itk::ProcessObject::GetOutput(1) );
164 template <
typename TInput,
typename TOutput>
168 typedef itk::CSVArray2DFileReader<double> ReaderType;
169 ReaderType::Pointer reader = ReaderType::New();
171 reader->SetFileName ( m_MatFilename );
172 reader->SetFieldDelimiterCharacter(
';' );
173 reader->SetStringDelimiterCharacter(
'"' );
174 reader->HasColumnHeadersOff();
175 reader->HasRowHeadersOff();
182 catch( itk::ExceptionObject & exp )
184 std::cerr <<
"Expected Exception caught!" << std::endl;
185 std::cerr << exp << std::endl;
189 reader->Print(std::cout);
191 typedef itk::CSVArray2DDataObject<double> DataFrameObjectType;
192 DataFrameObjectType::Pointer dfo = reader->GetOutput();
194 m_Matrix = dfo->GetMatrix();
198 template <
typename TInput,
typename TOutput>
203 unsigned int nbInputs = this->GetNumberOfIndexedInputs();
206 std::cerr <<
"Error: No inputs available... Exiting..." << std::endl;
210 if((m_MatFilename!=
"") && m_UseSpectralGradient)
212 if(m_ListImages.size()<3)
214 std::cerr <<
"-- Error in Graph3D: Wrong number of images, must be equal or superior to 3" << std::endl;
217 if(!readMatrixFile())
219 std::cerr <<
"-- Error in Graph3D: error while reading matrix file" << std::endl;
222 if( (m_Matrix.Rows()!=3) || (m_Matrix.Cols()!=m_ListImages.size()) )
224 std::cerr <<
"-- Error in Graph3D: Wrong number of coefficients in matrix after reading matrix csv file" << std::endl;
227 std::cout <<
"using matfilename" << std::endl;
229 else if( (m_Matrix.Rows()!=0) && m_UseSpectralGradient)
231 if( (m_Matrix.Rows()!=3) || (m_Matrix.Cols()!=m_ListImages.size()) )
233 std::cerr <<
"-- Error in NLinksFilter: Wrong number of coefficients in spectral gradient matrix" << std::endl;
234 std::cerr <<
"-- Matrix.Rows(): " << m_Matrix.Rows() << std::endl;
235 std::cerr <<
"-- Matrix.Cols(): " << m_Matrix.Cols() << std::endl;
236 std::cerr <<
"-- ListImages.size(): " << m_ListImages.size()<< std::endl;
240 std::cout <<
"using given matrix" << std::endl;
241 std::cout << m_Matrix(0,0) <<
" "<< m_Matrix(0,1) <<
" "<< m_Matrix(0,2) << std::endl;
242 std::cout << m_Matrix(1,0) <<
" "<< m_Matrix(1,1) <<
" "<< m_Matrix(1,2) << std::endl;
243 std::cout << m_Matrix(2,0) <<
" "<< m_Matrix(2,1) <<
" "<< m_Matrix(2,2) << std::endl;
248 m_Matrix.SetSize(3,3);
250 m_Matrix(0,0) = 0.002358; m_Matrix(0,1) = 0.025174; m_Matrix(0,2) = 0.010821;
251 m_Matrix(1,0) = 0.011943; m_Matrix(1,1) = 0.001715; m_Matrix(1,2) = -0.013994;
252 m_Matrix(2,0) = 0.013743; m_Matrix(2,1) = -0.023965; m_Matrix(2,2) = 0.00657;
255 if (m_UseSpectralGradient && (m_ListImages.size() != 3))
257 std::cerr <<
"-- Warning in Graph3D: the spectral gradient requires 3 modalities" << std::endl <<
"Falling back to conventional gradient approach" << std::endl;
258 m_UseSpectralGradient =
false;
261 if (m_UseSpectralGradient)
262 std::cout <<
"using original grad spec" << std::endl;
264 std::cout <<
"NO using grad spec" << std::endl;
267 m_size = this->GetMask()->GetLargestPossibleRegion().GetSize();
271 template <
typename TInput,
typename TOutput>
276 typename TOutput::Pointer output = this->GetOutput();
277 output->SetRegions(this->GetMask()->GetLargestPossibleRegion());
278 output->CopyInformation(this->GetMask());
280 output->FillBuffer(0);
282 typename TOutput::Pointer outputBackground = this->GetOutputBackground();
283 outputBackground->SetRegions(this->GetMask()->GetLargestPossibleRegion());
284 outputBackground->CopyInformation(this->GetMask());
285 outputBackground->Allocate();
286 outputBackground->FillBuffer(0);
288 std::cout <<
"Computing N-Links..."<< std::endl;
290 this->CheckSpectralGradient();
294 m_graph -> maxflow();
299 OutputIteratorType outBackgroundIt (outputBackground,outputBackground->GetLargestPossibleRegion() );
301 while (!maskIt.IsAtEnd())
304 if (maskIt.Get() != 0)
306 int v = m_graph->what_segment(cpt);
307 unsigned char buff = 0 | (v == GraphType::SOURCE) ? 1 : 0;
308 outIt.Set(static_cast<OutputPixelType>(buff));
309 outBackgroundIt.Set(1-buff);
319 m_ListImages.clear();
320 if (m_graph)
delete m_graph;
325 template <
typename TInput,
typename TOutput>
337 if (m_UseSpectralGradient)
339 double g = m_e1->GetPixel(index1) - m_e1->GetPixel(index2);
340 double w = m_e2->GetPixel(index1) - m_e2->GetPixel(index2);
341 return static_cast<double>((.1+std::exp(-(g * g + w * w) / (2 * m_Sigma * m_Sigma))));
345 int dim = m_ListImages.size();
348 for (
int m=0; m<dim; m++)
350 g = m_ListImages[m]->GetPixel(index1) - m_ListImages[m]->GetPixel(index2);
353 return static_cast<double>((.1+std::exp(- sum / (2 * m_Sigma * m_Sigma))));
357 template <
typename TInput,
typename TOutput>
362 if(m_UseSpectralGradient)
364 m_e1 = TSeedProba::New();
365 m_e1->SetRegions(this->GetMask()->GetLargestPossibleRegion());
366 m_e1->CopyInformation(this->GetMask());
370 m_e2 = TSeedProba::New();
371 m_e2->SetRegions(this->GetMask()->GetLargestPossibleRegion());
372 m_e2->CopyInformation(this->GetMask());
379 std::vector<InRegionConstIteratorType > ListImagesVectorIt;
380 for (
unsigned int i = 0; i < m_ListImages.size(); i++ )
383 ListImagesVectorIt.push_back(It);
386 while((!e1It.IsAtEnd()) && (!e2It.IsAtEnd()))
393 for(
unsigned int m=0; m < m_ListImages.size(); m++)
395 e += m_Matrix(0,m) * (ListImagesVectorIt[m].Get());
396 e_l += m_Matrix(1,m) * (ListImagesVectorIt[m].Get());
397 e_l_l += m_Matrix(2,m) * (ListImagesVectorIt[m].Get());
400 e2It.Set((e*e_l_l-std::pow(e_l, 2.f)) / std::pow(e,2.f) );
404 for (
unsigned int i = 0; i < m_ListImages.size(); i++ )
406 ++ListImagesVectorIt[i];
413 template <
typename TInput,
typename TOutput>
416 return ( x < m_size[0] && y < m_size[1] && z < m_size[2] && x >= 0 && y >= 0 && z >= 0 );
419 template <
typename TInput,
typename TOutput>
426 while (!maskIt.IsAtEnd())
428 if (maskIt.Get() != 0)
435 int nb_edges = 7*nb_vox;
439 m_graph =
new GraphType(nb_vox, nb_edges);
441 catch (std::bad_alloc& ba)
443 std::cerr <<
"-- Error in NLinksFilter: insufficient memory to create the graph: " << ba.what() <<
'\n';
449 ImageTypeInt::Pointer pix = ImageTypeInt::New();
450 pix->SetRegions(this->GetMask()->GetLargestPossibleRegion());
451 pix->CopyInformation(this->GetMask());
458 while (!maskIt.IsAtEnd())
460 if (maskIt.Get() != 0)
462 m_graph -> add_node();
475 while (!maskIt.IsAtEnd())
477 if(maskIt.Get() != 0)
480 index[0]=maskIt.GetIndex()[0];
481 index[1]=maskIt.GetIndex()[1];
482 index[2]=maskIt.GetIndex()[2];
484 int pix_ref = pix->GetPixel(index);
489 index1[0]=index[0]+1;
492 if ( (isInside(index[0]+1, index[1] , index[2])) && (this->GetMask()->GetPixel(index1)!=0) )
494 pix_courant = pix->GetPixel(index1);
495 cap = computeNLink(index[0]+1, index[1], index[2], index[0], index[1], index[2]);
499 m_graph -> add_edge(pix_ref, pix_courant, cap, rcap);
504 index1[1]=index[1]+1;
506 if ( (isInside(index[0], index[1]+1 , index[2])) && (this->GetMask()->GetPixel(index1)!=0) )
508 pix_courant = pix->GetPixel(index1);
509 cap = computeNLink(index[0], index[1]+1, index[2], index[0], index[1], index[2]);
513 m_graph -> add_edge(pix_ref, pix_courant, cap, rcap);
518 index1[2]=index[2]+1;
519 if ( (isInside(index[0], index[1] , index[2]+1)) && (this->GetMask()->GetPixel(index1)!=0) )
521 pix_courant = pix->GetPixel(index1);
522 cap = computeNLink(index[0], index[1], index[2]+1, index[0], index[1], index[2]);
526 m_graph -> add_edge(pix_ref, pix_courant, cap, rcap);
530 double t_source =
static_cast<double>(this->GetInputSeedProbaSources()->GetPixel(index));
531 double t_sink =
static_cast<double>(this->GetInputSeedProbaSinks()->GetPixel(index));
532 m_graph -> add_tweights(pix_ref, t_source, t_sink);
TInput::ConstPointer GetInputImage2()
Class creating a 3D graph in a graph cut framework.
itk::ImageRegionIterator< TSeedProba > ImageIteratorTypeProba
TInput::ConstPointer GetInputImage1()
itk::Image< PixelTypeD, 3 > TSeedProba
void CheckSpectralGradient(void)
TSeedProba::ConstPointer GetInputSeedProbaSinks()
void SetInputImage4(const TInput *image)
ImageTypeInt::IndexType pixelIndexInt
void GenerateData() ITK_OVERRIDE
void SetMask(const TMask *mask)
TMask::ConstPointer GetMask()
itk::ImageRegionConstIterator< TInput > InRegionConstIteratorType
void SetInputSeedProbaSinks(const TSeedProba *mask)
TInput::ConstPointer GetInputImage5()
TSeedProba::ConstPointer GetInputSeedProbaSources()
TInput::ConstPointer GetInputImage3()
void SetInputImage5(const TInput *image)
itk::ImageRegionIterator< TOutput > OutputIteratorType
void SetInputImage2(const TInput *image)
itk::ImageRegionIterator< ImageTypeInt > ImageIteratorTypeInt
double computeNLink(int i1, int j1, int k1, int i2, int j2, int k2)
itk::ImageRegionConstIterator< TMask > MaskRegionConstIteratorType
itk::Image< PixelTypeUC, 3 > TMask
TInput::ConstPointer GetInputImage4()
void SetInputImage1(const TInput *image)
bool isInside(unsigned int x, unsigned int y, unsigned int z) const
void SetInputSeedProbaSources(const TSeedProba *mask)
void SetInputImage3(const TInput *image)