参考:
代码是在vtk560环境下写出来的。下面直接贴代码:
using vtk;
namespace dicomorientationtest
{
public partial class Form1 : Form
{
#region 私有成员
private vtk.vtkFormsWindowControl vtkFormsWindowControl1 = null;
private vtk.vtkDICOMImageReader _reader = null;
private vtk.vtkVolume _vtkVolume = null;
private vtk.vtkRenderer _render = null;
private vtk.vtkGenericRenderWindowInteractor _iren = new vtk.vtkGenericRenderWindowInteractor();
private vtk.vtkRenderWindow _renwin = null;
private vtk.vtkFollower textActor;
#endregion
#region 属性
public string FileDir
{
get;
set;
}
#endregion
public Form1()
{
InitializeComponent();
InitRenderWindow();
}
private void InitRenderWindow()
{
this.vtkFormsWindowControl1 = new vtkFormsWindowControl();
this.SuspendLayout();
this.vtkFormsWindowControl1.Name = "vtkFormsWindowControl1";
this.vtkFormsWindowControl1.Size = new System.Drawing.Size(800, 800);
this.vtkFormsWindowControl1.TabIndex = 0;
this.Location = new System.Drawing.Point(10, 10);
this.vtkFormsWindowControl1.Text = "vtkFormsWindowControl1";
this.Controls.Add(vtkFormsWindowControl1);
}
private void btn_Open_Click(object sender, EventArgs e)
{
FolderBrowserDialog dlg = new FolderBrowserDialog();
if (DialogResult.OK == dlg.ShowDialog())
{
FileDir = dlg.SelectedPath;
}
}
private void btn_render_Click(object sender, EventArgs e)
{
if (!String.IsNullOrEmpty(FileDir))
{
_render = new vtkRenderer();
#region dicom
_reader = new vtkDICOMImageReader();
_reader.SetDirectoryName(FileDir);
_reader.SetDataByteOrderToLittleEndian();
_reader.Update();
int[] dimensions = _reader.GetOutput().GetDimensions();
#region opacity transfer
vtkPiecewiseFunction compositeOpacity = new vtkPiecewiseFunction();
compositeOpacity.AddPoint(-2048, 0);
compositeOpacity.AddPoint(128.643, 0);
compositeOpacity.AddPoint(129.982, 0.0982143);
compositeOpacity.AddPoint(173.636, 0.1);
compositeOpacity.AddPoint(255.884, 0.1);
compositeOpacity.AddPoint(3661, 1);
//compositeOpacity.AddPoint(173.636, 0);
//compositeOpacity.AddPoint(255.884, 0);
//compositeOpacity.AddPoint(3661, 0);
#endregion
#region colortransfer
vtkColorTransferFunction colorFun = new vtkColorTransferFunction();
colorFun.AddRGBPoint(-2048, 0, 0, 0);
colorFun.AddRGBPoint(128.643, 0, 0, 0);
colorFun.AddRGBPoint(129.982, 0.615686, 0, 0.0156863);
colorFun.AddRGBPoint(173.636, 0.909804, 0.454902, 0);
colorFun.AddRGBPoint(255.884, 0.886275, 0.886275, 0.886275);
colorFun.AddRGBPoint(584.878, 0.968627, 0.968627, 0.968627);
colorFun.AddRGBPoint(3661, 1, 1, 1);
#endregion
vtkVolumeProperty property = new vtkVolumeProperty();
property.ShadeOff();
property.SetInterpolationTypeToLinear();
property.SetColor(colorFun);
property.SetScalarOpacity(compositeOpacity);
property.SetDiffuse(0.9);
property.SetAmbient(0.1);
property.SetSpecular(0.2);
property.SetSpecularPower(10.0);
double[] range = _reader.GetOutput().GetScalarRange();
double min = range[0];
double max = range[1];
double diff = max - min;
double slope = 4095.0 / diff;//斜率
double inter = -slope * min;//截距
double shift = inter / slope;
vtkImageShiftScale vtkImageCast = new vtkImageShiftScale();
vtkImageCast.SetInput(_reader.GetOutput());
vtkImageCast.SetScale(slope);
vtkImageCast.SetShift(shift);
vtkImageCast.SetOutputScalarTypeToUnsignedShort();
vtkImageCast.Update();
vtkVolumeRayCastCompositeFunction compositefunction = new vtkVolumeRayCastCompositeFunction();
compositefunction.SetCompositeMethodToInterpolateFirst();
vtkVolumeRayCastMapper mapper = new vtkVolumeRayCastMapper();
mapper.SetVolumeRayCastFunction(compositefunction);
mapper.SetInput(vtkImageCast.GetOutput());
mapper.SetSampleDistance(0.1);
vtkVolume volume = new vtkVolume();
volume.SetMapper(mapper);
volume.SetProperty(property);
_render.AddViewProp(volume);
#endregion
#region axes
double[] space = _reader.GetOutput().GetSpacing();
Console.WriteLine("spacing[0]={0},[1]={1},[2]={2}", space[0], space[1], space[2]);
int[] extents = _reader.GetOutput().GetExtent();
Console.WriteLine("extents[0]={0},[1]={1},[2]={2},[3]={3},[4]={4},[5]={5}",
extents[0], extents[1], extents[2], extents[3], extents[4], extents[5]);
vtkTransform transform = new vtkTransform();
transform.Translate(0.0, 0.0, 0.0);
transform.Scale((extents[1]) * (space[0]), (extents[3]) * (space[1]), (extents[5]) * (space[2]));
vtkAxesActor axes = new vtkAxesActor();
axes.SetUserTransform(transform);
_render.AddActor(axes);
#endregion
#region text
double scalesize=(extents[1]) * (space[0])/20;
//原点
vtkVectorText otext = new vtkVectorText();
otext.SetText("O");
vtkPolyDataMapper textMapper = new vtkOpenGLPolyDataMapper();
textMapper.SetInputConnection(otext.GetOutputPort());
textActor = new vtkFollower();
textActor.SetMapper(textMapper);
textActor.SetScale(scalesize,scalesize,scalesize);
textActor.AddPosition(0, -0.1, 0);
textActor.SetCamera(_render.GetActiveCamera());
_render.AddViewProp(textActor);
//左 L
vtkVectorText lText = new vtkVectorText();
lText.SetText("L");
vtkPolyDataMapper lMapper = new vtkOpenGLPolyDataMapper();
lMapper.SetInputConnection(lText.GetOutputPort());
vtkFollower lActor = new vtkFollower();
lActor.SetMapper(lMapper);
lActor.SetScale(scalesize,scalesize,scalesize);
lActor.GetProperty().SetColor(0,1,0);
lActor.AddPosition((extents[1] * space[0])+10, (extents[3] * space[1]) / 2, (extents[5] * space[2]) / 2);
lActor.SetCamera(_render.GetActiveCamera());
_render.AddViewProp(lActor);
//右 R
vtkVectorText rText = new vtkVectorText();
rText.SetText("R");
vtkPolyDataMapper rMapper = new vtkOpenGLPolyDataMapper();
rMapper.SetInputConnection(rText.GetOutputPort());
vtkFollower rActor = new vtkFollower();
rActor.SetMapper(rMapper);
rActor.SetScale(scalesize, scalesize, scalesize);
rActor.GetProperty().SetColor(1, 0, 0);
rActor.AddPosition(-10, (extents[3] * space[1]) / 2, (extents[5] * space[2]) / 2);
rActor.SetCamera(_render.GetActiveCamera());
_render.AddViewProp(rActor);
//前 A
vtkVectorText aText = new vtkVectorText();
aText.SetText("A");
vtkPolyDataMapper aMapper = new vtkOpenGLPolyDataMapper();
aMapper.SetInputConnection(aText.GetOutputPort());
vtkFollower aActor = new vtkFollower();
aActor.SetMapper(aMapper);
aActor.SetScale(scalesize, scalesize, scalesize);
aActor.GetProperty().SetColor(0, 1, 0);
aActor.AddPosition((extents[1] * space[0]) / 2, (extents[3] * space[1])+10, (extents[5] * space[2]) / 2);
aActor.SetCamera(_render.GetActiveCamera());
_render.AddViewProp(aActor);
//后 P
vtkVectorText pText = new vtkVectorText();
pText.SetText("P");
vtkPolyDataMapper pMapper = new vtkOpenGLPolyDataMapper();
pMapper.SetInputConnection(pText.GetOutputPort());
vtkFollower pActor = new vtkFollower();
pActor.SetMapper(pMapper);
pActor.SetScale(scalesize, scalesize, scalesize);
pActor.GetProperty().SetColor(1, 0, 0);
pActor.AddPosition((extents[1] * space[0]) / 2, -10, (extents[5] * space[2]) / 2);
pActor.SetCamera(_render.GetActiveCamera());
_render.AddViewProp(pActor);
//头 H
vtkVectorText hText = new vtkVectorText();
hText.SetText("H");
vtkPolyDataMapper hMapper = new vtkOpenGLPolyDataMapper();
hMapper.SetInputConnection(hText.GetOutputPort());
vtkFollower hActor = new vtkFollower();
hActor.SetMapper(hMapper);
hActor.SetScale(scalesize, scalesize, scalesize);
hActor.GetProperty().SetColor(0, 1, 0);
hActor.AddPosition((extents[1] * space[0]) / 2,(extents[3] * space[1]) / 2,-10 );
hActor.SetCamera(_render.GetActiveCamera());
_render.AddViewProp(hActor);
//脚 F
vtkVectorText fText = new vtkVectorText();
fText.SetText("F");
vtkPolyDataMapper fMapper = new vtkOpenGLPolyDataMapper();
fMapper.SetInputConnection(fText.GetOutputPort());
vtkFollower fActor = new vtkFollower();
fActor.SetMapper(fMapper);
fActor.SetScale(scalesize, scalesize, scalesize);
fActor.GetProperty().SetColor(0, 1, 0);
fActor.AddPosition((extents[1] * space[0]) / 2, (extents[3] * space[1]) / 2, (extents[5] * space[2])+10);
fActor.SetCamera(_render.GetActiveCamera());
_render.AddViewProp(fActor);
#endregion
_render.ResetCamera();
vtkFormsWindowControl1.GetRenderWindow().AddRenderer(_render);
_renwin = vtkFormsWindowControl1.GetRenderWindow();
_renwin.AddRenderer(_render);
_renwin.Render();
}
else
{
MessageBox.Show("请先选定文件夹!");
}
}
}
}
效果图: