VTK 三维重建 面绘制

来源:互联网 发布:人工智能服务机器人 编辑:程序博客网 时间:2024/05/16 14:09

#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkDICOMImageReader.h"
#include "vtkPolyDataMapper.h"
#include "vtkActor.h"
#include "vtkOutlineFilter.h"
#include "vtkCamera.h"
#include "vtkProperty.h"
#include "vtkPolyDataNormals.h"
#include "vtkContourFilter.h"
#include "vtkVolume16Reader.h"
#include "vtkImageCast.h"
#include "vtkImageReader.h"
#include "vtkBMPReader.h"

#include "vtkMarchingCubes.h"
#include "vtkStripper.h"

void main () //////////////////面绘////////////////
{

// Create the renderer, the render window, and the interactor. The renderer

   vtkRenderer *aRenderer = vtkRenderer::New();//建立绘制者
   vtkRenderWindow *renWin = vtkRenderWindow::New(); //建立绘制窗口
   renWin->AddRenderer(aRenderer); //将绘制者加入绘制窗口
   vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
   iren->SetRenderWindow(renWin);

 

//dicom格式图片
   vtkDICOMImageReader *v16 = vtkDICOMImageReader::New();
   v16->SetDataByteOrderToLittleEndian();
   v16->SetDirectoryName("d://ct//dcm");
   v16->SetDataSpacing (3.2, 3.2, 1.5);
   v16->Update();

 

  /*
      vtkVolume16Reader *v16=vtkVolume16Reader ::New();//创建一个新的读取实例
      v16->SetDataDimensions(64,64);////设置数据的像素
      v16->SetDataByteOrderToLittleEndian();//指明写入字节顺序
      v16->SetFilePrefix("C://filepath//headname");  //设置所读取切片数据文件的路径    (如:C://filepath//headname;filepath文件夹下的图片:headname .1.bmp, headname .2.bmp, headname .3.bmp ……headname .n.bmp)
      v16->SetImageRange(1,93);//设置读取切片的起始段(多少张)
      v16->SetDataSpacing(3.2,3.2,1.5);//设置切片之间的间距和像素之间的间距
*/

 


/*
  vtkBMPReader *v16 = vtkBMPReader::New(); 
  v16->SetDataExtent(0,175,0,135,1,3);//其中最后一个参数20 就表示我的图像序列有20张图像
  v16->SetFilePrefix("C://filepath//headname");  //设置所读取切片数据文件的路径 

   (如:C://filepath//headname;filepath   文件夹下的图片:headname .1.bmp, headname .2.bmp,  ……headname .n.bmp)
  v16->SetDataSpacing (1, 1, 2);//像素间的间隔
  v16->SetAllow8BitBMP (16) ;//很重要 
   //reader->Allow8BitBMPOff();//标志
*/

 


  //对读取数据类型匹配
   vtkImageCast *readerImageCast = vtkImageCast::New();
    readerImageCast->SetInput((vtkDataObject *)v16->GetOutput());
   readerImageCast->SetOutputScalarTypeToUnsignedShort();

   vtkMarchingCubes *skinExtractor=vtkMarchingCubes::New();//建立一个Marching Cubes 算法的对象取出等值面的三角面片
   skinExtractor->SetInput((vtkDataObject *)readerImageCast->GetOutput());//获得所读取的CT 数据
   skinExtractor->SetValue(0,500);//提取出等值线值为500 的皮肤

   vtkStripper *skinNormals=vtkStripper::New();//建立三角带对象
   skinNormals->SetInput(skinExtractor->GetOutput());//将生成的三角片连接成三角带
 
   vtkPolyDataMapper *skinMapper=vtkPolyDataMapper::New();//建立一个数据映射对象
   skinMapper->SetInput(skinNormals->GetOutput());//将三角带映射为几何数据
/*

//vtkMarchingContourFilter
//SetValue和GenerateValues均为设置等值线值的函数首先调用GenerateValues(3, 100, 300)产生3条等值线,分别为100、200、300;然后调用SetValue(0, 125),则最终效果为共有3条等值线,分别为125、200、300;如果改为调用SetValue(3, 400),则最终效果为共有4条等值线,分别为100、200、300、400.SetValue一般用于覆盖某一条已经存在的等值线,或者增加一条等值线;   GenerateValues一般重新设置等值线的条数。
  vtkContourFilter *skinExtractor = vtkContourFilter::New(); //建立一个Contour Filter算法的对象提取多个等值面
  skinExtractor->SetInputConnection(readerImageCast->GetOutputPort()); //获得所读取的CT 数据
  skinExtractor->GenerateValues(3, 100, 300);//GenerateValues对应n条等值线的值
  skinExtractor->SetValue(3, 500); //SetValue设置一条等值线值
 

  vtkPolyDataNormals *skinNormals = vtkPolyDataNormals::New(); //曲面法向量
  skinNormals->SetInputConnection(skinExtractor->GetOutputPort());
  skinNormals->SetFeatureAngle(80.0); //);//设定一个阈值 确定的边缘

  vtkPolyDataMapper *skinMapper = vtkPolyDataMapper::New(); //建立一个数据映射对象
  skinMapper->SetInputConnection(skinNormals->GetOutputPort());
  skinMapper->ScalarVisibilityOff(); //断开标志(是否上色)
*/

  vtkActor *skin = vtkActor::New(); //建立一个代表皮肤的演员
  skin->SetMapper(skinMapper); //获得皮肤几何数据的属性
  skin->GetProperty()->SetDiffuseColor(1, .19, .15); //设置皮肤颜色的属性
  skin->GetProperty()->SetSpecular(.3); //设置反射率
  skin->GetProperty()->SetSpecularPower(20); //设置反射光强度


  // An outline provides context around the data.
 
  vtkOutlineFilter *outlineData = vtkOutlineFilter::New(); //轮廓线设置
  outlineData->SetInputConnection(v16->GetOutputPort());

  vtkPolyDataMapper *mapOutline = vtkPolyDataMapper::New();
  mapOutline->SetInputConnection(outlineData->GetOutputPort());

  vtkActor *outline = vtkActor::New();
  outline->SetMapper(mapOutline);
  outline->GetProperty()->SetColor(0,0,0);

 vtkCamera *aCamera = vtkCamera::New(); //定义摄像机
  aCamera->SetViewUp (0, 0, -1); //取得摄像机方向
  aCamera->SetPosition (0, 1, 0); //光源位置
  aCamera->SetFocalPoint (0, 0, 0); //取焦点坐标
  aCamera->ComputeViewPlaneNormal();
 
  aRenderer->AddActor(outline); //添加角色
  aRenderer->AddActor(skin);
  aRenderer->SetActiveCamera(aCamera);
  aRenderer->ResetCamera ();
  aCamera->Dolly(1.5); //大于1向摄像机焦点移动 小于1则向远离焦点的方向移动

 
aRenderer->SetBackground(1,1,1);
renWin->SetSize(640, 480);

// Note that when camera movement occurs (as it does in the Dolly()
// method), the clipping planes often need adjusting. Clipping planes
// consist of two planes: near and far along the view direction. The
// near plane clips out objects in front of the plane; the far plane
// clips out objects behind the plane. This way only what is drawn
// between the planes is actually rendered.
aRenderer->ResetCameraClippingRange (); //裁剪

// Initialize the event loop and then start it.
iren->Initialize();
iren->Start();

// It is important to delete all objects created previously to prevent

v16->Delete();
skinExtractor->Delete();
skinNormals->Delete();
skinMapper->Delete();
skin->Delete();
outlineData->Delete();
mapOutline->Delete();
outline->Delete();
aCamera->Delete();
iren->Delete();
renWin->Delete();
aRenderer->Delete();

}

//参考网易博客千纸鹤的内容