Esempio n. 1
0
        /// <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());
        }
Esempio n. 2
0
        /// <summary>
        /// Converts 3D byte array to vtkImageData.
        /// </summary>
        /// <param name="data">Input array.</param>
        /// <param name="orientation">Data orientation as a list of axes (0-2)</param>
        /// <returns>Converted array.</returns>
        public static vtkImageData byteToVTK(byte[,,] data, int[] orientation = null)
        {
            //Get input dimensions
            int[] dims = new int[] { data.GetLength(0), data.GetLength(1), data.GetLength(2) };
            //Create VTK data for putput
            vtkImageData vtkdata = vtkImageData.New();
            //Character array for conversion
            vtkUnsignedCharArray charArray = vtkUnsignedCharArray.New();
            //Pin byte array
            GCHandle pinnedArray = GCHandle.Alloc(data, GCHandleType.Pinned);

            //Set character array input
            charArray.SetArray(pinnedArray.AddrOfPinnedObject(), dims[0] * dims[1] * dims[2], 1);
            //Set vtkdata properties and connect array
            //Data from char array
            vtkdata.GetPointData().SetScalars(charArray);
            //Number of scalars/pixel
            vtkdata.SetNumberOfScalarComponents(1);
            //Data extent, 1st and last axis are swapped from the char array
            //Data is converted back to original orientation
            vtkdata.SetExtent(0, dims[2] - 1, 0, dims[1] - 1, 0, dims[0] - 1);
            //Scalar type
            vtkdata.SetScalarTypeToUnsignedChar();
            vtkdata.SetSpacing(1.0, 1.0, 1.0);
            vtkdata.Update();
            pinnedArray.Free();
            //Return vtk data
            if (orientation == null)
            {
                return(vtkdata);
            }
            else
            {
                vtkImagePermute permuter = vtkImagePermute.New();
                permuter.SetInput(vtkdata);
                permuter.SetFilteredAxes(orientation[0], orientation[1], orientation[2]);
                permuter.Update();
                return(permuter.GetOutput());
            }
        }
Esempio n. 3
0
        /// <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));
        }