2017-10-21 3 views
0

VTKを使用してDICOM(ctスキャン)イメージをポイントクラウドに変換する方法はありますか?VTKのDICOMとポイントクラウド

VTKでは、DICOMとDICOMシリーズとボリュームレンダリングを読み取ることができますが、一連のDICOM画像からポイントクラウドを生成することは可能ですか?

VTKでは不可能な場合は、この目的のために使用できる他のライブラリがありますか?

答えて

-1

私は結局、方法を見つけたかもしれないと思います。まだ試していないが、理論的にはうまくいくはずだ。

最初に、DICOMイメージを.vtkに変換すると、VTKを使用して.vtk形式に変換する必要があります。その後、PCL(ポイントクラウドライブラリ)を使用して.pcd(ポイントクラウド形式)に変換できます。

0

ここに私が使っているソースがありますが、これは非常に単純なdicomディレクトリ構造でしか動作しません:(tbh私はVTKにもっと複雑なディレクトリを行う能力はないと思っています...)。しかし、それが役に立った場合:

pcl::PointCloud<pcl::PointXYZI>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZI>); 

//dicom read 
vtkFileOutputWindow *outwin = vtkFileOutputWindow::New(); 
outwin->SetFileName("vtklog.txt"); 
outwin->SetInstance(outwin); 

vtkSmartPointer<ErrorObserver> errorObserver = vtkSmartPointer<ErrorObserver>::New(); 
vtkSmartPointer<vtkDICOMImageReader> reader = vtkSmartPointer<vtkDICOMImageReader>::New(); 

reader->AddObserver(vtkCommand::ErrorEvent, errorObserver); 
reader->AddObserver(vtkCommand::WarningEvent, errorObserver); 

vtkSmartPointer<vtkImageData> sliceData = vtkSmartPointer<vtkImageData>::New(); 
reader->SetDirectoryName(dicomDirectory.c_str()); 
reader->Update(); 

if (errorObserver->GetError() || errorObserver->GetWarning()) 
{ 
    std::cout << "Failed DICOM file access" << std::endl; 
    return false; 
} 

sliceData = reader->GetOutput(); 
outwin->Delete(); 

//extracting pointcloud 
int numberOfDims = sliceData->GetDataDimension(); 

int * dims = sliceData->GetDimensions(); 
std::cout << "Cloud dimensions: "; 
int totalPoints = 1; 
for (int i = 0; i < numberOfDims; i++) 
{ 
    std::cout << dims[i] << " , "; 
    totalPoints = totalPoints * dims[i]; 
} 
std::cout << std::endl; 

std::cout << "Number of dicom points: " << totalPoints << std::endl; 
//generate pcl point cloud 
double* dataRange = sliceData->GetScalarRange(); 
double* spacingData = reader->GetDataSpacing(); 
std::cout << "Data intensity bounds... min: " << dataRange[0] << ", max: " << dataRange[1] << std::endl; 
if (numberOfDims != 3) 
{ 
    std::cout << "Incorrect number of dimensions in dicom file, generation failed..." << std::endl; 
    return false; 
} 
else 
{ 
    double xScale = spacingData[0]; 
    double yScale = spacingData[1]; 
    double zScale = spacingData[2]; 

    std::cout << "x spacing: " << xScale << std::endl; 
    std::cout << "y spacing: " << yScale << std::endl; 
    std::cout << "z spacing: " << zScale << std::endl; 

    for (int z = 0; z < dims[2]; z++) 
    { 
     if (z % 50 == 0) 
     { 
      double percentageComplete = (double)z/(double)dims[2]; 
      std::cout << "Dicom Read Progress: " << (int)(100.0 * percentageComplete) << "%" << std::endl; 
     } 
     for (int y = 0; y < dims[1]; y++) 
     { 
      for (int x = 0; x < dims[0]; x++) 
      { 
       pcl::PointXYZI tempPt = pcl::PointXYZI(); 
       tempPt.x = x * xScale; 
       tempPt.y = y * yScale; 
       tempPt.z = z * zScale; 
       double tempIntensity = sliceData->GetScalarComponentAsDouble(x, y, z, 0); 
       if (!isinf(tempIntensity)) 
       { 
        tempPt.intensity = tempIntensity; 
       } 
       else 
       { 
        tempPt.intensity = 0; 
       } 

       cloud->points.push_back(tempPt); 
      } 
     } 
     std::cout << reader->GetTransferSyntaxUID() << std::endl; 
     //std::cout << reader->get 
    } 
}