CBICA Toolkit  1.0.0
cbicaITKUtilities.h
Go to the documentation of this file.
1 /**
2 \file cbicaITKUtilities.h
3 
4 \brief Some basic utility functions.
5 
6 Dependecies: ITK (module_review, module_skullstrip enabled), OpenMP
7 
8 https://www.cbica.upenn.edu/sbia/software/ <br>
9 software@cbica.upenn.edu
10 
11 Copyright (c) 2015 University of Pennsylvania. All rights reserved. <br>
12 See COPYING file or https://www.cbica.upenn.edu/sbia/software/license.html
13 
14 */
15 #pragma once
16 
17 #include <algorithm>
18 #include <functional>
19 #include <cmath>
20 #ifdef _OPENMP
21 #include <omp.h>
22 #endif
23 
24 #include "itkImage.h"
25 #include "itkImageRegionConstIterator.h"
26 #include "itkImageRegionConstIteratorWithIndex.h"
27 #include "itkImageRegionIterator.h"
28 
29 #include "itkHistogramMatchingImageFilter.h"
30 #include "itkAdaptiveHistogramEqualizationImageFilter.h"
31 
32 #include "itkConnectedThresholdImageFilter.h"
33 #include "itkOrientImageFilter.h"
34 #include "itkResampleImageFilter.h"
35 #include "itkIdentityTransform.h"
36 
37 //#include "itkMultiResolutionPDEDeformableRegistration.h"
38 //#include "itkDemonsRegistrationFilter.h"
39 //#include "itkDiffeomorphicDemonsRegistrationFilter.h"
40 //#include "itkFastSymmetricForcesDemonsRegistrationFilter.h"
41 //#include "itkSymmetricForcesDemonsRegistrationFilter.h"
42 
43 #include "itkLinearInterpolateImageFunction.h"
44 #include "itkBSplineInterpolateImageFunction.h"
45 #include "itkNearestNeighborInterpolateImageFunction.h"
46 //#include "itkWindowedSincInterpolateImageFunction.h"
47 
48 #include "itkTestingComparisonImageFilter.h"
49 
50 #include "itkStripTsImageFilter.h"
51 #include "itkMaskImageFilter.h"
52 
53 #include "cbicaUtilities.h"
54 #include "cbicaITKImageInfo.h"
55 
56 #include "gdcmMD5.h"
57 #include "gdcmReader.h"
58 
59 #include "DicomIOManager.h"
60 
61 using ImageTypeFloat3D = itk::Image< float, 3 >;
62 //unsigned int RmsCounter = 0;
63 //double MaxRmsE[4] = { 0.8, 0.75, 0.4, 0.2 };
64 
65 enum DeformRegType
66 {
67  Demons, DiffeomorphicDemons, SymmetricForcesDemons, FastSymmetricForcesDemons
68 };
69 
70 enum InterpolatorType
71 {
72  Linear, NearestNeighbor, BSpline
73 };
74 
75 /*
76 \namespace cbica
77 \brief Namespace for differentiating functions written for internal use
78 */
79 namespace cbica
80 {
81  /**
82  \brief Calculate and preserve the mask indeces
83 
84  \param inputModalitiesAndImages A collection of images which are stored in a per-modality basis (each entry corresponds to a subject, whose entries contain different modalities)
85  \return A collection of indeces which constitute the non-zero locations per modality (each entry corresponds to a subject, which contains the locations of non-zero pixel values for all modalities)
86  */
87  template< class TImageType = ImageTypeFloat3D >
88  std::vector< std::vector< typename TImageType::IndexType > > CreateMaskIndeces(const std::vector< std::vector< typename TImageType::Pointer > > &inputModalitiesAndImages)
89  {
90  std::vector< std::vector< typename TImageType::IndexType > > returnMaskIndeces;
91  returnMaskIndeces.resize(inputModalitiesAndImages.size()); // pre-allocate data for speed
92 
93  // start data processing
94  // made parallel for efficiency
95  int threads = omp_get_max_threads(); // obtain maximum number of threads available on machine
96  //threads > inputModalitiesAndImages.size() ? threads = inputModalitiesAndImages.size() : threads = threads;
97  //#pragma omp parallel for num_threads(threads)
98  for (int i = 0; i < inputModalitiesAndImages.size(); i++)
99  {
100  std::vector< float > means;
101  std::vector< typename TImageType::IndexType > tempIndeces;
102  typename TImageType::SizeType size = inputModalitiesAndImages[i][0]->GetLargestPossibleRegion().GetSize();
103  size_t totalImageSize = size[0] * size[1] * size[2];
104  means.resize(totalImageSize);
105  //std::fill(means.begin(), means.end(), 0);
106  means.assign(totalImageSize, 0);
107 
108  for (size_t j = 0; j < inputModalitiesAndImages[i].size(); j++)
109  {
110  std::vector< float > tempVec;
111  itk::ImageRegionIterator< TImageType > it(inputModalitiesAndImages[i][j], inputModalitiesAndImages[i][j]->GetLargestPossibleRegion());
112  it.GoToBegin();
113 
114  while (!it.IsAtEnd())
115  {
116  tempVec.push_back(it.Get());
117  tempIndeces.push_back(it.GetIndex());
118  ++it;
119  }
120  if (tempVec.size() == means.size())
121  {
122  std::transform(means.begin(), means.end(), tempVec.begin(), means.begin(), std::plus< float >()); // add tempVec to means dector
123  }
124  else
125  {
126  std::cerr << "Mean vector calculation error.\n";
127  exit(EXIT_FAILURE);
128  }
129  } // loop over all subjects in each modality
130 
131  //std::transform(means.begin(), means.end(), means.begin(), std::bind1st(std::divides< float >(), means.size())); // divide entire means vector by its size
132  std::vector< typename TImageType::IndexType > tempMaskIndeces;
133  for (size_t j = 0; j < means.size(); j++)
134  {
135  if (means[j] > 0)
136  {
137  tempMaskIndeces.push_back(tempIndeces[j]); // store indeces of non-zero mean values
138  }
139  }
140  returnMaskIndeces[i] = tempMaskIndeces;
141  } // loop over all modalities
142 
143  return returnMaskIndeces;
144  }
145 
146  /**
147  \brief Get Pixel Values of specified indeces of input Image
148 
149  \param inputImage The input image in itk::Image format
150  \param indeced The indeces from which pixel values need to be extracted
151  \return Vector of values whose data type is the same as image type
152  */
153  template < typename TImageType = ImageTypeFloat3D >
154  std::vector< typename TImageType::PixelType > GetPixelValuesFromIndeces(const typename TImageType::Pointer inputImage, const std::vector< typename TImageType::IndexType > &indeces)
155  {
156  std::vector< typename TImageType::PixelType > returnVector;
157  returnVector.resize(indeces.size()); // pre-allocation done for speed
158 
159  typedef itk::ImageRegionIterator< TImageType > IteratorType;
160  IteratorType imageIterator(inputImage, inputImage->GetBufferedRegion());
161 
162  // made parallel for efficiency
163  int threads = omp_get_max_threads(); // obtain maximum number of threads available on machine
164  //threads > returnVector.size() ? threads = returnVector.size() : threads = threads;
165  //#pragma omp parallel for num_threads(threads)
166  for (int i = 0; i < returnVector.size(); i++)
167  {
168  imageIterator.SetIndex(indeces[i]);
169  returnVector[i] = imageIterator.Get();
170  }
171 
172  return returnVector;
173  }
174 
175  /**
176  \brief Wrap of GetPixelValues
177  */
178  template < typename TImageType = ImageTypeFloat3D >
179  std::vector< typename TImageType::PixelType > ExtractPixelValuesFromIndeces(const typename TImageType::Pointer inputImage, const std::vector< typename TImageType::IndexType > &indeces)
180  {
181  return GetPixelValuesFromIndeces< TImageType >(inputImage, indeces);
182  }
183 
184  ///**
185  //\brief Get MD5 sum of a supplied file
186 
187  //\param fileName The input file
188  //\return The MD5 checksum
189  //*/
190  //inline std::string GetMD5Sum(const std::string &fileName)
191  //{
192  // gdcm::MD5 md5Computer;
193  // char digStr[1024/*MAX_PATH*/];
194  // md5Computer.ComputeFile(fileName.c_str(), digStr);
195  // return std::string(digStr);
196  //}
197 
198  ///**
199  //\brief Wrap of GetMD5Sum()
200  //*/
201  //inline std::string ComputeMD5Sum(const std::string &fileName)
202  //{
203  // return GetMD5Sum(fileName);
204  //}
205 
206  /**
207  \brief Get the indeces of the image which are not zero
208  */
209  template < typename TImageType = ImageTypeFloat3D >
210  std::vector< typename TImageType::IndexType > GetIndexFromNonZeroPixels(const typename TImageType::Pointer inputImage, const std::string valuesToExclude = "0")
211  {
212  std::vector< typename TImageType::IndexType > returnVector;
213 
214  itk::ImageRegionConstIterator< TImageType > iterator(inputImage, inputImage->GetLargestPossibleRegion());
215  for (iterator.GoToBegin(); !iterator.IsAtEnd(); ++iterator)
216  {
217  if (iterator.Get() != 0)
218  {
219  returnVector.push_back(iterator.GetIndex());
220  }
221  }
222 
223  return returnVector;
224  }
225 
226  /**
227  \brief Get the indeces of the image which are not zero
228 
229  \param inputImage The input image on which the matching needs to be done
230  \param referenceImage The reference image based on which the
231  \param numberOfMatchPoints Governs the number of quantile values to be matched
232  \param numberOfHistogramLevels Sets the number of bins used when creating histograms of the source and reference images
233  */
234  template < typename TImageType = ImageTypeFloat3D >
235  typename TImageType::Pointer GetHistogramMatchedImage(const typename TImageType::Pointer inputImage, const typename TImageType::Pointer referenceImage,
236  const int numberOfMatchPoints = 40, const int numberOfHistogramLevels = 100)
237  {
238  auto filter = itk::HistogramMatchingImageFilter< TImageType, TImageType >::New();
239  filter->SetInput(inputImage);
240  filter->SetReferenceImage(referenceImage);
241  if (numberOfHistogramLevels != 100)
242  {
243  filter->SetNumberOfHistogramLevels(numberOfHistogramLevels);
244  }
245  filter->ThresholdAtMeanIntensityOn();
246  filter->SetNumberOfMatchPoints(numberOfMatchPoints);
247  filter->Update();
248 
249  return filter->GetOutput();
250  }
251 
252  /**
253  \brief Get the indeces of the image which are not zero
254 
255  \param inputImage The input image on which the matching needs to be done
256  \param referenceImage The reference image based on which the
257  \param alpha Ranges between 0-1; with 1 giving result same as input image and lower values behaving as unsharp filters; default = 0.3
258  \param beta Ranges between 0-1; with 1 giving result same as input image and lower values behaving as unsharp filters; default = 0.3
259  \param radius Ranges between 1-10 with default = 1
260  */
261  template < typename TImageType = ImageTypeFloat3D >
262  typename TImageType::Pointer GetAdaptiveHistogramEqualizedImage(const typename TImageType::Pointer inputImage, const typename TImageType::Pointer referenceImage,
263  const float alpha = 0.3, const float beta = 0.3, const float radius = 1, const int numberOfHistogramLevels = 100)
264  {
265  auto filter = itk::AdaptiveHistogramEqualizationImageFilter< TImageType, TImageType >::New();
266  filter->SetInput(inputImage);
267  filter->SetAlpha(alpha);
268  filter->SetBeta(beta);
269  filter->SetRadius(radius);
270  filter->Update();
271 
272  return filter->GetOutput();
273  }
274 
275  /**
276  \brief Get result of Image comparison between 2 images
277 
278  This runs itk::Testing::ComparisonImageFilter inside so the inputs are identical. Always updates the largest possible region.
279 
280  \param referenceImage The reference image for comparison
281  \param checkImage The image to check
282  \param differenceThreshold The minimum number of different pixels among both images; default is 0
283  \param toleranceRadius The maximum distance to look for a matching pixel; default is 0
284  \param numberOfPixelsTolerance The maximum maximum number of pixels that can be different; default is 10
285  \param averageIntensityDifference The maximum allowed average intensity difference between both images; default is 0
286  \return True if images are similar in accordance with passed parameters
287  */
288  template< class TImageType = ImageTypeFloat3D >
289  bool GetResultOfImageComparasion(const typename TImageType::Pointer referenceImage, const typename TImageType::Pointer checkImage,
290  const typename TImageType::PixelType differenceThreshold = 0, const unsigned int toleranceRadius = 0,
291  const unsigned long long numberOfPixelsTolerance = 10, const typename TImageType::PixelType averageIntensityDifference = 0)
292  {
293  // check if sizes are different - that is a clear indicator that the images are NOT similar
294  if (referenceImage->GetLargestPossibleRegion().GetSize() != checkImage->GetLargestPossibleRegion().GetSize())
295  {
296  return false;
297  }
298 
299  // initialize the comparator
300  auto diff = itk::Testing::ComparisonImageFilter< TImageType, TImageType >::New();
301  diff->SetValidInput(referenceImage);
302  diff->SetTestInput(checkImage);
303  diff->SetDifferenceThreshold(differenceThreshold);
304  diff->SetToleranceRadius(toleranceRadius);
305  diff->UpdateLargestPossibleRegion();
306 
307  // check for different conditions
308  if (static_cast<typename TImageType::PixelType>(diff->GetTotalDifference()) > averageIntensityDifference)
309  {
310  // if there is an appreciable intensity difference between the images, check the number of difference pixels
311  if (diff->GetNumberOfPixelsWithDifferences() > numberOfPixelsTolerance)
312  {
313  return false;
314  }
315  }
316 
317  return true;
318  }
319 
320  /**
321  \brief Check properties of 2 images to see if they are defined in the same space.
322  */
323  template< typename TImageType >
324  inline bool ImageSanityCheck(const typename TImageType::Pointer image1, const typename TImageType::Pointer image2)
325  {
326  auto size_1 = image1->GetLargestPossibleRegion().GetSize();
327  auto size_2 = image2->GetLargestPossibleRegion().GetSize();
328 
329  auto origin_1 = image1->GetOrigin();
330  auto origin_2 = image2->GetOrigin();
331 
332  auto spacing_1 = image1->GetSpacing();
333  auto spacing_2 = image2->GetSpacing();
334 
335  for (size_t i = 0; i < TImageType::ImageDimension; i++)
336  {
337  if (size_1[i] != size_2[i])
338  {
339  std::cerr << "Size mismatch at dimension '" << i << "'\n";
340  return false;
341  }
342  if (origin_1[i] != origin_2[i])
343  {
344  std::cerr << "Origin mismatch at dimension '" << i << "'\n";
345  return false;
346  }
347  if (spacing_1[i] != spacing_2[i])
348  {
349  std::cerr << "Spacing mismatch at dimension '" << i << "'\n";
350  return false;
351  }
352  }
353 
354  return true;
355  }
356 
357  /**
358  \brief Check properties of 2 images to see if they are defined in the same space.
359 
360  Checks are done based on cbica::ImageInfo class
361  */
362  inline bool ImageSanityCheck(const std::string &image1, const std::string &image2)
363  {
364  auto imageInfo1 = cbica::ImageInfo(image1);
365  auto imageInfo2 = cbica::ImageInfo(image2);
366 
367  if (imageInfo1.GetImageDimensions() != imageInfo2.GetImageDimensions())
368  {
369  std::cout << "The dimensions of the image_1 (" << image1 << ") and image_2 (" << image2 << ") doesn't match.\n";
370  return false;
371  }
372 
373  // check size, spacing and origin information as well
374  auto dims = imageInfo1.GetImageDimensions();
375 
376  auto imageSize1 = imageInfo1.GetImageSize();
377  auto imageSize2 = imageInfo2.GetImageSize();
378 
379  auto imageSpacing1 = imageInfo1.GetImageSpacings();
380  auto imageSpacing2 = imageInfo2.GetImageSpacings();
381 
382  auto imageOrigin1 = imageInfo1.GetImageOrigins();
383  auto imageOrigin2 = imageInfo2.GetImageOrigins();
384 
385  for (size_t d = 0; d < dims; d++)
386  {
387  if (imageSize1[d] != imageSize2[d])
388  {
389  std::cout << "The size in dimension[" << d << "] of the image_1 (" << image1 << ") and image_2 (" << image2 << ") doesn't match.\n";
390  return false;
391  }
392  if (imageSpacing1[d] != imageSpacing2[d])
393  {
394  std::cout << "The spacing in dimension[" << d << "] of the image_1 (" << image1 << ") and image_2 (" << image2 << ") doesn't match.\n";
395  return false;
396  }
397  if (imageOrigin1[d] != imageOrigin2[d])
398  {
399  std::cout << "The origin in dimension[" << d << "] of the image_1 (" << image1 << ") and image_2 (" << image2 << ") doesn't match.\n";
400  return false;
401  }
402  }
403 
404  return true;
405  }
406 
407  /**
408  \brief Perform the deformable registration
409 
410  \param movingImage The moving image for registration
411  \param referenceImage The reference image for registration
412  \param multiResLevels Number of multi-resolution levels for registration, defaults to 5
413  \param iterationStart Start size of iteration for first multiResLevel, defaults to 10
414  \param iterationStep Step size of the iterations increasing over each MultiResLevel, defaults to 10
415  \param iterationEnd End size of iteration for first multiResLevel, defaults to 50
416  \param regType The type of registration to perform, defaults to 'Demons'
417  \param interpolatorType The type of interpolator to use, defaults to 'Linear'
418  */
419  /*template< class TImageType = ImageTypeFloat3D >
420  typename TImageType::Pointer GetDeformRegisteredImage(const typename TImageType::Pointer movingImage, const typename TImageType::Pointer referenceImage,
421  const unsigned int multiResLevels = 5,
422  const unsigned int iterationStart = 10, const unsigned int iterationStep = 10, const unsigned int iterationEnd = 50,
423  const int regType = Demons, const int interpolatorType = Linear)
424  {
425  // do histogram matchin of the 2 images
426  auto movingImage_histoMatched = GetHistogramMatchedImage< TImageType >(movingImage, referenceImage, 40, 1024);
427 
428  // setup the displacement field
429  using VectorPixelType = itk::Vector< float, TImageType::ImageDimension >;
430  using DisplacementFieldType = itk::Image< VectorPixelType, TImageType::ImageDimension >;
431 
432  auto multiRes = typename itk::MultiResolutionPDEDeformableRegistration< TImageType, TImageType, DisplacementFieldType >::New();
433 
434  // set the registration type
435  switch (regType)
436  {
437  case DiffeomorphicDemons:
438  {
439  auto filter = typename itk::DiffeomorphicDemonsRegistrationFilter< TImageType, TImageType, DisplacementFieldType >::New();
440  filter->SetStandardDeviations(1.0);
441  multiRes->SetRegistrationFilter(filter);
442  break;
443  }
444  case SymmetricForcesDemons:
445  {
446  auto filter = typename itk::SymmetricForcesDemonsRegistrationFilter< TImageType, TImageType, DisplacementFieldType >::New();
447  filter->SetStandardDeviations(1.0);
448  multiRes->SetRegistrationFilter(filter);
449  break;
450  }
451  case FastSymmetricForcesDemons:
452  {
453  auto filter = typename itk::FastSymmetricForcesDemonsRegistrationFilter< TImageType, TImageType, DisplacementFieldType >::New();
454  filter->SetStandardDeviations(1.0);
455  multiRes->SetRegistrationFilter(filter);
456  break;
457  }
458  default: // does Demons
459  {
460  auto filter = typename itk::DemonsRegistrationFilter< TImageType, TImageType, DisplacementFieldType >::New();
461  filter->SetStandardDeviations(1.0);
462  multiRes->SetRegistrationFilter(filter);
463  break;
464  }
465  }
466 
467  // set the different parameters of the multi resolution registration
468  multiRes->SetNumberOfLevels(multiResLevels);
469  multiRes->SetFixedImage(referenceImage);
470  multiRes->SetMovingImage(movingImage_histoMatched);
471 
472  // set up the iterations
473  std::vector< unsigned int > iterations_vector;
474  for (size_t i = iterationStart; i <= iterationEnd; i += iterationStep)
475  {
476  iterations_vector.push_back(i);
477  }
478  unsigned int *iterations_array = &iterations_vector[0];
479  multiRes->SetNumberOfIterations(iterations_array);
480 
481  // start the regisration
482  try
483  {
484  multiRes->Update();
485  }
486  catch (itk::ExceptionObject & excp)
487  {
488  std::cerr << excp << std::endl;
489  return referenceImage;
490  }
491 
492  // warp the moving image
493  auto warper = typename itk::WarpImageFilter< TImageType, TImageType, DisplacementFieldType >::New();
494  warper->SetInput(movingImage);
495  warper->SetOutputSpacing(referenceImage->GetSpacing());
496  warper->SetOutputOrigin(referenceImage->GetOrigin());
497  warper->SetOutputDirection(referenceImage->GetDirection());
498  warper->SetDisplacementField(multiRes->GetOutput());
499 
500  // set up the interpolator type
501  switch (interpolatorType)
502  {
503  case NearestNeighbor:
504  {
505  auto interpolator = typename itk::NearestNeighborInterpolateImageFunction< TImageType, double >::New();
506  warper->SetInterpolator(interpolator);
507  break;
508  }
509  case BSpline:
510  {
511  auto interpolator = typename itk::BSplineInterpolateImageFunction< TImageType, double >::New();
512  warper->SetInterpolator(interpolator);
513  break;
514  }
515  default: // linear by default
516  {
517  auto interpolator = typename itk::LinearInterpolateImageFunction< TImageType, double >::New();
518  warper->SetInterpolator(interpolator);
519  break;
520  }
521  }
522 
523  // perform the warping
524  try
525  {
526  warper->Update();
527  }
528  catch (itk::ExceptionObject & excp)
529  {
530  std::cerr << excp << std::endl;
531  return referenceImage;
532  }
533 
534  return warper->GetOutput();
535  }*/
536 
537  /**
538  \brief Get the image orientation
539 
540  \param inputImage The input image
541  \return A pair of string (which represents the orientation) and an itk::Image which represents the inputImage in RAI form
542  */
543  template< class TImageType = ImageTypeFloat3D >
544  std::pair< std::string, typename TImageType::Pointer > GetImageOrientation(const typename TImageType::Pointer inputImage)
545  {
546  using namespace itk::SpatialOrientation;
547  auto orientFilter = itk::OrientImageFilter< TImageType, TImageType >::New();
548  orientFilter->SetInput(inputImage);
549  orientFilter->SetDesiredCoordinateOrientation(ITK_COORDINATE_ORIENTATION_RAI);
550  orientFilter->Update();
551 
552  std::string returnString;
553 
554  switch (orientFilter->GetGivenCoordinateOrientation())
555  {
556  case ITK_COORDINATE_ORIENTATION_RIP:
557  {
558  returnString = "RIP";
559  break;
560  }
561  case ITK_COORDINATE_ORIENTATION_LIP:
562  {
563  returnString = "LIP";
564  break;
565  }
566  case ITK_COORDINATE_ORIENTATION_RSP:
567  {
568  returnString = "RSP";
569  break;
570  }
571  case ITK_COORDINATE_ORIENTATION_LSP:
572  {
573  returnString = "LSP";
574  break;
575  }
576  case ITK_COORDINATE_ORIENTATION_RIA:
577  {
578  returnString = "RIA";
579  break;
580  }
581  case ITK_COORDINATE_ORIENTATION_LIA:
582  {
583  returnString = "LIA";
584  break;
585  }
586  case ITK_COORDINATE_ORIENTATION_LSA:
587  {
588  returnString = "LSA";
589  break;
590  }
591  case ITK_COORDINATE_ORIENTATION_IRP:
592  {
593  returnString = "IRP";
594  break;
595  }
596  case ITK_COORDINATE_ORIENTATION_ILP:
597  {
598  returnString = "ILP";
599  break;
600  }
601  case ITK_COORDINATE_ORIENTATION_SRP:
602  {
603  returnString = "SRP";
604  break;
605  }
606  case ITK_COORDINATE_ORIENTATION_SLP:
607  {
608  returnString = "SLP";
609  break;
610  }
611  case ITK_COORDINATE_ORIENTATION_IRA:
612  {
613  returnString = "IRA";
614  break;
615  }
616  case ITK_COORDINATE_ORIENTATION_ILA:
617  {
618  returnString = "ILA";
619  break;
620  }
621  case ITK_COORDINATE_ORIENTATION_SRA:
622  {
623  returnString = "SRA";
624  break;
625  }
626  case ITK_COORDINATE_ORIENTATION_SLA:
627  {
628  returnString = "SLA";
629  break;
630  }
631  case ITK_COORDINATE_ORIENTATION_RPI:
632  {
633  returnString = "RPI";
634  break;
635  }
636  case ITK_COORDINATE_ORIENTATION_LPI:
637  {
638  returnString = "LPI";
639  break;
640  }
641  case ITK_COORDINATE_ORIENTATION_RAI:
642  {
643  returnString = "RAI";
644  break;
645  }
646  case ITK_COORDINATE_ORIENTATION_LAI:
647  {
648  returnString = "LAI";
649  break;
650  }
651  case ITK_COORDINATE_ORIENTATION_RPS:
652  {
653  returnString = "RPS";
654  break;
655  }
656  case ITK_COORDINATE_ORIENTATION_LPS:
657  {
658  returnString = "LPS";
659  break;
660  }
661  case ITK_COORDINATE_ORIENTATION_RAS:
662  {
663  returnString = "RAS";
664  break;
665  }
666  case ITK_COORDINATE_ORIENTATION_LAS:
667  {
668  returnString = "LAS";
669  break;
670  }
671  case ITK_COORDINATE_ORIENTATION_PRI:
672  {
673  returnString = "PRI";
674  break;
675  }
676  case ITK_COORDINATE_ORIENTATION_PLI:
677  {
678  returnString = "PLI";
679  break;
680  }
681  case ITK_COORDINATE_ORIENTATION_ARI:
682  {
683  returnString = "ARI";
684  break;
685  }
686  case ITK_COORDINATE_ORIENTATION_ALI:
687  {
688  returnString = "ALI";
689  break;
690  }
691  case ITK_COORDINATE_ORIENTATION_PRS:
692  {
693  returnString = "PRS";
694  break;
695  }
696  case ITK_COORDINATE_ORIENTATION_PLS:
697  {
698  returnString = "PLS";
699  break;
700  }
701  case ITK_COORDINATE_ORIENTATION_ARS:
702  {
703  returnString = "ARS";
704  break;
705  }
706  case ITK_COORDINATE_ORIENTATION_ALS:
707  {
708  returnString = "ALS";
709  break;
710  }
711  case ITK_COORDINATE_ORIENTATION_IPR:
712  {
713  returnString = "IPR";
714  break;
715  }
716  case ITK_COORDINATE_ORIENTATION_SPR:
717  {
718  returnString = "SPR";
719  break;
720  }
721  case ITK_COORDINATE_ORIENTATION_IAR:
722  {
723  returnString = "IAR";
724  break;
725  }
726  case ITK_COORDINATE_ORIENTATION_SAR:
727  {
728  returnString = "SAR";
729  break;
730  }
731  case ITK_COORDINATE_ORIENTATION_IPL:
732  {
733  returnString = "IPL";
734  break;
735  }
736  case ITK_COORDINATE_ORIENTATION_SPL:
737  {
738  returnString = "SPL";
739  break;
740  }
741  case ITK_COORDINATE_ORIENTATION_IAL:
742  {
743  returnString = "IAL";
744  break;
745  }
746  case ITK_COORDINATE_ORIENTATION_SAL:
747  {
748  returnString = "SAL";
749  break;
750  }
751  case ITK_COORDINATE_ORIENTATION_PIR:
752  {
753  returnString = "PIR";
754  break;
755  }
756  case ITK_COORDINATE_ORIENTATION_PSR:
757  {
758  returnString = "PSR";
759  break;
760  }
761  case ITK_COORDINATE_ORIENTATION_AIR:
762  {
763  returnString = "AIR";
764  break;
765  }
766  case ITK_COORDINATE_ORIENTATION_ASR:
767  {
768  returnString = "ASR";
769  break;
770  }
771  case ITK_COORDINATE_ORIENTATION_PIL:
772  {
773  returnString = "PIL";
774  break;
775  }
776  case ITK_COORDINATE_ORIENTATION_PSL:
777  {
778  returnString = "PSL";
779  break;
780  }
781  case ITK_COORDINATE_ORIENTATION_AIL:
782  {
783  returnString = "AIL";
784  break;
785  }
786  case ITK_COORDINATE_ORIENTATION_ASL:
787  {
788  returnString = "ASL";
789  break;
790  }
791  default:
792  {
793  returnString = "UNKNOWN";
794  break;
795  }
796  }
797 
798  return std::make_pair(returnString, orientFilter->GetOutput());
799  }
800 
801  /**
802  \brief Get skull stripped image
803 
804  Templated over InputImageType, AtlasImageType and AtlasLabelType
805 
806  \param inputImage The input image on which to run the skull stripping
807  \param atlasImage The atlas image
808  \param atlasLabelImage The atlas label
809  */
810  template< class TImageType = ImageTypeFloat3D, class TAtlasImageType = TImageType, class TAtlasLabelType = TImageType >
811  typename TImageType::Pointer GetSkullStrippedImage(const typename TImageType::Pointer inputImage,
812  const typename TAtlasImageType::Pointer atlasImage, const typename TAtlasLabelType::Pointer atlasLabelImage)
813  {
814  // skull stripping initialization
815  auto skullStripper = itk::StripTsImageFilter< TImageType, TAtlasImageType, TAtlasLabelType>::New();
816  skullStripper->SetInput(inputImage);
817  skullStripper->SetAtlasImage(atlasImage);
818  skullStripper->SetAtlasBrainMask(atlasLabelImage);
819 
820  // actually do the skull stripping
821  try
822  {
823  skullStripper->Update();
824  }
825  catch (itk::ExceptionObject &exception)
826  {
827  std::cerr << "Exception caught: " << exception << "\n";
828  return inputImage;
829  }
830 
831  // apply the generated mask
832  auto masker = itk::MaskImageFilter< TImageType, TAtlasLabelType, TImageType >::New();
833  masker->SetInput(inputImage);
834  masker->SetMaskImage(skullStripper->GetOutput());
835 
836  try
837  {
838  masker->Update();
839  }
840  catch (itk::ExceptionObject &exception)
841  {
842  std::cerr << "Exception caught: " << exception << "\n";
843  return inputImage;
844  }
845 
846  return masker->GetOutput();
847  }
848 
849  /**
850  \brief Get the distance between 2 indeces of an itk::Image
851  */
852  template< class TImageType = ImageTypeFloat3D >
853  float GetDistanceBetweenIndeces(const typename TImageType::IndexType point1, const typename TImageType::IndexType point2)
854  {
855  float currentDist = 0.0;
856  for (size_t i = 0; i < TImageType::ImageDimension; i++)
857  {
858  currentDist += powf(point1[i] - point2[i], 2);
859  }
860  currentDist = sqrtf(currentDist);
861 
862  return currentDist;
863  }
864 
865  /**
866  \brief Get the distance between 2 itk::P of an itk::Image
867  */
868  inline float GetDistanceBetweenIndeces(const float* point1, const float* point2)
869  {
870  float currentDist = 0.0;
871  for (size_t i = 0; i < 3; i++)
872  {
873  currentDist += powf(point1[i] - point2[i], 2);
874  }
875  currentDist = sqrtf(currentDist);
876 
877  return currentDist;
878  }
879 
880  /**
881  \brief Get the maximum distance and corresponding coordinate from a seed point in a label map
882 
883  \param inputLabelMap The label map on which to do the calculation
884  \param indexForComputation The index of the seed point from where to do the distance measurements
885  \param realCoordinatesPassed Bool which denotes if indexForComputation is real (e.g. the tumorPoints used by GLISTR) or an image index
886 
887  \return The maximum distance and the corrensponding index
888  */
889  template< class TImageType = ImageTypeFloat3D >
890  std::pair< float, typename TImageType::IndexType > GetMaxDistanceInLabelMap(const typename TImageType::Pointer inputLabelMap,
891  const typename TImageType::IndexType indexForComputation,
892  bool realCoordinateInput = false, bool realCoordinateOutput = false)
893  {
894  auto indexToUse = indexForComputation;
895  if (realCoordinateInput)
896  {
897  for (size_t i = 0; i < TImageType::ImageDimension; i++)
898  {
899  // gets the index of the point in question
900  indexToUse[i] = std::abs((indexToUse[i] * inputLabelMap->GetSpacing()[i]) + inputLabelMap->GetOrigin()[i]);
901  }
902  }
903  // setup the connected component segmentation
904  auto connectedComponentFilter = itk::ConnectedThresholdImageFilter< TImageType, TImageType >::New();
905  connectedComponentFilter->SetInput(inputLabelMap);
906  connectedComponentFilter->SetSeed(indexToUse);
907  connectedComponentFilter->SetReplaceValue(1);
908  // we only want the selected voxel value to be segmented and nothing else
909  auto currentPixelVal = inputLabelMap->GetPixel(indexToUse);
910  connectedComponentFilter->SetLower(currentPixelVal);
911  connectedComponentFilter->SetUpper(currentPixelVal);
912  connectedComponentFilter->Update();
913 
914  itk::ImageRegionConstIterator <TImageType> iterator(connectedComponentFilter->GetOutput(), connectedComponentFilter->GetOutput()->GetLargestPossibleRegion());
915 
916  float maxDist = 0;
917  typename TImageType::IndexType index_maxDist;
918 
919  // iterate through the whole image and find maximum distance
920  for (iterator.GoToBegin(); !iterator.IsAtEnd(); ++iterator)
921  {
922  if (iterator.Get() > 0)
923  {
924  auto currentIndex = iterator.GetIndex();
925  float currentDist = 0.0;// TBD gcc is unable to deduce sutable type. Please fix this -> GetDistanceBetweenIndeces(currentIndex, indexToUse);
926  currentDist = GetDistanceBetweenIndeces<TImageType>(currentIndex, indexToUse);
927 
928  if (currentDist > maxDist)
929  {
930  maxDist = currentDist;
931  index_maxDist = currentIndex;
932  }
933  }
934  }
935 
936  if (realCoordinateOutput)
937  {
938  for (size_t i = 0; i < TImageType::ImageDimension; i++)
939  {
940  // gets the index of the point in question
941  index_maxDist[i] = (index_maxDist[i] * inputLabelMap->GetSpacing()[i]) + inputLabelMap->GetOrigin()[i];
942  }
943  }
944 
945  return std::make_pair(maxDist, index_maxDist);
946  }
947 
948  /**
949  \brief Create an empty (optionally pass a value) ITK image based on an input image with same properties
950 
951  \param inputImage The image to base the output on
952  \param value The value to populate the new image with; defaults to '0'
953  */
954  template< class TImageType = ImageTypeFloat3D >
955  typename TImageType::Pointer CreateImage(const typename TImageType::Pointer inputImage, const typename TImageType::PixelType value = 0)
956  {
957  typename TImageType::Pointer new_image = TImageType::New();
958  new_image->SetLargestPossibleRegion(inputImage->GetLargestPossibleRegion());
959  new_image->SetRequestedRegion(inputImage->GetRequestedRegion());
960  new_image->SetBufferedRegion(inputImage->GetBufferedRegion());
961  new_image->SetDirection(inputImage->GetDirection());
962  new_image->SetOrigin(inputImage->GetOrigin());
963  new_image->SetSpacing(inputImage->GetSpacing());
964  new_image->Allocate();
965  new_image->FillBuffer(value);
966  return new_image;
967  }
968 
969  /**
970  \brief Create an empty (optionally pass a value) ITK image based on an input image with same properties
971 
972  \param inputImage The image to base the output on
973  \param oldValues Values separated by 'x'
974  \param newValues Values separated by 'x'
975  */
976  template< class TImageType = ImageTypeFloat3D >
977  typename TImageType::Pointer ChangeImageValues(const typename TImageType::Pointer inputImage, const std::string &oldValues, const std::string &newValues)
978  {
979  auto oldValues_split = cbica::stringSplit(oldValues, "x");
980  auto newValues_split = cbica::stringSplit(newValues, "x");
981  if (oldValues_split.size() != newValues_split.size())
982  {
983  std::cerr << "Change values needs the old and new values to be of same size, for example '-cv 1x2,2x3.\n";
984  return nullptr;
985  }
986 
987  itk::ImageRegionConstIterator< TImageType > iterator(inputImage, inputImage->GetBufferedRegion());
988  auto outputImage = inputImage;
989  outputImage->DisconnectPipeline();
990  itk::ImageRegionIterator< TImageType > outputIterator(outputImage, outputImage->GetBufferedRegion());
991  outputIterator.GoToBegin();
992  for (iterator.GoToBegin(); !iterator.IsAtEnd(); ++iterator, ++outputIterator)
993  {
994  for (size_t i = 0; i < oldValues_split.size(); i++)
995  {
996  if (iterator.Get() == std::atof(oldValues_split[i].c_str()))
997  {
998  outputIterator.Set(std::atof(newValues_split[i].c_str()));
999  }
1000  }
1001  }
1002 
1003  return outputImage;
1004  }
1005 
1006  /**
1007  \brief Get distances in world coordinates across axes for an image
1008 
1009  \param inputImage
1010  */
1011  template< typename TImageType = ImageTypeFloat3D >
1012  itk::Vector< float, TImageType::ImageDimension > GetDistances(const typename TImageType::Pointer inputImage)
1013  {
1014  itk::Vector< float, TImageType::ImageDimension > distances;
1015  itk::Point< float, TImageType::ImageDimension > start_worldCoordinates, end_worldCoordinates;
1016 
1017  typename TImageType::IndexType start_image, end_image;
1018 
1019  auto size = inputImage->GetBufferedRegion().GetSize();
1020 
1021  for (size_t i = 0; i < TImageType::ImageDimension; i++)
1022  {
1023  start_image[i] = 0;
1024  end_image[i] = size[i] - 1;
1025  }
1026 
1027  inputImage->TransformIndexToPhysicalPoint(start_image, start_worldCoordinates);
1028  inputImage->TransformIndexToPhysicalPoint(end_image, end_worldCoordinates);
1029 
1030  for (size_t i = 0; i < TImageType::ImageDimension; i++)
1031  {
1032  distances[i] = std::abs(end_worldCoordinates[i] - start_worldCoordinates[i]); // real world image span along each axis
1033  }
1034 
1035  return distances;
1036  }
1037 
1038  /**
1039  \brief Resample an image to an isotropic resolution using the specified output spacing vector
1040 
1041  This filter uses the example https://itk.org/Wiki/ITK/Examples/ImageProcessing/ResampleImageFilter as a base while processing time-stamped images as well
1042  \param inputImage The input image to process
1043  \param outputSpacing The output spacing, always isotropic
1044  \param interpolator The type of interpolator to use; can be Linear, BSpline or NearestNeighbor
1045  \return The resized image
1046  */
1047  template< class TImageType = ImageTypeFloat3D >
1048  typename TImageType::Pointer ResampleImage(const typename TImageType::Pointer inputImage, const itk::Vector< double, TImageType::ImageDimension > &outputSpacing, const std::string interpolator = "Linear")
1049  {
1050  auto outputSize = inputImage->GetLargestPossibleRegion().GetSize();
1051  auto outputSpacingVector = outputSpacing;
1052  auto inputSpacing = inputImage->GetSpacing();
1053  if (TImageType::ImageDimension != 4)
1054  {
1055  for (size_t i = 0; i < TImageType::ImageDimension; i++)
1056  {
1057  outputSize[i] = std::round(outputSize[i] * inputSpacing[i] / outputSpacing[i]);
1058  }
1059  }
1060  else // preserve all time points of a time series image
1061  {
1062  for (size_t i = 0; i < 3; i++)
1063  {
1064  outputSize[i] = std::round(outputSize[i] * inputSpacing[i] / outputSpacing[i]);
1065  }
1066  }
1067 
1068  return ResampleImage< TImageType >(inputImage, outputSpacingVector, outputSize, interpolator);
1069 
1070  }
1071 
1072  /**
1073  \brief Resample an image to an isotropic resolution using the specified output spacing vector
1074 
1075  This filter uses the example https://itk.org/Wiki/ITK/Examples/ImageProcessing/ResampleImageFilter as a base while processing time-stamped images as well
1076  \param inputImage The input image to process
1077  \param outputSpacing The output spacing, always isotropic
1078  \param interpolator The type of interpolator to use; can be Linear, BSpline or NearestNeighbor
1079  \return The resized image
1080  */
1081  template< class TImageType = ImageTypeFloat3D >
1082  typename TImageType::Pointer ResampleImage(const typename TImageType::Pointer inputImage, const typename TImageType::SpacingType outputSpacing,
1083  typename TImageType::SizeType outputSize, const std::string interpolator = "Linear")
1084  {
1085  std::string interpolator_wrap = interpolator;
1086  std::transform(interpolator_wrap.begin(), interpolator_wrap.end(), interpolator_wrap.begin(), ::tolower);
1087 
1088  auto resampler = itk::ResampleImageFilter< TImageType, TImageType >::New();
1089  resampler->SetInput(inputImage);
1090  resampler->SetSize(outputSize);
1091  resampler->SetOutputSpacing(outputSpacing);
1092  resampler->SetOutputOrigin(inputImage->GetOrigin());
1093  resampler->SetOutputDirection(inputImage->GetDirection());
1094  resampler->SetOutputStartIndex(inputImage->GetLargestPossibleRegion().GetIndex());
1095  resampler->SetTransform(itk::IdentityTransform< double, TImageType::ImageDimension >::New());
1096  if (interpolator_wrap == "bspline")
1097  {
1098  auto interpolatorFunc = itk::BSplineInterpolateImageFunction< TImageType, double >::New();
1099  resampler->SetInterpolator(interpolatorFunc);
1100  }
1101  else if (interpolator_wrap.find("bicubic") != std::string::npos)
1102  {
1103  auto interpolatorFunc = itk::BSplineInterpolateImageFunction< TImageType >::New();
1104  interpolatorFunc->SetSplineOrder(3);
1105  resampler->SetInterpolator(interpolatorFunc);
1106  }
1107  else if (interpolator_wrap.find("nearest") != std::string::npos)
1108  {
1109  auto interpolatorFunc = itk::NearestNeighborInterpolateImageFunction< TImageType, double >::New();
1110  resampler->SetInterpolator(interpolatorFunc);
1111  }
1112  //else if (interpolator_wrap.find("window") != std::string::npos)
1113  //{
1114  // constexpr unsigned int WindowRadius = 5; // pass as parameter
1115  // auto interpolatorFunc = itk::WindowedSincInterpolateImageFunction< TImageType,
1116  // WindowRadius, // pass as parameter
1117  // itk::Function::HammingWindowFunction< WindowRadius >, // pass as parameter
1118  // itk::ConstantBoundaryCondition< TImageType >, // pass as parameter
1119  // double >::New();
1120  // resampler->SetInterpolator(interpolatorFunc);
1121  //}
1122  else
1123  {
1124  auto interpolatorFunc = itk::LinearInterpolateImageFunction< TImageType, double >::New();
1125  resampler->SetInterpolator(interpolatorFunc);
1126  }
1127  resampler->UpdateLargestPossibleRegion();
1128 
1129  return resampler->GetOutput();
1130  }
1131 
1132  /**
1133  \brief Resample an image to an isotropic resolution using the specified output spacing
1134 
1135  This filter uses the example https://itk.org/Wiki/ITK/Examples/ImageProcessing/ResampleImageFilter as a base while processing time-stamped images as well
1136  \param inputImage The input image to process
1137  \param outputSpacing The output spacing, always isotropic
1138  \param interpolator The type of interpolator to use; can be Linear, BSpline or NearestNeighbor
1139  \return The resized image
1140  */
1141  template< class TImageType = ImageTypeFloat3D >
1142  typename TImageType::Pointer ResampleImage(const typename TImageType::Pointer inputImage, const float outputSpacing = 1.0, const std::string interpolator = "Linear")
1143  {
1144  auto outputSize = inputImage->GetLargestPossibleRegion().GetSize();
1145  auto inputSpacing = inputImage->GetSpacing();
1146  auto outputSpacingVector = inputSpacing;
1147  if (TImageType::ImageDimension != 4)
1148  {
1149  outputSpacingVector.Fill(outputSpacing);
1150  for (size_t i = 0; i < TImageType::ImageDimension; i++)
1151  {
1152  outputSize[i] = std::round(outputSize[i] * inputSpacing[i] / outputSpacing);
1153  }
1154  }
1155  else // preserve all time points of a time series image
1156  {
1157  for (size_t i = 0; i < 3; i++)
1158  {
1159  outputSpacingVector[i] = outputSpacing;
1160  outputSize[i] = std::round(outputSize[i] * inputSpacing[i] / outputSpacing);
1161  }
1162  outputSpacingVector[3] = inputSpacing[3];
1163  }
1164 
1165  return ResampleImage< TImageType >(inputImage, outputSpacingVector, outputSize, interpolator);
1166 
1167  }
1168 
1169  /**
1170  \brief Resize an input image by a factor (expressed as a percentage)
1171 
1172  This filter uses the example https://itk.org/Wiki/ITK/Examples/ImageProcessing/ResampleImageFilter as a base while processing time-stamped images as well
1173  \param inputImage The input image to process
1174  \param resizeFactor The resize factor; can be greater than 100 (which causes an expanded image to be written) but can never be less than zero
1175  \param interpolator The type of interpolator to use; can be Linear, BSpline, BiCubic or NearestNeighbor
1176  \return The resized image
1177  */
1178  template< class TImageType = ImageTypeFloat3D >
1179  typename TImageType::Pointer ResizeImage(const typename TImageType::Pointer inputImage, const size_t resizeFactor, const std::string &interpolator = "Linear")
1180  {
1181  const float factor = static_cast<float>(resizeFactor) / 100;
1182  auto outputSize = inputImage->GetLargestPossibleRegion().GetSize();
1183  auto outputSpacing = inputImage->GetSpacing();
1184  if (TImageType::ImageDimension != 4)
1185  {
1186  for (size_t i = 0; i < TImageType::ImageDimension; i++)
1187  {
1188  outputSize[i] = outputSize[i] * factor;
1189  outputSpacing[i] = outputSpacing[i] / factor;
1190  }
1191  }
1192  else // preserve all time points of a time series image
1193  {
1194  for (size_t i = 0; i < 3; i++)
1195  {
1196  outputSize[i] = outputSize[i] * factor;
1197  outputSpacing[i] = outputSpacing[i] / factor;
1198  }
1199  }
1200 
1201  return ResampleImage < TImageType >(inputImage, outputSpacing, outputSize, interpolator);
1202 
1203  }
1204 
1205  /**
1206  \brief Get the unique values in an image
1207 
1208  \param inputImage The input image
1209  \param sortResult Whether the output should be sorted in ascending order or not, defaults to true
1210  */
1211  template< class TImageType = ImageTypeFloat3D >
1212  std::vector< typename TImageType::PixelType > GetUniqueValuesInImage(typename TImageType::Pointer inputImage, bool sortResult = true)
1213  {
1214  itk::ImageRegionConstIterator< TImageType > iterator(inputImage, inputImage->GetBufferedRegion());
1215 
1216  std::vector< typename TImageType::PixelType > uniqueValues;
1217 
1218  for (iterator.GoToBegin(); !iterator.IsAtEnd(); ++iterator)
1219  {
1220  auto currentValue = iterator.Get();
1221  if (std::find(uniqueValues.begin(), uniqueValues.end(), currentValue) == uniqueValues.end())
1222  {
1223  uniqueValues.push_back(currentValue);
1224  }
1225  }
1226 
1227  if (sortResult)
1228  {
1229  std::sort(uniqueValues.begin(), uniqueValues.end(), std::less< typename TImageType::PixelType >());
1230  }
1231 
1232  return uniqueValues;
1233  }
1234 
1235  /**
1236  \brief Get Non-zero indeces of image
1237  */
1238  template< class TImageType = ImageTypeFloat3D >
1239  std::vector< typename TImageType::IndexType > GetNonZeroIndeces(typename TImageType::Pointer inputImage)
1240  {
1241  std::vector< typename TImageType::IndexType > outputIndeces;
1242  itk::ImageRegionConstIterator< TImageType > iterator(inputImage, inputImage->GetBufferedRegion());
1243 
1244  for (iterator.GoToBegin(); !iterator.IsAtEnd(); ++iterator)
1245  {
1246  if (iterator.Get() != 0)
1247  {
1248  outputIndeces.push_back(iterator.GetIndex());
1249  }
1250  }
1251  return outputIndeces;
1252  }
1253 
1254 }
std::vector< typename TImageType::IndexType > GetNonZeroIndeces(typename TImageType::Pointer inputImage)
Get Non-zero indeces of image.
Definition: cbicaITKUtilities.h:1239
TImageType::Pointer CreateImage(const typename TImageType::Pointer inputImage, const typename TImageType::PixelType value=0)
Create an empty (optionally pass a value) ITK image based on an input image with same properties.
Definition: cbicaITKUtilities.h:955
std::vector< std::string > stringSplit(const std::string &str, const std::string &delim)
Splits the string.
std::vector< typename TImageType::PixelType > GetPixelValuesFromIndeces(const typename TImageType::Pointer inputImage, const std::vector< typename TImageType::IndexType > &indeces)
Get Pixel Values of specified indeces of input Image.
Definition: cbicaITKUtilities.h:154
std::vector< typename TImageType::PixelType > GetUniqueValuesInImage(typename TImageType::Pointer inputImage, bool sortResult=true)
Get the unique values in an image.
Definition: cbicaITKUtilities.h:1212
TImageType::Pointer ChangeImageValues(const typename TImageType::Pointer inputImage, const std::string &oldValues, const std::string &newValues)
Create an empty (optionally pass a value) ITK image based on an input image with same properties.
Definition: cbicaITKUtilities.h:977
Reads any image from file name and generates relevant data.
Definition: cbicaITKImageInfo.h:36
std::vector< typename TImageType::IndexType > GetIndexFromNonZeroPixels(const typename TImageType::Pointer inputImage, const std::string valuesToExclude="0")
Get MD5 sum of a supplied file.
Definition: cbicaITKUtilities.h:210
TImageType::Pointer ResampleImage(const typename TImageType::Pointer inputImage, const itk::Vector< double, TImageType::ImageDimension > &outputSpacing, const std::string interpolator="Linear")
Resample an image to an isotropic resolution using the specified output spacing vector.
Definition: cbicaITKUtilities.h:1048
TImageType::Pointer GetSkullStrippedImage(const typename TImageType::Pointer inputImage, const typename TAtlasImageType::Pointer atlasImage, const typename TAtlasLabelType::Pointer atlasLabelImage)
Get skull stripped image.
Definition: cbicaITKUtilities.h:811
bool ImageSanityCheck(const typename TImageType::Pointer image1, const typename TImageType::Pointer image2)
Check properties of 2 images to see if they are defined in the same space.
Definition: cbicaITKUtilities.h:324
TImageType::Pointer GetAdaptiveHistogramEqualizedImage(const typename TImageType::Pointer inputImage, const typename TImageType::Pointer referenceImage, const float alpha=0.3, const float beta=0.3, const float radius=1, const int numberOfHistogramLevels=100)
Get the indeces of the image which are not zero.
Definition: cbicaITKUtilities.h:262
TImageType::Pointer GetHistogramMatchedImage(const typename TImageType::Pointer inputImage, const typename TImageType::Pointer referenceImage, const int numberOfMatchPoints=40, const int numberOfHistogramLevels=100)
Get the indeces of the image which are not zero.
Definition: cbicaITKUtilities.h:235
std::pair< float, typename TImageType::IndexType > GetMaxDistanceInLabelMap(const typename TImageType::Pointer inputLabelMap, const typename TImageType::IndexType indexForComputation, bool realCoordinateInput=false, bool realCoordinateOutput=false)
Get the maximum distance and corresponding coordinate from a seed point in a label map.
Definition: cbicaITKUtilities.h:890
TImageType::Pointer ResizeImage(const typename TImageType::Pointer inputImage, const size_t resizeFactor, const std::string &interpolator="Linear")
Resize an input image by a factor (expressed as a percentage)
Definition: cbicaITKUtilities.h:1179
float GetDistanceBetweenIndeces(const typename TImageType::IndexType point1, const typename TImageType::IndexType point2)
Get the distance between 2 indeces of an itk::Image.
Definition: cbicaITKUtilities.h:853
bool GetResultOfImageComparasion(const typename TImageType::Pointer referenceImage, const typename TImageType::Pointer checkImage, const typename TImageType::PixelType differenceThreshold=0, const unsigned int toleranceRadius=0, const unsigned long long numberOfPixelsTolerance=10, const typename TImageType::PixelType averageIntensityDifference=0)
Get result of Image comparison between 2 images.
Definition: cbicaITKUtilities.h:289
Some basic utility functions.
std::vector< typename TImageType::PixelType > ExtractPixelValuesFromIndeces(const typename TImageType::Pointer inputImage, const std::vector< typename TImageType::IndexType > &indeces)
Wrap of GetPixelValues.
Definition: cbicaITKUtilities.h:179
Declaration of the ImageInfo class.
std::vector< std::vector< typename TImageType::IndexType > > CreateMaskIndeces(const std::vector< std::vector< typename TImageType::Pointer > > &inputModalitiesAndImages)
Calculate and preserve the mask indeces.
Definition: cbicaITKUtilities.h:88
std::pair< std::string, typename TImageType::Pointer > GetImageOrientation(const typename TImageType::Pointer inputImage)
Perform the deformable registration.
Definition: cbicaITKUtilities.h:544
itk::Vector< float, TImageType::ImageDimension > GetDistances(const typename TImageType::Pointer inputImage)
Get distances in world coordinates across axes for an image.
Definition: cbicaITKUtilities.h:1012