VTK 实现MinIP Activiz

public partial class Form1 : Form
    {
        #region 私有变量
        private Kitware.VTK.vtkRenderer _render = null;
        private Kitware.VTK.vtkRenderWindow _renWin = null;
        private Kitware.VTK.vtkRenderWindowInteractor _iren = null;
        private Kitware.VTK.vtkDICOMImageReader _reader = null;
        private double opacityWindow = 4096;
        private double opacityLevel = 2048;

        #endregion

        #region 属性
        public string FileDir
        {
            get;
            set;
        }
        #endregion

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog dlg = new FolderBrowserDialog();
            if (DialogResult.OK == dlg.ShowDialog())
            {
                FileDir = dlg.SelectedPath;
            }
        }

        private void renderWindowControl1_Load(object sender, EventArgs e)
        {
            _render = renderWindowControl1.RenderWindow.GetRenderers().GetFirstRenderer();
            _renWin = renderWindowControl1.RenderWindow;
            _iren = renderWindowControl1.RenderWindow.GetInteractor();

        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (!String.IsNullOrEmpty(FileDir))
            {
                _reader = new Kitware.VTK.vtkDICOMImageReader();
                _reader.SetDirectoryName(FileDir);
                _reader.SetDataByteOrderToLittleEndian();
                _reader.Update();

                _reader.SetDataScalarTypeToShort();
                _reader.UpdateWholeExtent();
                _reader.GetOutput().UpdateInformation();

                double[] range = _reader.GetOutput().GetScalarRange();//获得颜色映射标量值的范围

                double min = range[1];//
                double max = range[0];//
                double diff = max - min;
                double slope = 255.0 / diff;//斜率
                double inter = -slope * min;//截距
                double shift = inter / slope;

                vtkImageShiftScale vtkImageCast = vtkImageShiftScale.New();
                //With vtkImageShiftScale Pixels are shifted
                //(a constant value added) and then scaled (multiplied by a scalar. As a convenience,
                //this class allows you to set the output scalar type similar to vtkImageCast.
                //This is because shift scale operations frequently convert data types.

                //如果不进行转换,vtkVolumeRayCastMapper会无法渲染short类型的数据,
                //必须要经过转换将数据转换为vtkVolumeRayCastMapper可以渲染的数据
                vtkImageCast.SetInput(_reader.GetOutput());
                vtkImageCast.SetScale(slope);
                vtkImageCast.SetShift(shift);
                vtkImageCast.SetOutputScalarTypeToUnsignedShort();
                vtkImageCast.Update();

                //获得透明度转换函数的参数
                range = vtkImageCast.GetOutput().GetScalarRange();
                double level = 0.5 * (range[1] + range[0]);
                double window = range[1] - range[0];

                vtkPiecewiseFunction opacityFun = new vtkPiecewiseFunction();
                opacityFun.AddPoint(level - window / 2, 0.0);
                opacityFun.AddPoint(level + window / 2, 1.0);

                vtkPiecewiseFunction grayTransferFun = new vtkPiecewiseFunction();
                grayTransferFun.AddSegment(level - window / 2, 0.0, level + window / 2, 1.0);

                vtkVolumeProperty property = new vtkVolumeProperty();
                property.SetInterpolationTypeToLinear();
                property.SetScalarOpacity(opacityFun);
                property.SetColor(grayTransferFun);

                vtkVolumeRayCastMIPFunction mipFun = new vtkVolumeRayCastMIPFunction();
                mipFun.SetMaximizeMethodToOpacity();
                
                

                vtkVolumeRayCastMapper mapper = new vtkVolumeRayCastMapper();
                mapper.SetVolumeRayCastFunction(mipFun);
                mapper.SetInput(vtkImageCast.GetOutput());
                // mapper.SetInput(_reader.GetOutput());
                //会报错:无法渲染非unsigned char或者unsigned short 类型的数据
                //vtkVolumeRayCastMapper (09C92D38):
                //Cannot volume render data of type short, only unsigned char or unsigned short.


                vtkVolume volume = new vtkVolume();
                volume.SetProperty(property);
                volume.SetMapper(mapper);


                _render.AddViewProp(volume);
                _render.ResetCamera();

                _renWin.Render();
                _iren.Initialize();
                _iren.Start();
            }
            else
            {
                MessageBox.Show("请先选定文件夹!");
            }
        }
    }

你可能感兴趣的:(VTK 实现MinIP Activiz)