CPR曲面重建代码

废话不说,直接上代码:

#include "vtkAutoInit.h"
#include "vtkPolyData.h"
#include "vtkProbeFilter.h"
#include "vtkParametricFunctionSource.h"
#include "vtkParametricSpline.h"
#include "vtkDICOMImageReader.h"
#include "vtkPoints.h"
#include "vtkCellArray.h"
#include "vtkWindowLevelLookupTable.h"
#include "vtkActor.h"
#include "vtkCamera.h"
#include "vtkNamedColors.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkImageData.h"
#include "vtkDataSetMapper.h"

VTK_MODULE_INIT(vtkRenderingFreeType)
VTK_MODULE_INIT(vtkRenderingOpenGL2);
VTK_MODULE_INIT(vtkInteractionStyle);
VTK_MODULE_INIT(vtkRenderingVolumeOpenGL2);

// 由曲线生成曲面

vtkPolyData* SweepLine(vtkParametricFunctionSource* line, double direction[3], double distance, int cols)
{
    int rows = line->GetOutput()->GetNumberOfPoints(); //待生成的surface的行数为曲线上点的个数
    double spacing = distance / rows;           //列方向上的spacing
    vtkPolyData* surface = vtkPolyData::New();

    //生成点
    cols += 1;
    int numberOfPoints = rows * cols;       //surface内点的个数
    int numberOfPolys = (rows - 1) * (cols - 1);

    vtkPoints* points = vtkPoints::New();
    points->Allocate(numberOfPoints);
    vtkCellArray* polys = vtkCellArray::New();
    polys->Allocate(numberOfPolys);

    //生成每行每列的点坐标,
    double x[] = { 0.0, 0.0, 0.0 };
    int cnt = 0;

    for (int row = 0; row < rows; row++)
    {
        for (int col = 0; col < cols; col++) 
        {
            double p[3] = { 0.0,0.0,0.0 };
            line->GetOutput()->GetPoint(row, p);
            x[0] = p[0] + direction[0] * col * spacing;
            x[1] = p[1] + direction[1] * col * spacing;
            x[2] = p[2] + direction[2] * col * spacing;
            points->InsertPoint(cnt, x);
            cnt++;
        }
    }


    //生成四边形
    vtkIdType pts[4] = { 0,0,0,0 };
    for (int row = 0; row < rows - 1; row++)
    {
        for (int col = 0; col < cols - 1; col++)
        {
            pts[0] = col + row * cols;
            pts[1] = pts[0] + 1;
            pts[2] = pts[0] + cols + 1;
            pts[3] = pts[0] + cols;
         //   polys->InsertNextCell(4, pts);   //每临近的四个点构成一个单元
            polys->InsertNextCell(4, pts);
  
        }
    }

    surface->SetPoints(points);
    surface->SetPolys(polys);

    return surface;
}

int main(int argc, char* argv[])
{
    char szInputFile[] = { "D:/imgdata/2013-06-04_dcm" };
    
    vtkDICOMImageReader* reader = vtkDICOMImageReader::New();
    reader->SetDataByteOrderToLittleEndian();
    reader->SetDirectoryName(szInputFile);
    reader->Update();
    int resolution = 100;
    int extent[2] = { 255, 255 };
    double thickness = 1.0;
    double spacing[2] = { 1.0, 1.0 };

    //自定义折线顶点坐标
    vtkPoints* points = vtkPoints::New();
    //(a,b,c,d)其中a表示序号,(b,c,d)表示点的坐标
    points->InsertPoint(0, 1.0, 0.0, 0.0);
    points->InsertPoint(1, 200, 100, 0.0);
    points->InsertPoint(2, 100, 200, 0.0);
    points->InsertPoint(3, 200, 300, 0.0);

    //将点插值逆合成一条曲线
    vtkParametricSpline* spline = vtkParametricSpline::New();
    spline->SetPoints(points);
    vtkParametricFunctionSource* splineFilter = vtkParametricFunctionSource::New();
    splineFilter->SetParametricFunction(spline);
    splineFilter->Update();


    //有曲线生成曲面
    double direction[] = { 0.0, 0.0, 1.0 };
    int distance = 160;
    vtkPolyData* surface = SweepLine(splineFilter, direction, distance, resolution);
    vtkProbeFilter* sampleVolume = vtkProbeFilter::New();
    //这里只能填1,和0,否则曲面要么是一块,要么什么也没有;
    sampleVolume->SetInputConnection(1, reader->GetOutputPort());
    sampleVolume->SetInputData(0, surface);

    //根据数据源的数据范围设置映射表的窗宽窗位
    vtkWindowLevelLookupTable* wlLut = vtkWindowLevelLookupTable::New();
    double range = reader->GetOutput()->GetScalarRange()[1] - reader->GetOutput()->GetScalarRange()[0];
    double level = (reader->GetOutput()->GetScalarRange()[1] - reader->GetOutput()->GetScalarRange()[0]) / 2;
    wlLut->SetWindow(range);
    wlLut->SetLevel(level);

    //创建映射器和角色
    vtkDataSetMapper* mapper = vtkDataSetMapper::New();
    mapper->SetInputConnection(sampleVolume->GetOutputPort());
    mapper->SetLookupTable(wlLut);
    mapper->SetScalarRange(0, 255);

    vtkActor* actor = vtkActor::New();
    actor->SetMapper(mapper);

    //创建渲染器,渲染窗口和交互
    vtkRenderer* ren = vtkRenderer::New();
    vtkRenderWindow* renWin = vtkRenderWindow::New();
    renWin->AddRenderer(ren);
    renWin->SetWindowName("CurvedReformation");

    vtkRenderWindowInteractor* iren = vtkRenderWindowInteractor::New();
    iren->SetRenderWindow(renWin);

    //将角色添加到场景
    ren->AddActor(actor);
    vtkNamedColors* colors = vtkNamedColors::New();
   // ren->SetBackground(colors->GetColor3d("DarkSlateGray"));
    ren->SetBackground(0.4, 0.4, 0.4);

    //设置相机以查看图像
    ren->GetActiveCamera()->SetViewUp(0, 0, 1);
    ren->GetActiveCamera()->SetPosition(0, 0, 0);
    ren->GetActiveCamera()->SetFocalPoint(1, 0, 0);
    ren->ResetCamera();

    //渲染和交互
    renWin->Render();
    iren->Start();

    return 0;
}

效果:

CPR曲面重建代码_第1张图片

你可能感兴趣的:(算法)