]> Creatis software - clitk.git/blobdiff - tools/clitkProfileImageGenericFilter.cxx
cosmetic for .ggo
[clitk.git] / tools / clitkProfileImageGenericFilter.cxx
index 82298151116fc67a2505603e01d5b4dedfd11829..6c81756fbcf7adf9a3f51bfa0ad7fd753a73431f 100644 (file)
 #include "clitkProfileImageGenericFilter.h"
 
 // itk include
-#include "itkBinaryThresholdImageFilter.h"
-#include "itkMaskImageFilter.h"
-#include "itkMaskNegatedImageFilter.h"
+#include <itkLineIterator.h>
+#include <itkPoint.h>
 
 #include <clitkCommon.h>
 
+
+
 namespace clitk
 {
 
@@ -59,6 +60,30 @@ void ProfileImageGenericFilter::InitializeImageType()
 //--------------------------------------------------------------------
 
 
+//--------------------------------------------------------------------
+vtkFloatArray* ProfileImageGenericFilter::GetArrayX()
+{
+  return(mArrayX);
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+vtkFloatArray* ProfileImageGenericFilter::GetArrayY()
+{
+  return(mArrayY);
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+vtkFloatArray* ProfileImageGenericFilter::GetCoord()
+{
+  return(mCoord);
+}
+//--------------------------------------------------------------------
+
+
 //--------------------------------------------------------------------
 void ProfileImageGenericFilter::SetArgsInfo(const args_info_type & a)
 {
@@ -88,53 +113,137 @@ ProfileImageGenericFilter::UpdateWithInputImageType()
 
   // Reading input
   typename InputImageType::Pointer input = this->template GetInput<InputImageType>(0);
-
-  // Main filter
   typedef typename InputImageType::PixelType PixelType;
-  typedef itk::Image<uchar, InputImageType::ImageDimension> OutputImageType;
-
-  // Filter
-  typedef itk::BinaryThresholdImageFilter<InputImageType, OutputImageType> BinaryThresholdImageFilterType;
-  typename BinaryThresholdImageFilterType::Pointer thresholdFilter=BinaryThresholdImageFilterType::New();
-  thresholdFilter->SetInput(input);
-  thresholdFilter->SetInsideValue(mArgsInfo.fg_arg);
-
-  if (mArgsInfo.lower_given) thresholdFilter->SetLowerThreshold(static_cast<PixelType>(mArgsInfo.lower_arg));
-  if (mArgsInfo.upper_given) thresholdFilter->SetUpperThreshold(static_cast<PixelType>(mArgsInfo.upper_arg));
-
-  /* Three modes :
-     - FG -> only use FG value for pixel in the Foreground (or Inside), keep input values for outside
-     - BG -> only use BG value for pixel in the Background (or Outside), keep input values for inside
-     - both -> use FG and BG (real binary image)
-  */
-  if (mArgsInfo.mode_arg == std::string("both")) {
-    thresholdFilter->SetOutsideValue(mArgsInfo.bg_arg);
-    thresholdFilter->Update();
-    typename OutputImageType::Pointer outputImage = thresholdFilter->GetOutput();
-    this->template SetNextOutput<OutputImageType>(outputImage);
-  } else {
-    typename InputImageType::Pointer outputImage;
-    thresholdFilter->SetOutsideValue(0);
-    if (mArgsInfo.mode_arg == std::string("BG")) {
-      typedef itk::MaskImageFilter<InputImageType,OutputImageType> maskFilterType;
-      typename maskFilterType::Pointer maskFilter = maskFilterType::New();
-      maskFilter->SetInput1(input);
-      maskFilter->SetInput2(thresholdFilter->GetOutput());
-      maskFilter->SetOutsideValue(mArgsInfo.bg_arg);
-      maskFilter->Update();
-      outputImage = maskFilter->GetOutput();
-    } else {
-      typedef itk::MaskNegatedImageFilter<InputImageType,OutputImageType> maskFilterType;
-      typename maskFilterType::Pointer maskFilter = maskFilterType::New();
-      maskFilter->SetInput1(input);
-      maskFilter->SetInput2(thresholdFilter->GetOutput());
-      maskFilter->SetOutsideValue(mArgsInfo.fg_arg);
-      maskFilter->Update();
-      outputImage = maskFilter->GetOutput();
+  typedef typename InputImageType::IndexType IndexType;
+
+  mArrayX = vtkSmartPointer<vtkFloatArray>::New();
+  mArrayY = vtkSmartPointer<vtkFloatArray>::New();
+  mCoord = vtkSmartPointer<vtkFloatArray>::New();
+  mCoord->SetNumberOfComponents(InputImageType::ImageDimension);
+  mCoordmm = vtkSmartPointer<vtkFloatArray>::New();
+  mCoordmm->SetNumberOfComponents(InputImageType::ImageDimension);
+  mDimension = InputImageType::ImageDimension;
+  
+  /*typename InputImageType::Pointer outputImage;
+  outputImage = InputImageType::New();
+  outputImage->SetRegions(input->GetLargestPossibleRegion());
+  outputImage->Allocate();
+  outputImage->FillBuffer(0); */
+  
+  //Iterator
+  IndexType pointBegin, pointEnd;
+  
+  for (int i = 0; i < mArgsInfo.point1_given; ++i) {
+    pointBegin[i] = mArgsInfo.point1_arg[i];
+    pointEnd[i] = mArgsInfo.point2_arg[i];
+  }
+  
+  itk::LineConstIterator<InputImageType> itProfile(input, pointBegin, pointEnd);
+  itProfile.GoToBegin();
+  int lineNumber(1);
+  double *tuple;
+  double distance;
+  tuple = new double[InputImageType::ImageDimension];
+  itk::Point<double, InputImageType::ImageDimension> transformedFirstPoint;
+  itk::Point<double, InputImageType::ImageDimension> transformedCurrentPoint;
+  
+  input->TransformIndexToPhysicalPoint(itProfile.GetIndex(), transformedFirstPoint);
+  
+  while (!itProfile.IsAtEnd())
+  {    
+    // Fill in the table the intensity value
+    mArrayY->InsertNextTuple1(itProfile.Get());
+        
+    for (int i=0; i<InputImageType::ImageDimension; ++i) {
+        tuple[i] = itProfile.GetIndex()[i];
     }
-    // Write/Save results
-    this->template SetNextOutput<InputImageType>(outputImage);
+
+    input->TransformIndexToPhysicalPoint(itProfile.GetIndex(), transformedCurrentPoint);
+    distance = transformedFirstPoint.EuclideanDistanceTo(transformedCurrentPoint);
+
+    // Fill in the table the distance value
+    mArrayX->InsertNextTuple1(distance);
+    
+    // Fill in the table the voxel coordinate value
+    mCoord->InsertNextTuple(tuple); //index
+    for (int i=0; i<InputImageType::ImageDimension; ++i) {
+        tuple[i] = transformedCurrentPoint[i];
+    }
+    mCoordmm->InsertNextTuple(tuple); //mm
+    ++lineNumber;
+    ++itProfile;
+  }
+
+  if (mArgsInfo.output_given) {
+    std::string str(mArgsInfo.output_arg);
+    this->WriteOutput(str);
+  }
+  
+  /*
+  itk::LineIterator<InputImageType> otProfile(outputImage, pointBegin, pointEnd);
+  otProfile.GoToBegin();  
+  while (!otProfile.IsAtEnd())
+  {    
+    otProfile.Set(1.0);
+    ++otProfile;
+  }
+  
+  this->template SetNextOutput<InputImageType>(outputImage): */
+  
+  delete [] tuple;
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+void ProfileImageGenericFilter::WriteOutput(std::string outputFilename)
+{
+  ofstream fileOpen(outputFilename.c_str(), std::ofstream::trunc);
+
+  if(!fileOpen) {
+      cerr << "Error during saving" << endl;
+      return;
+  }
+
+  double *tuple;
+  tuple = new double[mDimension];
+  int i(0);
+  fileOpen << "The Bresenham algorithm is used to travel along the line. Values represent the center of each crossed voxel (in voxel and mm)" << endl;
+  fileOpen << "Id" << "\t" << "Value" << "\t" ;
+  fileOpen << "x(vox)" << "\t" << "y(vox)" << "\t";
+  if (mDimension >=3)
+      fileOpen << "z(vox)" << "\t";
+  if (mDimension >=4)
+      fileOpen << "t" << "\t";
+  fileOpen << "x(mm)" << "\t" << "y(mm)" << "\t";
+  if (mDimension >=3)
+      fileOpen << "z(mm)" << "\t";
+  if (mDimension >=4)
+      fileOpen << "t" << "\t";
+  fileOpen << endl;
+
+  while (i<mArrayX->GetNumberOfTuples()) {
+      fileOpen << i << "\t" << mArrayY->GetTuple(i)[0] << "\t" ;
+
+      mCoord->GetTuple(i, tuple);
+      for (int j=0; j<mDimension ; ++j) {
+          fileOpen << tuple[j] << "\t" ;
+      }
+      mCoordmm->GetTuple(i, tuple);
+      for (int j=0; j<mDimension ; ++j) {
+          fileOpen << tuple[j] << "\t" ;
+      }
+      if (mDimension == 4) {
+          fileOpen << tuple[3] << "\t" ;
+      }
+      fileOpen << endl;
+      ++i;
   }
+
+  delete [] tuple;
+
+  fileOpen.close();
 }
 //--------------------------------------------------------------------