VTK体绘制(volume rendering)或三维重建的demo(基于dicom序列图像) C++ code


最近一直有碰到关于三维重建的问题,发现volume rendering的方式不同,显示效果及实时性也不一样。用两种方式写了个demo,来记录一下。
    

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include
#include
#include
#include

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

    std::string folder = "F:/Projects/BoneVisualization/201_240";

    //read all the dicom files with the received path.
  vtkSmartPointer reader = vtkSmartPointer::New();
    reader->SetDirectoryName(folder.c_str());
    reader->Update();

    int imageDims[3];
    reader->GetOutput()->GetDimensions(imageDims); //need include 
    cout << "dimension[] :" << imageDims[0] << " " << imageDims[1] << " " << imageDims[2] << endl;

    vtkSmartPointer cast = vtkSmartPointer::New();
    cast->SetInputData((vtkDataObject*)reader->GetOutput());
    cast->SetOutputScalarTypeToFloat();
    cast->SetOutputScalarTypeToUnsignedChar();
    cast->Update();

    //**********************************************************************
    //method 1
    
    vtkSmartPointer rayCastFun = vtkSmartPointer::New();
    // 定义光线经过体数据后的颜色计算方式
    vtkSmartPointer volumeMapper = vtkSmartPointer::New();
    //光线投射法-最常用的体绘制方法
    volumeMapper->SetInputData(cast->GetOutput());
    volumeMapper->SetVolumeRayCastFunction(rayCastFun);

    method 2
    //vtkSmartPointer volumeMapperGpu = vtkSmartPointer::New();
    基于GPU加速的光线投射体绘制算法
    //volumeMapperGpu->SetInputData(cast->GetOutput());
    //volumeMapperGpu->SetImageSampleDistance(0.5);
    //volumeMapperGpu->SetSampleDistance(1.0);
    //volumeMapperGpu->SetAutoAdjustSampleDistances(1);

    //***********************************************************************
    vtkSmartPointer volumeProperty = vtkSmartPointer::New();//定义对象属性
    volumeProperty->SetInterpolationTypeToLinear();
    volumeProperty->ShadeOn();
    volumeProperty->SetAmbient(0.4);
    volumeProperty->SetDiffuse(0.6);
    volumeProperty->SetSpecular(0.2);

    vtkSmartPointer compositeOpacity = vtkSmartPointer::New();
    //Defines a piecewise function mapping.
    compositeOpacity->AddPoint(60, 0.00);
    compositeOpacity->AddPoint(140, 0.40);
    compositeOpacity->AddPoint(180, 0.90);

    volumeProperty->SetScalarOpacity(compositeOpacity);

    vtkSmartPointer color = vtkSmartPointer::New();
    color->AddRGBPoint(0, 0, 0, 0);
    color->AddRGBPoint(64, 1, 0.52, 0.30);
    color->AddRGBPoint(190.0, 1, 1, 1);
    color->AddRGBPoint(220, 0.2, 0.2, 0.2);

    volumeProperty->SetColor(color);

    vtkSmartPointer volume = vtkSmartPointer::New();
    //represents a volume(data & properties) in a rendered scene
    //volume->SetMapper(volumeMapperGpu);
    volume->SetMapper(volumeMapper);
    volume->SetProperty(volumeProperty);

    vtkSmartPointer rendererVolume = vtkSmartPointer::New();
    vtkSmartPointer renderWindow = vtkSmartPointer::New();
    vtkSmartPointer renderWindowInteractor =           vtkSmartPointer::New();

    rendererVolume->AddVolume(volume);
    renderWindow->AddRenderer(rendererVolume);
    renderWindowInteractor->SetRenderWindow(renderWindow);

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

    return 0;
}

做了些测试,同样参数下两种方式的显示效果

VTK体绘制(volume rendering)或三维重建的demo(基于dicom序列图像) C++ code_第1张图片

method1

VTK体绘制(volume rendering)或三维重建的demo(基于dicom序列图像) C++ code_第2张图片
method 2(与method 1同一参数)

VTK体绘制(volume rendering)或三维重建的demo(基于dicom序列图像) C++ code_第3张图片

method2 (更改参数后)

method2 经过GPU加速后,不管是显示效果还是实时性都有很大的提升。三幅图像都为同一病人的脊柱CT数据,下面两层为CT扫描上金属片。最后一幅图像,相比于前面两幅,一些模糊的部分为身体骨骼外的其他部分(软组织)。

光线投射法的优点是能够较精确的模拟原始体数据,但计算量比较大,实时性则对硬件需求较高。

你可能感兴趣的:(VTK,volume,rendering,dicom)