/// <summary> /// Function for removing sample edges. /// </summary> /// <param name="stack"></param> /// <param name="side"></param> /// <param name="get_center"></param> /// <returns></returns> public static vtkImageData center_crop(vtkImageData stack, int side = 400, bool get_center = true) { //Get input dimensions int[] dims = stack.GetExtent(); //Find the center of the sample int x1; int x2; int y1; int y2; int[] center = find_center(stack, 70, new int[] { 0, (dims[5] - dims[4] + 1) / 3 });//GetCenter(bytedata,80); //Compute new volume sides y2 = Math.Min(center[0] + (side / 2), dims[1]); y1 = Math.Max(y2 - side + 1, dims[0]); x2 = Math.Min(center[1] + (side / 2), dims[3]); x1 = Math.Max(x2 - side + 1, dims[2]); //Create VOI extractor vtkExtractVOI cropper = vtkExtractVOI.New(); cropper.SetVOI(y1, y2, x1, x2, dims[4], dims[5]); cropper.SetInput(stack); cropper.Update(); return(cropper.GetOutput()); }
/// <summary> /// Gets a 2D slice from the 3D data. /// </summary> /// <param name="volume">Full 3D data.</param> /// <param name="sliceN">Number of slice to be selected.</param> /// <param name="axis">Axis on which selection will be made.</param> /// <returns></returns> public static vtkImageData volumeSlicer(vtkImageData volume, int[] sliceN, int axis) { //Initialize VOI extractor and permuter. //Permuter will correct the orientation of the output image vtkExtractVOI slicer = vtkExtractVOI.New(); vtkImagePermute permuter = vtkImagePermute.New(); //Connect data to slicer slicer.SetInput(volume); slicer.Update(); //Get data dimensions int[] dims = slicer.GetOutput().GetExtent(); //Get slice //Coronal plane if (axis == 0) { //Set VOI slicer.SetVOI(sliceN[0] - 1, sliceN[0], dims[2], dims[3], dims[4], dims[5]); slicer.Update(); //Permute image (not necessary here) permuter.SetInputConnection(slicer.GetOutputPort()); permuter.SetFilteredAxes(1, 2, 0); permuter.Update(); } //Transverse plane YZ if (axis == 1) { //Set VOI slicer.SetVOI(dims[0], dims[1], sliceN[1] - 1, sliceN[1], dims[4], dims[5]); slicer.Update(); //Permute image permuter.SetInputConnection(slicer.GetOutputPort()); permuter.SetFilteredAxes(0, 2, 1); permuter.Update(); } //Transverse plane, XZ if (axis == 2) { //Set VOI slicer.SetVOI(dims[0], dims[1], dims[2], dims[3], sliceN[2] - 1, sliceN[2]); slicer.Update(); //Permute image permuter.SetInputConnection(slicer.GetOutputPort()); permuter.SetFilteredAxes(0, 1, 2); permuter.Update(); } //slicer.Update(); //Return copy of the slice return(permuter.GetOutput()); }
/// <summary> /// Scans the input mask slice by slice and selects the largest binary component of each slice. /// Return cleaned mask as vtkImageData /// </summary> /// <param name="input"></param> /// <param name="extent"></param> /// <param name="threshold"></param> /// <param name="axes"></param> /// <returns></returns> public static vtkImageData FalsePositiveSuppresion(vtkImageData input, int[] extent, double threshold, int axis, double scale = 1.0) { //Slice extractor vtkExtractVOI slicer = vtkExtractVOI.New(); //Permuter vtkImagePermute permuter = vtkImagePermute.New(); //List of outputs List <byte[, , ]> outputs = new List <byte[, , ]>(); //List of output orientations List <int[]> orientations = new List <int[]>(); //vtkImageData size int[] full_extent = input.GetExtent(); //Set range for slices int start = 0, stop = 0; int[] size = new int[2]; int[] outextent = new int[4]; if (axis == 0) { start = extent[0]; stop = extent[1]; size = new int[] { extent[3] - extent[2] + 1, extent[5] - extent[4] + 1 }; outextent = new int[] { extent[2], extent[3] + 1, extent[4], extent[5] + 1 }; } if (axis == 1) { start = extent[2]; stop = extent[3]; size = new int[] { extent[1] - extent[0] + 1, extent[5] - extent[4] + 1 }; outextent = new int[] { extent[0], extent[1] + 1, extent[4], extent[5] + 1 }; } if (axis == 2) { start = extent[4]; stop = extent[5]; size = new int[] { extent[1] - extent[0] + 1, extent[3] - extent[2] + 1 }; outextent = new int[] { extent[0], extent[1] + 1, extent[2], extent[3] + 1 }; } //Temporary array for output byte[,,] output = new byte[full_extent[1] + 1, full_extent[3] + 1, full_extent[5] + 1]; int[] outsize = new int[] { size[0], size[1], stop - start + 1 }; //Loop over current axis for (int k = start; k < stop; k++) { byte[] bytedata = new byte[size[0] * size[1]]; //Select slice if (axis == 0) { slicer.Dispose(); slicer = vtkExtractVOI.New(); slicer.SetInput(input); slicer.SetVOI(k, k, extent[2], extent[3], extent[4], extent[5]); slicer.Update(); permuter.Dispose(); permuter = vtkImagePermute.New(); permuter.SetInput(slicer.GetOutput()); permuter.SetFilteredAxes(1, 2, 0); permuter.Update(); } if (axis == 1) { slicer.Dispose(); slicer = vtkExtractVOI.New(); slicer.SetInput(input); slicer.SetVOI(extent[0], extent[1], k, k, extent[4], extent[5]); slicer.Update(); permuter.Dispose(); permuter = vtkImagePermute.New(); permuter.SetInput(slicer.GetOutput()); permuter.SetFilteredAxes(0, 2, 1); permuter.Update(); } if (axis == 2) { slicer.Dispose(); slicer = vtkExtractVOI.New(); slicer.SetInput(input); slicer.SetVOI(extent[0], extent[1], extent[2], extent[3], k, k); slicer.Update(); permuter.Dispose(); permuter = vtkImagePermute.New(); permuter.SetInput(slicer.GetOutput()); permuter.SetFilteredAxes(0, 1, 2); permuter.Update(); } //Convert data to byte bytedata = DataTypes.vtkToByte(permuter.GetOutput()); slicer.Dispose(); permuter.Dispose(); //convert data to Mat Mat image = new Mat(size[1], size[0], MatType.CV_8UC1, bytedata); //Get largest binary object Mat bw = Processing.LargestBWObject(image, 0.7 * 255.0); //Set slice to byte array if (bw.Sum().Val0 > 0) { output = DataTypes.setByteSlice(output, bw, outextent, axis, k); } } return(DataTypes.byteToVTK(output)); }
//private void CommonInit(Sequence BinarySubImageSeq) //{ // vtkImageData ImageData1 = new vtkImageData(); // ImageData1.SetDimensions(BinarySubImageSeq.Width, BinarySubImageSeq.Height, BinarySubImageSeq.Depth); // ImageData1.SetNumberOfScalarComponents(1); // ImageData1.SetSpacing(BinarySubImageSeq.XResolution, BinarySubImageSeq.YResolution, BinarySubImageSeq.ZResolution); // ImageData1.SetScalarTypeToFloat(); // vtkFloatArray array1 = new vtkFloatArray(); // for (int i = 0; i < BinarySubImageSeq.ImageSize; i++) // array1.InsertTuple1(i, BinarySubImageSeq[0].Data[0][i]); // ImageData1.GetPointData().SetScalars(array1); // vtkExtractVOI VOI = new vtkExtractVOI(); // VOI.SetInput(ImageData1); // VOI.SetSampleRate(1, 1, 1); // vtkMarchingCubes ContourObject = vtkMarchingCubes.New(); // vtk_PolyDataMapper = vtkPolyDataMapper.New(); // //ContourActor = new vtkActor(); // VOI.SetVOI(0, BinarySubImageSeq.Width - 1, 0, BinarySubImageSeq.Height - 1, 0, BinarySubImageSeq.Depth - 1); // ContourObject.SetInput(VOI.GetOutput()); // ContourObject.SetValue(0, 0.5); // vtk_PolyDataMapper.SetInput(ContourObject.GetOutput()); // vtk_PolyDataMapper.ScalarVisibilityOn(); // vtk_PolyDataMapper.SetScalarModeToUseFieldData(); //} ///// <summary> ///// Generate a 3D mesh using marching-cubes algorithm. If voxel value is lower than 1 it is consider as background, else as object ///// </summary> ///// <param name="BinarySubImageSeq">The binary image</param> ///// <param name="Colour">Mesh color</param> ///// <param name="Pos">Postion of the object in the world</param> //public void Generate(Sequence BinarySubImageSeq, Color Colour, cPoint3D Pos) //{ // vtkImageData ImageData1 = new vtkImageData(); // ImageData1.SetDimensions(BinarySubImageSeq.Width, BinarySubImageSeq.Height, BinarySubImageSeq.Depth); // ImageData1.SetNumberOfScalarComponents(1); // ImageData1.SetSpacing(BinarySubImageSeq.XResolution, BinarySubImageSeq.YResolution, BinarySubImageSeq.ZResolution); // ImageData1.SetScalarTypeToFloat(); // vtkFloatArray array1 = new vtkFloatArray(); // for (int i = 0; i < BinarySubImageSeq.ImageSize; i++) // array1.InsertTuple1(i, BinarySubImageSeq[0].Data[0][i]); // ImageData1.GetPointData().SetScalars(array1); // vtkExtractVOI VOI = new vtkExtractVOI(); // VOI.SetInput(ImageData1); // VOI.SetSampleRate(1, 1, 1); // vtkMarchingCubes ContourObject = vtkMarchingCubes.New(); // vtk_PolyDataMapper = vtkPolyDataMapper.New(); // //ContourActor = new vtkActor(); // VOI.SetVOI(0, BinarySubImageSeq.Width - 1, 0, BinarySubImageSeq.Height - 1, 0, BinarySubImageSeq.Depth - 1); // // perform the amrching cubes // ContourObject.SetInput(VOI.GetOutput()); // ContourObject.SetValue(0, 0.5); // //vtkDecimatePro deci // //deci SetInputConnection [fran GetOutputPort] // //deci SetTargetReduction 0.9 // //deci PreserveTopologyOn // if (MeshSmoother!=null) // { // vtkSmoothPolyDataFilter smoother = new vtkSmoothPolyDataFilter(); // smoother.SetInputConnection(ContourObject.GetOutputPort());// [deci GetOutputPort] // smoother.SetNumberOfIterations(50); // vtk_PolyData = smoother.GetOutput(); // } // else // { // vtk_PolyData = ContourObject.GetOutput(); // } // vtk_PolyDataMapper.SetInput(vtk_PolyData); // vtk_PolyDataMapper.ScalarVisibilityOn(); // vtk_PolyDataMapper.SetScalarModeToUseFieldData(); // this.Position = new cPoint3D(Pos.X, Pos.Y, Pos.Z); // this.Colour = Colour; // CreateVTK3DObject(1); // vtk_PolyData = ContourObject.GetOutput(); // // compute convex hull // hullFilter = vtkHull.New(); // hullFilter.SetInputConnection(ContourObject.GetOutputPort()); // hullFilter.AddRecursiveSpherePlanes(1); // hullFilter.Update(); // // this.BackfaceCulling(false); // Information = new cInformation(ContourObject, this, hullFilter); //} public void Generate(cImage BinarySubImageSeq, Color Colour, cPoint3D Pos/*, List<cBiological3DObject> Containers, int ContainerMode*/) { vtkImageData ImageData1 = new vtkImageData(); ImageData1.SetDimensions(BinarySubImageSeq.Width, BinarySubImageSeq.Height, BinarySubImageSeq.Depth); ImageData1.SetNumberOfScalarComponents(1); ImageData1.SetSpacing(BinarySubImageSeq.Resolution.X, BinarySubImageSeq.Resolution.Y, BinarySubImageSeq.Resolution.Z); ImageData1.SetScalarTypeToFloat(); vtkFloatArray array1 = new vtkFloatArray(); for (int i = 0; i < BinarySubImageSeq.ImageSize; i++) array1.InsertTuple1(i, BinarySubImageSeq.SingleChannelImage[0].Data[i]); ImageData1.GetPointData().SetScalars(array1); vtkExtractVOI VOI = new vtkExtractVOI(); VOI.SetInput(ImageData1); VOI.SetSampleRate(1, 1, 1); vtkMarchingCubes ContourObject = vtkMarchingCubes.New(); vtk_PolyDataMapper = vtkPolyDataMapper.New(); //ContourActor = new vtkActor(); VOI.SetVOI(0, BinarySubImageSeq.Width - 1, 0, BinarySubImageSeq.Height - 1, 0, BinarySubImageSeq.Depth - 1); ContourObject.SetInput(VOI.GetOutput()); ContourObject.SetValue(0, 0.5); vtkAlgorithmOutput AlgoOutPut = null; if (MeshSmoother != null) { //vtkSmoothPolyDataFilter smoother = new vtkSmoothPolyDataFilter(); vtkWindowedSincPolyDataFilter smoother = new vtkWindowedSincPolyDataFilter(); smoother.SetInputConnection(ContourObject.GetOutputPort());// [deci GetOutputPort] smoother.SetNumberOfIterations(MeshSmoother.NumberOfIterations); vtk_PolyData = smoother.GetOutput(); //smoother.GetOutputPort(); AlgoOutPut = smoother.GetOutputPort(); } else { vtk_PolyData = ContourObject.GetOutput(); AlgoOutPut = ContourObject.GetOutputPort(); } vtk_PolyDataMapper.SetInput(vtk_PolyData); vtk_PolyDataMapper.ScalarVisibilityOn(); vtk_PolyDataMapper.SetScalarModeToUseFieldData(); vtkActor TmpActor = vtkActor.New(); TmpActor.SetMapper(vtk_PolyDataMapper); TmpActor.SetPosition(Pos.X, Pos.Y, Pos.Z); //Console.WriteLine("PosX"+Pos.X+" PosY"+Pos.Y+" PosZ"+Pos.Z); #region deal with the containers if (this.Containers != null) { if (this.Containers.ContainerMode == 0) { cPoint3D Centroid = new cPoint3D((float)TmpActor.GetCenter()[0], (float)TmpActor.GetCenter()[1], (float)TmpActor.GetCenter()[2]); bool IsInside = false; for (int Idx = 0; Idx < Containers.Containers.Count; Idx++) { cBiological3DVolume CurrentContainer = (cBiological3DVolume)(Containers.Containers[Idx]); if (CurrentContainer.IsPointInside(Centroid)) { IsInside = true; ContainerIdx = Idx; break; } } if (IsInside) { this.SetPosition(new cPoint3D(Pos.X, Pos.Y, Pos.Z)); this.Colour = Colour; CreateVTK3DObject(1); // vtk_PolyData = ContourObject.GetOutput(); // compute convex hull hullFilter = vtkHull.New(); hullFilter.SetInputConnection(AlgoOutPut); hullFilter.AddRecursiveSpherePlanes(0); hullFilter.Update(); Information = new cInformation(AlgoOutPut, this, hullFilter); this.Detected = true; } else { this.Detected = false; } } else if (Containers.ContainerMode == 1) { this.Detected = true; //bool IsInside = false; for (int Idx = 0; Idx < Containers.Containers.Count; Idx++) { cBiological3DVolume CurrentContainer = (cBiological3DVolume)(Containers.Containers[Idx]); if (CurrentContainer.IsPointInside(Pos)) { //IsInside = false; this.Detected = false; return; } } this.SetPosition(new cPoint3D(Pos.X, Pos.Y, Pos.Z)); this.Colour = Colour; CreateVTK3DObject(1); // vtk_PolyData = ContourObject.GetOutput(); // compute convex hull hullFilter = vtkHull.New(); hullFilter.SetInputConnection(AlgoOutPut); hullFilter.AddRecursiveSpherePlanes(0); hullFilter.Update(); Information = new cInformation(AlgoOutPut, this, hullFilter); this.Detected = true; } } else { this.SetPosition(new cPoint3D(Pos.X, Pos.Y, Pos.Z)); this.Colour = Colour; CreateVTK3DObject(1); // vtk_PolyData = ContourObject.GetOutput(); // compute convex hull hullFilter = vtkHull.New(); hullFilter.SetInputConnection(AlgoOutPut); hullFilter.AddRecursiveSpherePlanes(1); hullFilter.Update(); // this.BackfaceCulling(false); Information = new cInformation(AlgoOutPut, this, hullFilter); } #endregion }
public void Generate(CImage3D BinarySubImageSeq, Color Colour, cPoint3D Pos) { vtkImageData ImageData1 = new vtkImageData(); ImageData1.SetDimensions(BinarySubImageSeq.Width, BinarySubImageSeq.Height, BinarySubImageSeq.Depth); ImageData1.SetNumberOfScalarComponents(1); //ImageData1.SetSpacing(BinarySubImageSeq.XResolution, BinarySubImageSeq.YResolution, BinarySubImageSeq.ZResolution); ImageData1.SetScalarTypeToFloat(); vtkFloatArray array1 = new vtkFloatArray(); for (int i = 0; i < BinarySubImageSeq.ImageSize; i++) array1.InsertTuple1(i, BinarySubImageSeq.Data[i]); ImageData1.GetPointData().SetScalars(array1); vtkExtractVOI VOI = new vtkExtractVOI(); VOI.SetInput(ImageData1); VOI.SetSampleRate(1, 1, 1); vtkMarchingCubes ContourObject = vtkMarchingCubes.New(); vtk_PolyDataMapper = vtkPolyDataMapper.New(); //ContourActor = new vtkActor(); VOI.SetVOI(0, BinarySubImageSeq.Width - 1, 0, BinarySubImageSeq.Height - 1, 0, BinarySubImageSeq.Depth - 1); ContourObject.SetInput(VOI.GetOutput()); ContourObject.SetValue(0, 0.5); vtkAlgorithmOutput AlgoOutPut = null; vtk_PolyData = ContourObject.GetOutput(); AlgoOutPut = ContourObject.GetOutputPort(); vtk_PolyDataMapper.SetInput(vtk_PolyData); vtk_PolyDataMapper.ScalarVisibilityOn(); vtk_PolyDataMapper.SetScalarModeToUseFieldData(); vtkActor TmpActor = vtkActor.New(); TmpActor.SetMapper(vtk_PolyDataMapper); TmpActor.SetPosition(Pos.X, Pos.Y, Pos.Z); //Console.WriteLine("PosX"+Pos.X+" PosY"+Pos.Y+" PosZ"+Pos.Z); #region deal with the containers this.Position = new cPoint3D(Pos.X, Pos.Y, Pos.Z); this.Colour = Colour; CreateVTK3DObject(1); // vtk_PolyData = ContourObject.GetOutput(); // compute convex hull hullFilter = vtkHull.New(); hullFilter.SetInputConnection(AlgoOutPut); hullFilter.AddRecursiveSpherePlanes(1); hullFilter.Update(); // this.BackfaceCulling(false); Information = new cInformation(AlgoOutPut, this, hullFilter); #endregion }