private void RotateImage(RotationOperation operation) { vtkImageReslice reslice = vtkImageReslice.New(); vtkTransform transform = vtkTransform.New(); transform.PostMultiply(); double[] center = { 75, 100, 0 }; transform.Translate(-center[0], -center[1], -center[2]); if (operation == RotationOperation.Forward) { transform.RotateZ(90); } else if (operation == RotationOperation.Back) { transform.RotateZ(-90); } transform.Translate(+center[0], +center[1], +center[2]); transform.Update(); reslice.SetInput(_viewer.GetInput()); reslice.SetResliceTransform(transform); reslice.Update(); _viewer.SetInput(reslice.GetOutput()); UpdateViewer(); }
/// <summary> /// Update the 2D visualization when the plane moved. /// </summary> /// <param name="plane">PlaneWidget which changed the coordinates.</param> public void PlaneMoved(vtkImagePlaneWidget plane) { vtkImageReslice reslice = vtkImageReslice.New(); vtkTransform transform = vtkTransform.New(); transform.PostMultiply(); //TODO wyznaczenie centrum okna double[] center = { 75, 100, 0 }; transform.Translate(-center[0], -center[1], -center[2]); transform.RotateZ(_orientation); transform.Translate(+center[0], +center[1], +center[2]); transform.Update(); reslice.SetInput(plane.GetResliceOutput()); reslice.SetResliceTransform(transform); reslice.Update(); // vtkImageData viewerInputData; viewerInputData = reslice.GetOutput(); _lastData = viewerInputData; _viewer.SetInput(viewerInputData); // //_viewer.SetInput(reslice.GetOutput()); UpdateViewer(); }
//TODO public void DrawingModeRepaint() { if (_lastData == null) { return; } vtkImageReslice reslice = vtkImageReslice.New(); vtkTransform transform = vtkTransform.New(); transform.PostMultiply(); //TODO wyznaczenie centrum okna double[] center = { 75, 100, 0 }; transform.Translate(-center[0], -center[1], -center[2]); transform.RotateZ(_orientation); transform.Translate(+center[0], +center[1], +center[2]); transform.Update(); reslice.SetInput(_lastData); reslice.SetResliceTransform(transform); reslice.Update(); vtkImageData viewerInputData; if (!DrawingEnabled) { viewerInputData = reslice.GetOutput(); } else { var resliceOutput = reslice.GetOutput(); var sizeArray = resliceOutput.GetDimensions(); vtkImageCanvasSource2D imageCanvas = vtkImageCanvasSource2D.New(); imageCanvas.SetScalarTypeToUnsignedChar(); imageCanvas.SetExtent(0, sizeArray[0], 0, sizeArray[1], 0, 0); imageCanvas.DrawImage(0, 0, resliceOutput); DrawingUtils.Draw(imageCanvas, DrawingInfo); imageCanvas.Update(); viewerInputData = imageCanvas.GetOutput(); } _viewer.SetInput(viewerInputData); UpdateViewer(); }
//切片模式_绘制 private void DrawMode_Slice() { int[] xyz = m_ImageData.GetDimensions(); double[] sp = m_ImageData.GetSpacing(); double[] pos = new double[] { m_XPos, m_YPos, m_ZPos }; #region -------------------XOY切片(垂直Z轴)------------------- m_ImageResliceXOY = vtkImageReslice.New(); m_ImageResliceXOY.SetInput(m_ImageData); m_ImageResliceXOY.SetResliceAxesDirectionCosines( 1, 0, 0, 0, 1, 0, 0, 0, 1 ); m_ImageResliceXOY.InterpolateOn(); m_ImageResliceXOY.SetInterpolationModeToNearestNeighbor(); m_ImageResliceXOY.SetResliceAxesOrigin(pos[0], pos[1], pos[2]); m_ImageResliceXOY.SetOutputDimensionality(2); m_ImageResliceXOY.Update(); m_TextureXOY = vtkTexture.New(); m_TextureXOY.InterpolateOff(); m_TextureXOY.SetInput(m_ImageResliceXOY.GetOutput()); m_TextureXOY.SetLookupTable(m_LookupTable); m_TextureXOY.MapColorScalarsThroughLookupTableOn(); //---------------------set plane position---------- m_PlaneSourceXOY = vtkPlaneSource.New(); m_PlaneSourceXOY.SetXResolution(xyz[0]); m_PlaneSourceXOY.SetYResolution(xyz[1]); m_PlaneSourceXOY.SetOrigin(0, 0, 0); m_PlaneSourceXOY.SetPoint1((xyz[0] - 1) * sp[0], 0, 0); m_PlaneSourceXOY.SetPoint2(0, (xyz[1] - 1) * sp[1], 0); m_PlaneSourceXOY.Push(pos[2]); //---------------------pipeline-------------------- m_PlaneMapperXOY = vtkPolyDataMapper.New(); m_PlaneMapperXOY.SetInput(m_PlaneSourceXOY.GetOutput()); m_ActorXOY = vtkActor.New(); m_ActorXOY.SetMapper(m_PlaneMapperXOY); m_ActorXOY.SetTexture(m_TextureXOY); #endregion #region -------------------XOZ切片(垂直Y轴)------------------- m_ImageResliceXOZ = vtkImageReslice.New(); m_ImageResliceXOZ.SetInput(m_ImageData); m_ImageResliceXOZ.SetResliceAxesDirectionCosines( 1, 0, 0, 0, 0, -1, 0, 1, 0 ); m_ImageResliceXOZ.InterpolateOn(); m_ImageResliceXOZ.SetInterpolationModeToNearestNeighbor(); m_ImageResliceXOZ.SetResliceAxesOrigin(pos[0], pos[1], pos[2]); m_ImageResliceXOZ.SetOutputDimensionality(2); m_ImageResliceXOZ.Update(); m_TextureXOZ = vtkTexture.New(); m_TextureXOZ.SetInput(m_ImageResliceXOZ.GetOutput()); m_TextureXOZ.SetLookupTable(m_LookupTable); m_TextureXOZ.MapColorScalarsThroughLookupTableOn(); //---------------------set plane position-------------------- m_PlaneSourceXOZ = vtkPlaneSource.New(); m_PlaneSourceXOZ.SetXResolution(xyz[0]); m_PlaneSourceXOZ.SetYResolution(xyz[2]); m_PlaneSourceXOZ.SetOrigin(0, 0, (xyz[2] - 1) * sp[2]); m_PlaneSourceXOZ.SetPoint1((xyz[0] - 1) * sp[0], 0, (xyz[2] - 1) * sp[2]); m_PlaneSourceXOZ.SetPoint2(0, 0, 0); m_PlaneSourceXOZ.Push(pos[1]); //---------------------pipeline------------------------------ m_PlaneMapperXOZ = vtkPolyDataMapper.New(); m_PlaneMapperXOZ.SetInput(m_PlaneSourceXOZ.GetOutput()); m_ActorXOZ = vtkActor.New(); m_ActorXOZ.SetMapper(m_PlaneMapperXOZ); m_ActorXOZ.SetTexture(m_TextureXOZ); #endregion #region -------------------YOZ切片(垂直X轴)------------------- m_ImageResliceYOZ = vtkImageReslice.New(); m_ImageResliceYOZ.SetInput(m_ImageData); m_ImageResliceYOZ.SetResliceAxesDirectionCosines( 0, 0, -1, 0, 1, 0, 1, 0, 0 ); m_ImageResliceYOZ.InterpolateOn(); m_ImageResliceYOZ.SetInterpolationModeToNearestNeighbor(); m_ImageResliceYOZ.SetResliceAxesOrigin(pos[0], pos[1], pos[2]); m_ImageResliceYOZ.SetOutputDimensionality(2); m_ImageResliceYOZ.Update(); m_TextureYOZ = vtkTexture.New(); m_TextureYOZ.SetInput(m_ImageResliceYOZ.GetOutput()); m_TextureYOZ.SetLookupTable(m_LookupTable); m_TextureYOZ.MapColorScalarsThroughLookupTableOn(); //---------------------set plane position-------------------- m_PlaneSourceYOZ = vtkPlaneSource.New(); m_PlaneSourceYOZ.SetXResolution(xyz[2]); m_PlaneSourceYOZ.SetYResolution(xyz[1]); m_PlaneSourceYOZ.SetOrigin(0, 0, (xyz[2] - 1) * sp[2]); m_PlaneSourceYOZ.SetPoint1(0, 0, 0); m_PlaneSourceYOZ.SetPoint2(0, (xyz[1] - 1) * sp[1], (xyz[2] - 1) * sp[2]); m_PlaneSourceYOZ.Push(pos[0]); //---------------------pipeline------------------------------ m_PlaneMapperYOZ = vtkPolyDataMapper.New(); m_PlaneMapperYOZ.SetInput(m_PlaneSourceYOZ.GetOutput()); m_ActorYOZ = vtkActor.New(); m_ActorYOZ.SetMapper(m_PlaneMapperYOZ); m_ActorYOZ.SetTexture(m_TextureYOZ); #endregion m_Renderer.AddActor(m_ActorXOY); m_Renderer.AddActor(m_ActorXOZ); m_Renderer.AddActor(m_ActorYOZ); }
/// <summary> /// Rotates 3D vtk volume around x and y axes. /// </summary> /// <param name="input"></param> /// <param name="angle"></param> /// <param name="axis"></param> /// <param name="out_extent"></param> /// <returns></returns> public static vtkImageData rotate_sample(vtkImageData input, double angle, int axis, int out_extent = 0) { //get input data dimensions int[] dims = input.GetExtent(); //Compute centers int[] centers = new int[] { (dims[1] + dims[0]) / 2, (dims[3] + dims[2]) / 2, (dims[5] + dims[4]) / 2 }; //Set rotation axis int[] axes = new int[3]; axes[axis] = 1; int[] new_dims = new int[] { dims[0], dims[1], dims[2], dims[3], dims[4], dims[5] }; int[] new_centers = new int[] { centers[0], centers[1], centers[2] }; //Compute new sample dimensions if (axis == 0) { new_dims[3] = (int)(Math.Cos(Math.Abs(angle / 180) * Math.PI) * new_dims[3] + Math.Sin(Math.Abs(angle / 180) * Math.PI) * new_dims[5]); new_dims[5] = (int)(Math.Sin(Math.Abs(angle / 180) * Math.PI) * new_dims[3] + Math.Cos(Math.Abs(angle / 180) * Math.PI) * new_dims[5]); new_centers[1] = (Math.Abs(new_dims[3]) + Math.Abs(new_dims[2])) / 2; new_centers[2] = (Math.Abs(new_dims[5]) + Math.Abs(new_dims[4])) / 2; } if (axis == 1) { new_dims[1] = (int)(Math.Cos(Math.Abs(angle / 180) * Math.PI) * new_dims[1] + Math.Sin(Math.Abs(angle / 180) * Math.PI) * new_dims[5]); new_dims[5] = (int)(Math.Sin(Math.Abs(angle / 180) * Math.PI) * new_dims[1] + Math.Cos(Math.Abs(angle / 180) * Math.PI) * new_dims[5]); new_centers[0] = (Math.Abs(new_dims[0]) + Math.Abs(new_dims[1])) / 2; new_centers[2] = (Math.Abs(new_dims[5]) + Math.Abs(new_dims[4])) / 2; } //Image transformation vtkTransform transform = vtkTransform.New(); transform.Translate(centers[0], centers[1], centers[2]); transform.RotateWXYZ(angle, axes[0], axes[1], axes[2]); if (out_extent == 0) { transform.Translate(-centers[0], -centers[1], -centers[2]); } else { transform.Translate(-new_centers[0], -new_centers[1], -new_centers[2]); } //Console.ReadKey(); transform.Update(); //Compute new data extent int[] diff = new int[] { new_dims[1] - dims[1], new_dims[3] - dims[3], new_dims[5] - dims[5] }; new_dims[0] += diff[0] / 2; new_dims[1] -= diff[0] / 2; new_dims[2] += diff[1] / 2; new_dims[3] -= diff[1] / 2; new_dims[4] += diff[2] / 2; new_dims[5] -= diff[2] / 2; //Image reslicing vtkImageReslice rotater = vtkImageReslice.New(); rotater.SetInput(input); rotater.SetInformationInput(input); rotater.SetResliceTransform(transform); rotater.SetInterpolationModeToCubic(); //rotater.SetInterpolationModeToLinear(); if (out_extent == 1) { rotater.SetOutputSpacing(input.GetSpacing()[0], input.GetSpacing()[1], input.GetSpacing()[2]); rotater.SetOutputOrigin(input.GetOrigin()[0], input.GetOrigin()[1], input.GetOrigin()[2]); rotater.SetOutputExtent(new_dims[0], new_dims[1], new_dims[2], new_dims[3], new_dims[4], new_dims[5]); } rotater.Update(); vtkImageData output = vtkImageData.New(); output.DeepCopy(rotater.GetOutput()); rotater.Dispose(); transform.Dispose(); return(output); }