参考水灵大神的代码编写的,将其改为在C#下,用activiz实现。
大神的源码在这里:
http://blog.csdn.net/www_doling_net/article/details/8551523
在c#中,有些VTK的功能不支持,所以需要自己改一下:
namespace SliceMonitortest
{
/// <summary>
/// 封装了4*4矩阵的乘法
/// 因为在Activiz中,vtkMatrix4x4的 MultiplyPoint 功能无法使用,所以自己封装了一个类来实现矩阵乘法。
/// </summary>
public class Matrix4
{
private double[,] vtkArray;
public double[,] VtkArray
{
get
{
return vtkArray;
}
}
public Matrix4(vtkMatrix4x4 vtkMatrix)
{
vtkArray=new double[4,4];
for (int i = 0; i < 4; i++)
{
//double[] temp = new double[4];
for (int j = 0; j < 4; j++)
{
vtkArray[i,j] = vtkMatrix.GetElement(i,j);
}
}
}
/// <summary>
/// 矩阵乘法
/// </summary>
/// <param name="inArray">输入矩阵</param>
/// <param name="outArray">输出矩阵</param>
public void MultiplyPoint(double[] inArray,double[] outArray)
{
for (int i = 0; i < 4; i++)
{
outArray[i] = 0.0;
for (int j = 0; j < 4; j++)
{
outArray[i] += vtkArray[i, j] * inArray[j];
}
}
}
}
}
namespace SliceMonitortest
{
public partial class Form1 : Form
{
private vtkDICOMImageReader _reader = null;
private vtkRenderer _render = null;
private vtkRenderWindow _renwin = null;
private vtkRenderWindowInteractor _iren = null;
private vtkImageReslice reslice = null;
private vtkObject.vtkObjectEventHandler InteractorHandler = null;
private int Slicing;
public string FileDir
{
get;
set;
}
public Form1()
{
InitializeComponent();
}
private void renderWindowControl1_Load(object sender, EventArgs e)
{
_renwin = renderWindowControl1.RenderWindow;
_render = _renwin.GetRenderers().GetFirstRenderer();
_iren = _renwin.GetInteractor();
InteractorHandler=new vtkObject.vtkObjectEventHandler(_iren_AnyEvt);//注册交互事件处理程序
_iren.AnyEvt += InteractorHandler;
Slicing = 0;
}
void _iren_AnyEvt(vtkObject sender, vtkObjectEventArgs e)
{
int[] lastPos = _iren.GetLastEventPosition();
int[] currPos = _iren.GetEventPosition();
vtkCommand.EventIds eid = (vtkCommand.EventIds)e.EventId;
if (eid == vtkCommand.EventIds.LeftButtonPressEvent)
{
this.Slicing = 1;
}
else if (eid == vtkCommand.EventIds.LeftButtonReleaseEvent)
{
this.Slicing = 0;
}
else if (eid == vtkCommand.EventIds.MouseMoveEvent)
{
if (this.Slicing==1)
{
int deltY = lastPos[1] - currPos[1];//计算鼠标移动
reslice.Update();
double sliceSpacing = reslice.GetOutput().GetSpacing()[2];
vtkMatrix4x4 matrix = reslice.GetResliceAxes();//获取转换矩阵
Matrix4 tempmatrix = new Matrix4(matrix);
//因为vtkMatrix4x4的 MultiplyPoint 功能无法使用,所以自己封装了一个类实现矩阵乘法
// move the center point that we are slicing through
double[] point=new double[4]{0.0,0.0,sliceSpacing*deltY,1.0};
double[] center = new double[4]{0.0,0.0,0.0,0.0};
tempmatrix.MultiplyPoint(point,center);
//计算边界,当超出边界时不再移动
int[] extent = _reader.GetOutput().GetExtent();
double[] spacing = _reader.GetOutput().GetSpacing();
double[] origin = _reader.GetOutput().GetOrigin();
double[] Border=new double[3];
Border[0]= origin[0] + spacing[0] * (extent[0] + extent[1]);
Border[1]= origin[1] + spacing[1] * (extent[2] + extent[3]);
Border[2]= origin[2] + spacing[2] * (extent[4] + extent[5]);
for (int i = 0; i < 3; i++)
{
if (center[i] < origin[i]) center[i] = origin[i];
}
for (int i = 0; i < 3; i++)
{
if (center[i] > Border[i]) center[i] = Border[i];
}
matrix.SetElement(0, 3, center[0]);
matrix.SetElement(1, 3, center[1]);
matrix.SetElement(2, 3, center[2]);
//if((center[0]<0)||(center[0]>))
_iren.Render();
}
else
{
vtkInteractorStyle style = vtkInteractorStyle.SafeDownCast(_iren.GetInteractorStyle());
if (style != null)
{
style.OnMouseMove();
}
}
}
}
private void btn_ReadFiles_Click(object sender, EventArgs e)
{
FolderBrowserDialog dlg = new FolderBrowserDialog();
if (dlg.ShowDialog() == DialogResult.OK)
{
FileDir = dlg.SelectedPath;
}
if (!String.IsNullOrEmpty(FileDir))
{
_reader = new Kitware.VTK.vtkDICOMImageReader();
_reader.SetDirectoryName(FileDir);
_reader.SetDataByteOrderToLittleEndian();
_reader.Update();
int[] extent = _reader.GetOutput().GetExtent();
double[] spacing = _reader.GetOutput().GetSpacing();
double[] origin = _reader.GetOutput().GetOrigin();
double[] center = new double[3];
center[0] = origin[0] + spacing[0] * 0.5 * (extent[0] + extent[1]);
center[1] = origin[1] + spacing[1] * 0.5 * (extent[2] + extent[3]);
center[2] = origin[2] + spacing[2] * 0.5 * (extent[4] + extent[5]);
double[] axialElements ={
1,0,0,0,
0,1,0,0,
0,0,1,0,
0,0,0,1
};//平行于XY平面,轴面
vtkMatrix4x4 resliceAxes = new vtkMatrix4x4();
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
resliceAxes.SetElement(i, j, axialElements[i * 4 + j]);
}
resliceAxes.SetElement(0, 3, center[0]);
resliceAxes.SetElement(1, 3, center[1]);
resliceAxes.SetElement(2, 3, center[2]);
Console.WriteLine("center[0]:{0},center[1]:{1},center[2]:{2}",center[0],center[1],center[2]);
reslice = new vtkImageReslice();
reslice.SetInputConnection(_reader.GetOutputPort());
reslice.SetOutputDimensionality(2);
reslice.SetResliceAxes(resliceAxes);
reslice.SetInterpolationModeToLinear();
vtkLookupTable colortable = new vtkLookupTable();
colortable.SetRange(0, 1000);
colortable.SetValueRange(0.0, 1.0);
colortable.SetSaturationRange(0.0, 0.0);
colortable.SetRampToLinear();
colortable.Build();
vtkImageMapToColors colormap = new vtkImageMapToColors();
colormap.SetLookupTable(colortable);
colormap.SetInputConnection(reslice.GetOutputPort());
vtkImageActor imgActor = new vtkImageActor();
imgActor.SetInput(colormap.GetOutput());
_render.AddActor(imgActor);
_render.SetBackground(0.4, 0.5, 0.6);
vtkInteractorStyle imagestyle = new vtkInteractorStyle();
_iren.SetInteractorStyle(imagestyle);
_render.ResetCamera();
_renwin.Render();
_iren.Initialize();
_iren.Start();
}
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
if (_iren != null)
_iren.AnyEvt -= InteractorHandler;
}
}
}