如何使用VTK或ITK库编写读取DICOM文件?

时间:2015-12-09 06:08:48

标签: image-processing processing vtk dicom itk

我使用vtkDICOMImageReader来读取DICOM文件。我使用vtkImageThreshold来阈值CT图像。现在我想在进一步处理之前将其写回我的硬盘。

我试过vtkImageWriter库把它写回来。但是当我尝试使用3D切片器打开文件时,它无法正常工作。如果有人能建议我编写Dicom文件的方法,我将不胜感激。

我在这里包含了我的代码,我正在尝试对dicom图像进行阈值处理并查看它。然后我想将阈值图像保存为dicom文件。但我无法成功地做到这一点。请帮我。

提前谢谢。

#include <itkImageToVTKImageFilter.h>
#include <vtkSmartPointer.h>
#include <vtkImageData.h>
#include <vtkImageThreshold.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleImage.h>
#include <vtkRenderer.h>
#include <vtkImageMapper3D.h>
#include <vtkImageActor.h>
#include <vtkImageCast.h>
#include <vtkNIFTIImageWriter.h>
#include <vtkImageMandelbrotSource.h>
#include <vtkImageViewer2.h>
#include <vtkDICOMImageReader.h>

int main(int argc, char* argv[])
{

std::string folder = argv[1];

vtkSmartPointer<vtkDICOMImageReader> reader =
      vtkSmartPointer<vtkDICOMImageReader>::New();
reader->SetFileName(folder.c_str());
reader->Update();

vtkSmartPointer<vtkImageViewer2> imageViewer =
  vtkSmartPointer<vtkImageViewer2>::New();
imageViewer->SetInputConnection(reader->GetOutputPort());

// threshold the images
vtkSmartPointer<vtkImageThreshold> imageThreshold = 
    vtkSmartPointer<vtkImageThreshold>::New();
imageThreshold->SetInputConnection(reader->GetOutputPort());
// unsigned char lower = 127;
unsigned char upper = 511;

imageThreshold->ThresholdByLower(upper);
imageThreshold->ReplaceInOn();
imageThreshold->SetInValue(0);
imageThreshold->ReplaceOutOn();
imageThreshold->SetOutValue(511);
imageThreshold->Update();

// Create actors
vtkSmartPointer<vtkImageActor> inputActor =
  vtkSmartPointer<vtkImageActor>::New();
inputActor->GetMapper()->SetInputConnection(
  reader->GetOutputPort());

vtkSmartPointer<vtkImageActor> thresholdedActor =
vtkSmartPointer<vtkImageActor>::New();
thresholdedActor->GetMapper()->SetInputConnection(
imageThreshold->GetOutputPort());

// There will be one render window
vtkSmartPointer<vtkRenderWindow> renderWindow =
  vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->SetSize(600, 300);

// And one interactor
vtkSmartPointer<vtkRenderWindowInteractor> interactor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
interactor->SetRenderWindow(renderWindow);

// Define viewport ranges
// (xmin, ymin, xmax, ymax)
double leftViewport[4] = {0.0, 0.0, 0.5, 1.0};
double rightViewport[4] = {0.5, 0.0, 1.0, 1.0};

// Setup both renderers
vtkSmartPointer<vtkRenderer> leftRenderer =
  vtkSmartPointer<vtkRenderer>::New();
renderWindow->AddRenderer(leftRenderer);
leftRenderer->SetViewport(leftViewport);
leftRenderer->SetBackground(.6, .5, .4);

vtkSmartPointer<vtkRenderer> rightRenderer =
  vtkSmartPointer<vtkRenderer>::New();
renderWindow->AddRenderer(rightRenderer);
rightRenderer->SetViewport(rightViewport);
rightRenderer->SetBackground(.4, .5, .6);

leftRenderer->AddActor(inputActor);
rightRenderer->AddActor(thresholdedActor);

leftRenderer->ResetCamera();
rightRenderer->ResetCamera();

renderWindow->Render();
interactor->Start();

vtkSmartPointer<vtkNIFTIImageWriter> writer =
  vtkSmartPointer<vtkNIFTIImageWriter>::New();
writer->SetInputConnection(reader->GetOutputPort());
writer->SetFileName("output");
writer->Write();

// writing the thresholded image to the hard drive.
//this is the part i am not able to code. Please can somebody help me     please? 

return EXIT_SUCCESS;

 }

