Medical Imaging Interaction Toolkit  2024.06.00
Medical Imaging Interaction Toolkit
mitkCLUtil.h
Go to the documentation of this file.
1 /*============================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center (DKFZ)
6 All rights reserved.
7 
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
10 
11 ============================================================================*/
12 
13 #ifndef mitkCLUtil_h
14 #define mitkCLUtil_h
15 
16 #include <itkeigen/Eigen/Dense>
17 #include <MitkCLUtilitiesExports.h>
18 #include <itkImageRegionIterator.h>
19 
20 
21 #include <mitkImage.h>
22 #include <mitkImageCast.h>
23 #include <mitkITKImageImport.h>
24 
25 #include <itkConnectedComponentImageFilter.h>
26 namespace mitk
27 {
28 
30 {
31 public:
36  {
38  };
39 
45  static void CreateCheckerboardMask(mitk::Image::Pointer image, mitk::Image::Pointer & outimage);
46 
53  static void InterpolateCheckerboardPrediction(mitk::Image::Pointer checkerboard_prediction, mitk::Image::Pointer & checkerboard_mask, mitk::Image::Pointer & outimage);
54 
60  static void CountVoxel(mitk::Image::Pointer image, std::map<unsigned int, unsigned int> & map);
61 
68  static void CountVoxel(mitk::Image::Pointer image, unsigned int label, unsigned int & count);
69 
75  static void CountVoxel(mitk::Image::Pointer image, unsigned int & count);
76 
84  static void SumVoxelForLabel(mitk::Image::Pointer image, const mitk::Image::Pointer & source , unsigned int label, double & val );
85 
93  static void SqSumVoxelForLabel(mitk::Image::Pointer image, const mitk::Image::Pointer & source, unsigned int label, double & val );
94 
101  static void LogicalAndImages(const Image::Pointer &image1, const Image::Pointer &image2, Image::Pointer &outimage);
102 
103 
110  static void GaussianFilter(mitk::Image::Pointer image, mitk::Image::Pointer & smoothed ,double sigma);
111 
119  static void DifferenceOfGaussianFilter(mitk::Image::Pointer image, mitk::Image::Pointer & smoothed, double sigma1, double sigma2);
120 
127  static void LaplacianOfGaussianFilter(mitk::Image::Pointer image, mitk::Image::Pointer & smoothed, double sigma1);
128 
135  static void HessianOfGaussianFilter(mitk::Image::Pointer image, std::vector<mitk::Image::Pointer> &out, double sigma);
136 
144  static void LocalHistogram(mitk::Image::Pointer image, std::vector<mitk::Image::Pointer> &out, int Bins, int NeighbourhoodSize);
145 
151  template<typename TMatrixElementType>
152  static mitk::Image::Pointer Transform(const Eigen::Matrix<TMatrixElementType, Eigen::Dynamic, Eigen::Dynamic> & matrix, const mitk::Image::Pointer & mask)
153  {
154  itk::Image<unsigned int, 3>::Pointer itkMask;
155  mitk::CastToItkImage(mask,itkMask);
156 
157  typename itk::Image<TMatrixElementType, 3>::Pointer itk_img = itk::Image<TMatrixElementType, 3>::New();
158  itk_img->SetRegions(itkMask->GetLargestPossibleRegion());
159  itk_img->SetOrigin(itkMask->GetOrigin());
160  itk_img->SetSpacing(itkMask->GetSpacing());
161  itk_img->SetDirection(itkMask->GetDirection());
162  itk_img->Allocate();
163 
164 
165  unsigned int n_numSamples = 0;
166  mitk::CLUtil::CountVoxel(mask,n_numSamples);
167 
168  if(n_numSamples != matrix.rows())
169  MITK_ERROR << "Number of samples in matrix and number of points under the masks is not the same!";
170 
171  auto mit = itk::ImageRegionConstIterator<itk::Image<unsigned int, 3> >(itkMask, itkMask->GetLargestPossibleRegion());
172  auto oit = itk::ImageRegionIterator<itk::Image<TMatrixElementType, 3> >(itk_img, itk_img->GetLargestPossibleRegion());
173 
174  unsigned int current_row = 0;
175  while(!mit.IsAtEnd())
176  {
177  if(mit.Value() > 0)
178  oit.Set(matrix(current_row++,0));
179  else
180  oit.Set(0.0);
181  ++mit;
182  ++oit;
183  }
184 
186  mitk::GrabItkImageMemory(itk_img,out_img);
187  return out_img;
188  }
194  template<typename TMatrixElementType>
195  static Eigen::Matrix<TMatrixElementType, Eigen::Dynamic, Eigen::Dynamic> Transform(const mitk::Image::Pointer & img, const mitk::Image::Pointer & mask)
196  {
197  itk::Image<unsigned int, 3>::Pointer current_mask;
198  mitk::CastToItkImage(mask,current_mask);
199 
200  unsigned int n_numSamples = 0;
201  mitk::CLUtil::CountVoxel(mask,n_numSamples);
202 
203  typename itk::Image<TMatrixElementType, 3>::Pointer current_img;
204  mitk::CastToItkImage(img,current_img);
205 
206  Eigen::Matrix<TMatrixElementType, Eigen::Dynamic, Eigen::Dynamic> out_matrix(n_numSamples,1);
207 
208  auto mit = itk::ImageRegionConstIterator<itk::Image<unsigned int, 3> >(current_mask, current_mask->GetLargestPossibleRegion());
209  auto iit = itk::ImageRegionConstIterator<itk::Image<TMatrixElementType, 3> >(current_img,current_img->GetLargestPossibleRegion());
210  unsigned int current_row = 0;
211  while (!mit.IsAtEnd()) {
212  if(mit.Value() > 0)
213  out_matrix(current_row++) = iit.Value();
214  ++mit;
215  ++iit;
216  }
217 
218  return out_matrix;
219  }
220 
228  static void DilateBinary(mitk::Image::Pointer & sourceImage, mitk::Image::Pointer& resultImage, int radius , MorphologicalDimensions d);
229 
237  static void ErodeBinary(mitk::Image::Pointer & sourceImage, mitk::Image::Pointer& resultImage, int radius, MorphologicalDimensions d);
238 
246  static void ClosingBinary(mitk::Image::Pointer & sourceImage, mitk::Image::Pointer& resultImage, int radius, MorphologicalDimensions d);
247 
248 
254  static void MergeLabels(mitk::Image::Pointer & img, const std::map<unsigned int, unsigned int> & map);
255 
263  static void ConnectedComponentsImage(mitk::Image::Pointer & image, mitk::Image::Pointer& mask, mitk::Image::Pointer &outimage, unsigned int& num_components);
264 
271  static void GrabLabel(mitk::Image::Pointer & image, mitk::Image::Pointer & outimage, unsigned int label);
272 
273 
280  static void InsertLabel(mitk::Image::Pointer & image, mitk::Image::Pointer & maskImage, unsigned int label);
281 
289  static void ErodeGrayscale(mitk::Image::Pointer & image, unsigned int radius, mitk::CLUtil::MorphologicalDimensions d, mitk::Image::Pointer & outimage );
290 
298  static void DilateGrayscale(mitk::Image::Pointer & image, unsigned int radius, mitk::CLUtil::MorphologicalDimensions d, mitk::Image::Pointer & outimage );
299 
305  static void FillHoleGrayscale(mitk::Image::Pointer & image, mitk::Image::Pointer & outimage);
306 
314  static void ProbabilityMap(const mitk::Image::Pointer& sourceImage, double mean, double std_dev, mitk::Image::Pointer& resultImage);
315 
316  template<class TImageType>
317  static void itkCountVoxel( TImageType * image, std::map<unsigned int, unsigned int> & map)
318  {
319  auto it = itk::ImageRegionIterator< TImageType >(image,image->GetLargestPossibleRegion());
320  while(!it.IsAtEnd())
321  {
322  if(map.find(it.Value()) == map.end())
323  map[it.Value()] = 0;
324  map[it.Value()]++;
325  ++it;
326  }
327  }
328 
329  template <class TImageType>
330  static void itkCountVoxel(TImageType* image, typename TImageType::PixelType label, unsigned int & count )
331  {
332  itk::ImageRegionConstIterator<TImageType> inputIter(image, image->GetLargestPossibleRegion());
333  while(!inputIter.IsAtEnd())
334  {
335  if(inputIter.Value() == label) ++count;
336  ++inputIter;
337  }
338  }
339 
340  template<typename TImageType>
341  static inline void itkCountVoxel(TImageType * mask, unsigned int & n_numSamples)
342  {
343  auto mit = itk::ImageRegionConstIterator<TImageType>(mask, mask->GetLargestPossibleRegion());
344  while (!mit.IsAtEnd())
345  {
346  if(mit.Value() > 0)
347  n_numSamples++;
348  ++mit;
349  }
350  }
351 
352  template <class TImageType1, class TImageType2>
353  static void itkSampleLabel(TImageType1* image, TImageType2* output, double acceptrate, unsigned int label)
354  {
355  std::srand (time(nullptr));
356 
357  itk::ImageRegionConstIterator< TImageType1 > inputIter(image, image->GetLargestPossibleRegion());
358  itk::ImageRegionIterator< TImageType2 > outputIter(output, output->GetLargestPossibleRegion());
359 
360  while (!inputIter.IsAtEnd())
361  {
362  double r = (double)(rand()) / RAND_MAX;
363  if(inputIter.Get() == label && r < acceptrate)
364  outputIter.Set(label);
365 
366  ++inputIter;
367  ++outputIter;
368  }
369  }
370 
371  template <class TImageType>
372  static void itkSampleLabel(TImageType* image, mitk::Image::Pointer & output, unsigned int n_samples_drawn)
373  {
374  std::srand (time(nullptr));
375 
376  typename TImageType::Pointer itk_out = TImageType::New();
377  itk_out->SetRegions(image->GetLargestPossibleRegion());
378  itk_out->SetDirection(image->GetDirection());
379  itk_out->SetOrigin(image->GetOrigin());
380  itk_out->SetSpacing(image->GetSpacing());
381  itk_out->Allocate();
382  itk_out->FillBuffer(0);
383 
384  itk::ImageRegionConstIterator< TImageType > inputIter(image, image->GetLargestPossibleRegion());
385  itk::ImageRegionIterator< TImageType > outputIter(itk_out, itk_out->GetLargestPossibleRegion());
386 
387  for(unsigned int i = 0 ; i < n_samples_drawn ;)
388  {
389  double r = (double)(rand()) / RAND_MAX;
390  if(inputIter.Value() != 0 && r < 0.01 && outputIter.Value() == 0)
391  {
392  outputIter.Set(inputIter.Value());
393  i++;
394  }
395  ++inputIter;
396  ++outputIter;
397 
398  if(inputIter.IsAtEnd())
399  {
400  inputIter.GoToBegin();
401  outputIter.GoToBegin();
402  }
403 
404  }
405 
406  mitk::CastToMitkImage(itk_out, output);
407  }
408 
409 private:
410 
411  template<class TImageType>
412  static void itkErodeGrayscale(TImageType * image, mitk::Image::Pointer & outimage , unsigned int radius, mitk::CLUtil::MorphologicalDimensions d);
413 
414  template<class TImageType>
415  static void itkDilateGrayscale(TImageType * image, mitk::Image::Pointer & outimage , unsigned int radius, mitk::CLUtil::MorphologicalDimensions d);
416 
417  template<class TImageType>
418  static void itkFillHoleGrayscale(TImageType * image, mitk::Image::Pointer & outimage);
419 
420  template< typename TImageType >
421  static void itkInsertLabel(TImageType * maskImage, mitk::Image::Pointer & outimage, unsigned int label)
422  {
423 
424  typename TImageType::Pointer itk_out;
425 
426  if(outimage.IsNull()) // create if necessary
427  {
428  MITK_INFO << "Initialize new image";
429  itk_out = TImageType::New();
430  itk_out->SetSpacing(maskImage->GetSpacing());
431  itk_out->SetDirection(maskImage->GetDirection());
432  itk_out->SetOrigin(maskImage->GetOrigin());
433  itk_out->SetRegions(maskImage->GetLargestPossibleRegion());
434  itk_out->Allocate();
435  itk_out->FillBuffer(0);
436  }else
437  {
438  mitk::CastToItkImage(outimage, itk_out);
439  }
440 
441  itk::ImageRegionIterator<TImageType> oit(itk_out,itk_out->GetLargestPossibleRegion());
442  itk::ImageRegionConstIterator<TImageType> mit(maskImage,maskImage->GetLargestPossibleRegion());
443 
444  while(!mit.IsAtEnd())
445  {
446  if(mit.Value() != 0)
447  {
448  oit.Set(label);
449  }
450  ++oit;
451  ++mit;
452  }
453 
454  mitk::CastToMitkImage(itk_out,outimage);
455  }
456 
457 
458  template< typename TImageType >
459  static void itkGrabLabel(TImageType * image, mitk::Image::Pointer & outimage, unsigned int label)
460  {
461  typedef itk::Image<unsigned short, 3> TOutType;
462  TOutType::Pointer itk_out = TOutType::New();
463  itk_out->SetRegions(image->GetLargestPossibleRegion());
464  itk_out->SetDirection(image->GetDirection());
465  itk_out->SetOrigin(image->GetOrigin());
466  itk_out->SetSpacing(image->GetSpacing());
467  itk_out->Allocate();
468 
469  itk::ImageRegionConstIterator<TImageType> iit(image, image->GetLargestPossibleRegion());
470  itk::ImageRegionIterator<TOutType> oit(itk_out,itk_out->GetLargestPossibleRegion());
471 
472  while(!iit.IsAtEnd())
473  {
474  if(iit.Value() == static_cast<typename TImageType::PixelType>(label))
475  oit.Set(1);
476  else
477  oit.Set(0);
478 
479  ++iit;
480  ++oit;
481  }
482 
483  mitk::CastToMitkImage(itk_out, outimage);
484  }
485 
486  template<class TImagetype>
487  static void itkMergeLabels(TImagetype * img, const std::map<unsigned int, unsigned int> & map)
488  {
489 
490  auto it = itk::ImageRegionIterator<TImagetype>(img,img->GetLargestPossibleRegion());
491 
492  while(!it.IsAtEnd())
493  {
494  if(map.find(it.Value())!=map.end())
495  it.Set( map.at(it.Value()) );
496  ++it;
497  }
498 
499  }
500 
501  template<typename TImageType>
502  static void itkConnectedComponentsImage(TImageType * image, mitk::Image::Pointer& mask, mitk::Image::Pointer &outimage, unsigned int& num_components)
503  {
504  typedef itk::Image<unsigned short, 3> MaskImageType;
505  MaskImageType::Pointer itk_mask;
506  if(mask.IsNull())
507  {
508  itk_mask = MaskImageType::New();
509  itk_mask->SetRegions(image->GetLargestPossibleRegion());
510  itk_mask->SetDirection(image->GetDirection());
511  itk_mask->SetOrigin(image->GetOrigin());
512  itk_mask->SetSpacing(image->GetSpacing());
513  itk_mask->Allocate();
514  itk_mask->FillBuffer(1);
515  }else{
516  mitk::CastToItkImage(mask,itk_mask);
517  }
518 
519  typedef itk::ConnectedComponentImageFilter<TImageType, MaskImageType, MaskImageType > FilterType;
520  typename FilterType::Pointer cc_filter = FilterType::New();
521  cc_filter->SetMaskImage(itk_mask.GetPointer());
522  cc_filter->SetInput(image);
523  cc_filter->SetBackgroundValue(0);
524  cc_filter->Update();
525 
526  num_components = cc_filter->GetObjectCount();
527  mitk::CastToMitkImage(cc_filter->GetOutput(), outimage);
528  }
529 
530  template< typename TImageType >
531  static void itkCreateCheckerboardMask(TImageType * image, mitk::Image::Pointer & outimage);
532 
533  template< typename TImageType >
534  static void itkInterpolateCheckerboardPrediction(TImageType * checkerboard_prediction, mitk::Image::Pointer & checkerboard_mask, mitk::Image::Pointer & outimage);
535 
536  template <class TImageType>
537  static void itkSumVoxelForLabel(TImageType* image, const mitk::Image::Pointer & source , typename TImageType::PixelType label, double & val );
538 
539  template <class TImageType>
540  static void itkSqSumVoxelForLabel(TImageType* image, const mitk::Image::Pointer & source, typename TImageType::PixelType label, double & val );
541 
542  template<typename TStructuringElement>
543  static void itkFitStructuringElement(TStructuringElement & se, MorphologicalDimensions d, int radius);
544 
545  template<typename TImageType>
546  static void itkDilateBinary(TImageType * sourceImage, mitk::Image::Pointer& resultImage, int radius , MorphologicalDimensions d);
547 
548  template<typename TImageType>
549  static void itkErodeBinary(TImageType * sourceImage, mitk::Image::Pointer& resultImage, int radius, MorphologicalDimensions d);
550 
551  template<typename TImageType>
552  static void itkClosingBinary(TImageType * sourceImage, mitk::Image::Pointer& resultImage, int radius, MorphologicalDimensions d);
553 
554  template<typename TPixel, unsigned int VDimension>
555  static void itkFillHolesBinary(itk::Image<TPixel, VDimension>* sourceImage, mitk::Image::Pointer& resultImage);
556 
557  template<typename TImageType>
558  static void itkLogicalAndImages(const TImageType * image1, const mitk::Image::Pointer & image2, mitk::Image::Pointer & outimage);
559 
560  template<class TImageType>
561  static void itkGaussianFilter(TImageType * image, mitk::Image::Pointer & smoothed ,double sigma);
562 
563  template<class TImageType>
564  static void itkDifferenceOfGaussianFilter(TImageType * image, mitk::Image::Pointer & smoothed, double sigma1, double sigma2);
565 
566  template<typename TImageType>
567  static void itkProbabilityMap(const TImageType * sourceImage, double mean, double std_dev, mitk::Image::Pointer& resultImage);
568 
569  template<typename TPixel, unsigned int VImageDimension>
570  static void itkHessianOfGaussianFilter(itk::Image<TPixel, VImageDimension>* itkImage, double variance, std::vector<mitk::Image::Pointer> &out);
571 
572  template<typename TPixel, unsigned int VImageDimension>
573  static void itkLaplacianOfGaussianFilter(itk::Image<TPixel, VImageDimension>* itkImage, double variance, mitk::Image::Pointer &output);
574 
575  template<typename TPixel, unsigned int VImageDimension>
576  static void itkLocalHistograms(itk::Image<TPixel, VImageDimension>* itkImage, std::vector<mitk::Image::Pointer> &out, int size, int bins);
577 };
578 
579 } //namespace MITK
580 
581 #endif
MITKCLUTILITIES_EXPORT
#define MITKCLUTILITIES_EXPORT
Definition: MitkCLUtilitiesExports.h:15
mitk::GrabItkImageMemory
Image::Pointer GrabItkImageMemory(itk::SmartPointer< ItkOutputImageType > &itkimage, mitk::Image *mitkImage=nullptr, const BaseGeometry *geometry=nullptr, bool update=true)
Grabs the memory of an itk::Image (with a specific type) and puts it into an mitk::Image.
mitk::AnatomicalPlane::Coronal
@ Coronal
MITK_INFO
#define MITK_INFO
Definition: mitkLog.h:209
mitkImage.h
mitk::Image::New
static Pointer New()
mitk::CLUtil::itkSampleLabel
static void itkSampleLabel(TImageType1 *image, TImageType2 *output, double acceptrate, unsigned int label)
Definition: mitkCLUtil.h:353
mitkImageCast.h
mitk::CLUtil::itkSampleLabel
static void itkSampleLabel(TImageType *image, mitk::Image::Pointer &output, unsigned int n_samples_drawn)
Definition: mitkCLUtil.h:372
mitk::CLUtil::itkCountVoxel
static void itkCountVoxel(TImageType *image, typename TImageType::PixelType label, unsigned int &count)
Definition: mitkCLUtil.h:330
mitk::CLUtil::CountVoxel
static void CountVoxel(mitk::Image::Pointer image, std::map< unsigned int, unsigned int > &map)
CountVoxel.
MITK_ERROR
#define MITK_ERROR
Definition: mitkLog.h:211
itk::SmartPointer
Definition: mitkIFileReader.h:30
mitk::CastToMitkImage
void CastToMitkImage(const itk::SmartPointer< ItkOutputImageType > &itkimage, itk::SmartPointer< mitk::Image > &mitkoutputimage)
Cast an itk::Image (with a specific type) to an mitk::Image.
Definition: mitkImageCast.h:74
mitk
Find image slices visible on a given plane.
Definition: RenderingTests.dox:1
mitk::CLUtil::Transform
static Eigen::Matrix< TMatrixElementType, Eigen::Dynamic, Eigen::Dynamic > Transform(const mitk::Image::Pointer &img, const mitk::Image::Pointer &mask)
TransformImageToMatrix.
Definition: mitkCLUtil.h:195
mitk::CLUtil
Definition: mitkCLUtil.h:29
mitk::AnatomicalPlane::Axial
@ Axial
mitk::CLUtil::MorphologicalDimensions
MorphologicalDimensions
The MorphologicalDimensions enum.
Definition: mitkCLUtil.h:35
mitk::CastToItkImage
void MITKCORE_EXPORT CastToItkImage(const mitk::Image *mitkImage, itk::SmartPointer< ItkOutputImageType > &itkOutputImage)
Cast an mitk::Image to an itk::Image with a specific type.
mitkITKImageImport.h
mitk::CLUtil::itkCountVoxel
static void itkCountVoxel(TImageType *image, std::map< unsigned int, unsigned int > &map)
Definition: mitkCLUtil.h:317
mitk::CLUtil::Transform
static mitk::Image::Pointer Transform(const Eigen::Matrix< TMatrixElementType, Eigen::Dynamic, Eigen::Dynamic > &matrix, const mitk::Image::Pointer &mask)
transform
Definition: mitkCLUtil.h:152
map
Definition: mitkFastSymmetricForcesDemonsMultiResDefaultRegistrationAlgorithm_ProfileResource.h:26
mitk::CLUtil::itkCountVoxel
static void itkCountVoxel(TImageType *mask, unsigned int &n_numSamples)
Definition: mitkCLUtil.h:341
MitkCLUtilitiesExports.h
mitk::CLUtil::Sagittal
@ Sagittal
Definition: mitkCLUtil.h:37