-1

I am trying to convert a DICOM file into PLY format using VTK to further convert it into .pcd (point cloud format). I have followed the example provided here.

However in the above example the code is supposed to change .vtu format into .ply format. I changed the code to convert the .dcm format into .ply format as shown below. The build succeeded and the exe file is working as well, however, it does not write the required output file. Can anyone please point out where did I go wrong??

#include <vtkSmartPointer.h>
#include <vtkPolyData.h>
#include <vtkDICOMImageReader.h>
#include <vtkXMLPolyDataReader.h>
#include <vtkPLYWriter.h>

int main(int argc, char *argv[])
{
  if(argc < 3)
  {
    std::cerr << "Required arguments: input.vtp output.ply" << std::endl;
    return EXIT_FAILURE;
  }

  std::string inputFileName = argv[1];
  std::string outputFileName = argv[2];

  // Read the DICOM file in the specified directory.
  vtkSmartPointer<vtkDICOMImageReader> reader = 
vtkSmartPointer<vtkDICOMImageReader>::New();
  reader->SetFileName(inputFilename.c_str());
  reader->Update();


  vtkSmartPointer<vtkPLYWriter> writer = vtkSmartPointer<vtkPLYWriter>::New();
  writer->SetFileName(outputFileName.c_str());
  writer->SetInputConnection(reader->GetOutputPort());
  writer->Update();

  return EXIT_SUCCESS;
}
  • Have you tried debugging it? What does the reader object look like after calling Update()? Does it look like the data has loaded correctly? – brad Oct 23 '17 at 21:43
  • you are loading in imagedata, a 3D regularised voxel grid and then trying to save it out using a PLY or polydata - this is for an unstructured set of points! You want all the voxels to become a set of points? Or a specific set based on the image intensity? I would add a marching cubes filter in to get a subset of the volume to convert to a point cloud. – g.stevo Oct 24 '17 at 02:19
  • @g.stevo Yes I want the voxels to become a specific set of points. Basically, I want to create a 3D Point Cloud model of Spinal CT Image for further processing. Can you point me to some useful resource which will help me understand how to convert DICOM to Point Cloud using marching cubes? – user2521733 Oct 24 '17 at 15:32

1 Answers1

0

Below is an example of a simple contouring of a DICOM file and extraction of the largest connected area of polydata from the Marching Cubes filter then saved as a PLY format file. This should answer your question.

`
#include <vtkSmartPointer.h>
#include <vtkPolyData.h>
#include <vtkDICOMImageReader.h>
#include "vtkMarchingCubes.h"
#include "vtkPolyDataConnectivityFilter.h"
#include <vtkPLYWriter.h>

int main(int argc, char *argv[])
{
  if(argc < 3)
  {
    std::cerr << "Required arguments: input.dcm output.ply" << std::endl;
    return EXIT_FAILURE;
  }

  std::string inputFileName = argv[1];
  std::string outputFileName = argv[2];

  // Read the DICOM file in the specified directory.
  vtkSmartPointer<vtkDICOMImageReader> reader = 
  vtkSmartPointer<vtkDICOMImageReader>::New();
  reader->SetFileName(inputFilename.c_str());
  reader->Update();

  //arb. threshold for bone based on CT Hounsfield Units
  float isoValue = 400.0

  vtkSmartPointer<vtkMarchingCubes> surface =  vtkSmartPointer<vtkMarchingCubes>::New(); 
  surface->SetInputConnection(reader->GetOutputPort());
  surface->ComputeNormalsOn();
  surface->SetValue(0, isoValue);
  surface->Update()

  // To remain largest region
  vtkSmartPointer<vtkPolyDataConnectivityFilter> confilter =
  vtkSmartPointer<vtkPolyDataConnectivityFilter>::New();
  confilter->SetInputConnection(surface->GetOutputPort());
  confilter->SetExtractionModeToLargestRegion();
  confilter->Update();

  vtkSmartPointer<vtkPLYWriter> writer = vtkSmartPointer<vtkPLYWriter>::New();
  writer->SetFileName(outputFileName.c_str());
  writer->SetInputConnection(confilter->GetOutputPort());
  writer->Update();

  return EXIT_SUCCESS;
}
g.stevo
  • 745
  • 3
  • 10