2 个答案:

答案 0 :(得分:0)

首先,您想要保存阈值图像还是只读取图像?如果没有用imageThreshold替换阅读器

writer->SetInputConnection(reader->GetOutputPort())

通过查看NIFTI读者和作者的VTK测试,可能需要以下选项......

writer->SetNIFTIHeader(reader->GetNIFTIHeader())
writer->SetQFac(reader->GetQFac());
writer->SetTimeDimension(reader->GetTimeDimension());
writer->SetTimeSpacing(reader->GetTimeSpacing());
writer->SetRescaleSlope(reader->GetRescaleSlope());
writer->SetRescaleIntercept(reader->GetRescaleIntercept());
writer->SetQFormMatrix(reader->GetQFormMatrix()); 

我会测试添加这些选项,然后看看你得到了什么

答案 1 :(得分:0)

我认为VTK对处理图像有点困惑。我只用它来显示图像。我为你写了一段代码。读取,阈值和写入dicom图像的代码如下。它仅使用itk。我认为它填补了这个账单。

    #include "itkBinaryThresholdImageFilter.h"
    #include "itkImageFileReader.h"
    #include "itkGDCMImageIO.h"
    #include "itkImageFileWriter.h"
    #include "itkImage.h"

    int main () {
    typedef unsigned char InputPixelType ;  //Pixel Type of Input image
    typedef unsigned char OutputPixelType;  //Pixel Type of Output image
    const unsigned int InputDimension = 2;  //Dimension of image

    typedef itk::Image < InputPixelType, InputDimension > InputImageType; //Type definition of Input Image
    typedef itk::Image < InputPixelType, InputDimension > OutputImageType;//Type definition of Output Image
    typedef itk::ImageSeriesReader< InputImageType > ReaderType;//Type definition of Reader  
    typedef itk::BinaryThresholdImageFilter<InputImageType, OutputImageType > FilterType; // Type definition of Filter
    typedef itk::ImageFileWriter<OutputImageType> ImageWriterType; //Definition of Writer of Ouput image
    typedef itk::GDCMImageIO ImageIOType; //Type definition of Image IO for Dicom images

//Starts Reading Process
    ReaderType::Pointer reader = ReaderType::New(); //Creates reader
    ImageIOType::Pointer gdcmImageIO_input = ImageIOType::New(); //Creates ImageIO object for input image

    reader->SetImageIO( gdcmImageIO_input ); // Sets image IO of reader
    reader->SetFileNames( "example_image.dcm" ); // Sets filename to reader

//Exceptional handling
    try
    {
          reader->UpdateLargestPossibleRegion();
    }
    catch (itk::ExceptionObject & e)
    {
          std::cerr << "exception in file reader " << std::endl;
          std::cerr << e << std::endl;
          return EXIT_FAILURE;
    }
// Start filtering process
    FilterType::Pointer filter = FilterType::New(); //Creates filter
    filter->SetInput( reader->GetOutput() );
    filter->SetOutsideValue( 0);  // Set pixel value which are out of lower and upper threshold value
    filter->SetInsideValue( 255 );// Set pixel value which are within lower and upper threshold value
    filter->SetLowerThreshold( 25 ); // Lower threshold value 25
    filter->SetUpperThreshold( 150 );// Upper threshold value 150
    filter->Update();


//Starts Writing Process

    ImageWriterType::Pointer imageWriter = ImageWriterType::New(); // Creates writer
    ImageIOType::Pointer gdcmImageIO_output = ImageIOType::New(); // Creates Image IO object for output image

    imageWriter->SetImageIO( gdcmImageIO_output ); // Set image IO as dicom
    imageWriter->SetInput(filter->GetOutput() );  // Connects output of filter with to input of writer
    imageWriter->SetFileName(example_image_thresholded.dcm); // Sets output file name
//Exceptional handling
    try
      {
      imageWriter->Update();
      }
    catch ( itk::ExceptionObject &exception )
      {
      std::cerr << "Exception in file writer ! " << std::endl;
      std::cerr << exception << std::endl;

      return EXIT_FAILURE;
      }
    return EXIT_SUCCESS;
    }