/// <summary> /// Extract data as vtkImageData /// </summary> /// <returns>Converted data as vtkImageData variable.</returns> public vtkImageData GetData() { //Conver byte data to vtkImageData vtkdata = DataTypes.byteToVTK(data); return(vtkdata); }
public static vtkImageData OCVFPSuppression(vtkImageData BCI, vtkImageData sample, int axis = 0, double BC_threshold = 0.7 * 255.0, double sample_threshold = 80) { //Get dimensions int[] dims = BCI.GetExtent(); //Get byte data from input samples byte[] BCIByte = DataTypes.vtkToByte(BCI); byte[] SampleByte = DataTypes.vtkToByte(sample); //Output byte array byte[,,] OutByte = new byte[(dims[1] - dims[0] + 1), (dims[3] - dims[2] + 1), (dims[5] - dims[4] + 1)]; //Loop parameters int start = 0; int stop = 0; int h = 0; int w = 0; int strideh = 0; int stridew = 0; int pos = 0; if (axis == 0) { start = dims[0]; stop = dims[1] + 1; h = dims[5] + 1; w = dims[3] + 1; strideh = (dims[1] + 1) * (dims[3] + 1); stridew = 1; } if (axis == 1) { start = dims[2]; stop = dims[3] + 1; h = dims[5] + 1; w = dims[1] + 1; strideh = (dims[1] + 1) * (dims[3] + 1); stridew = (dims[3] + 1); } if (axis == 2) { start = dims[4]; stop = dims[5] + 1; h = dims[1] + 1; w = dims[3] + 1; strideh = dims[3] + 1; stridew = 1; } //Iterate over samples in parallel Parallel.For(start, stop, (int k) => { //Get slices to OpenCV matrices Mat BCMat = new Mat(h, w, MatType.CV_8UC1); var BCIndexer = BCMat.GetGenericIndexer <Vec2b>(); Mat SampleMat = new Mat(h, w, MatType.CV_8UC1); var SampleIndexer = SampleMat.GetGenericIndexer <Vec2b>(); //Iterate over indices Parallel.For(0, h, (int kh) => { Parallel.For(0, w, (int kw) => { //Current slice index if (axis == 0) { pos = k * (dims[1] + 1); } ; if (axis == 1) { pos = k; } ; if (axis == 2) { pos = k * (dims[1] + 1) * (dims[3] + 1); } ; //Current index int cur = pos + kh * strideh + kw * stridew; //Get values Vec2b bcval = BCIndexer[kh, kw]; bcval.Item0 = BCIByte[cur]; bcval.Item1 = BCIByte[cur]; Vec2b sampleval = SampleIndexer[kh, kw]; sampleval.Item0 = SampleByte[cur]; sampleval.Item1 = SampleByte[cur]; //Update matrices BCIndexer[kh, kw] = bcval; SampleIndexer[kh, kw] = sampleval; }); }); if (k == 500) { using (var window = new Window("BCMat", image: BCMat, flags: WindowMode.AutoSize)) { Cv2.WaitKey(); } using (var window = new Window("Sample", image: SampleMat, flags: WindowMode.AutoSize)) { Cv2.WaitKey(); } } //Get binary masks Mat BCBW = BCMat.Threshold(BC_threshold, 255.0, ThresholdTypes.Binary); Mat SampleBW = SampleMat.Threshold(sample_threshold, 255.0, ThresholdTypes.Binary); if (k == 500) { using (var window = new Window("BCMat", image: BCBW, flags: WindowMode.AutoSize)) { Cv2.WaitKey(); } using (var window = new Window("Sample", image: SampleBW, flags: WindowMode.AutoSize)) { Cv2.WaitKey(); } } //Subtract BCI mask from sample mask Mat D = SampleBW - BCBW; if (k == 500) { using (var window = new Window("D", image: D, flags: WindowMode.AutoSize)) { Cv2.WaitKey(); } } //Closing //Generate structuring element InputArray element = InputArray.Create(new Mat(1, 50, MatType.CV_8UC1)); D = D.Dilate(element); D = D.Erode(element); if (k == 500) { using (var window = new Window("D", image: D, flags: WindowMode.AutoSize)) { Cv2.WaitKey(); } } //Subtract closed mask from BCI mask BCBW = BCBW - D; if (k == 500) { using (var window = new Window("Cleaned BC", image: BCBW, flags: WindowMode.AutoSize)) { Cv2.WaitKey(); } } //Dilate BCBW = BCBW.Dilate(element); if (k == 500) { using (var window = new Window("Dilated BC", image: BCBW, flags: WindowMode.AutoSize)) { Cv2.WaitKey(); } } //Multiply BCI matrix with the mask BCMat = BCMat.Mul(BCBW); BCIndexer = BCMat.GetGenericIndexer <Vec2b>(); if (k == 500) { using (var window = new Window("Dilated BC", image: BCBW, flags: WindowMode.AutoSize)) { Cv2.WaitKey(); } } //Return the elements to output byte array Parallel.For(0, h, (int kh) => { Parallel.For(0, w, (int kw) => { //Get value Vec2b bcval = BCIndexer[kh, kw]; //Update outputarray if (axis == 0 && bcval.Item0 > BC_threshold) { OutByte[kh, k, kw] = 255; } ; if (axis == 1 && bcval.Item0 > BC_threshold) { OutByte[kh, kw, k] = 255; } ; if (axis == 2 && bcval.Item0 > BC_threshold) { OutByte[k, kh, kw] = 255; } ; }); }); }); //Convert outputarray to VTK data return(DataTypes.byteToVTK(OutByte)); }
public static vtkImageData SWFPSuppression(vtkImageData BCI, int[] extent, double threshold = 0.7 * 255.0, int min = 0, int max = 650, int step = 4, int ws = 50, double wt = 20.0, double minones = 192.0) { //Get dimensions int[] dims = BCI.GetExtent(); int h = dims[1] - dims[0] + 1; int w = dims[3] - dims[2] + 1; int d = dims[5] - dims[4] + 1; //Make array of extents List <int[]> regions = new List <int[]>(); for (int k1 = 0; k1 < 4; k1++) { for (int k2 = 0; k2 < 4; k2++) { int step1 = (extent[1] - extent[0] + 1) / 8; int step2 = (extent[3] - extent[2] + 1) / 8; int[] _tmp = new int[] { extent[0] + k1 * step1, extent[0] + (k1 + 1) * step1, extent[2] + k2 * step2, extent[2] + (k2 + 1) * step2 }; regions.Add(_tmp); Console.WriteLine("Region:"); Console.WriteLine("{0},{1},{2},{3}", _tmp[0], _tmp[1], _tmp[2], _tmp[3]); } } //Get byte data from input samples byte[] BCIByte = DataTypes.vtkToByte(BCI); List <byte[]> sums = new List <byte[]>(); //Itereate over pixels foreach (int[] region in regions) { byte[] tmp = new byte[max - min]; for (int k = min; k < max; k += step) { int w1 = k; int w2 = w1 + ws; int roisum = 0; Parallel.For(w1, w2, (int kz) => { Parallel.For(region[0], region[1], (int ky) => { Parallel.For(region[2], region[3], (int kx) => { int pos = kz * (h * w) + ky * w + kx; if ((double)BCIByte[pos] > threshold) { roisum += (int)BCIByte[pos]; } }); }); }); //Set sliding window index at k to 1 if enough non-zero pixels were found if (((double)roisum / (minones * minones)) > wt) { tmp[k] = 1; } //Check if there's a drop between consecutive results if (k > min + step && tmp[k] == 0 && tmp[k - step] == 1) { sums.Add(tmp); break; } //Otherswise append the data at the end else { if (k + step >= max) { sums.Add(tmp); } } } } int[] idx = new int[sums.Count]; //Scan sums vector find last non-zero index int c = 0; foreach (byte[] sum in sums) { for (int k = sum.Length - 1; k >= 0; k -= 1) { if (sum[k] == 1) { idx[c] = k; c++; break; } } } byte[,,] output = new byte[d, h, w]; //Set array indices below idx to outputvalues c = 0; foreach (int[] region in regions) { int _idx = idx[c]; Console.WriteLine("Max idx: {0} | Height: {1}", _idx, d); int z = 0; if (_idx == 0) { z = d; } else { z = Math.Min(_idx + 20, d); } Parallel.For(0, z, (int kz) => { Parallel.For(region[0], region[1], (int ky) => { Parallel.For(region[2], region[3], (int kx) => { int pos = kz * (h * w) + ky * (w) + kx; output[kz, ky, kx] = BCIByte[pos]; }); }); }); c++; } return(DataTypes.byteToVTK(output)); }
/// <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)); }