public override Tuple <IImageRaster <IRaster3DInteger, int>, IImageRaster <IRaster3DInteger, float>, IList <int []>, IList <float []> > Initialize(IRaster3DInteger raster) { IImageRaster3D <int> region_image = new ImageRaster3D <int>(raster); IImageRaster3D <float> distance_image = new ImageRaster3D <float>(raster, Single.MaxValue); Tuple <IList <int []>, IList <float []> > Centroids = InitializeCentroids(raster); IList <int[]> cluster_spatial_centroids = Centroids.Item1; IList <float[]> cluster_feature_centroids = Centroids.Item2; int neigbourhood_element_count = ((d_cluster_dimensions[0] * 2) + 1) * ((d_cluster_dimensions[1] * 2) + 1) * ((d_cluster_dimensions[2] * 2) + 1); int[] element_index_indexes = new int[neigbourhood_element_count]; for (int centroid_index = 0; centroid_index < cluster_spatial_centroids.Count; centroid_index++) { raster.GetNeigbourhoodElementIndexesRBA(cluster_spatial_centroids[centroid_index], d_cluster_dimensions, element_index_indexes); for (int element_index_index = 0; element_index_index < neigbourhood_element_count; element_index_index++) { int element_index = element_index_indexes[element_index_index]; if (element_index != -1) { int[] element_coordinates = raster.GetElementCoordinates(element_index); float distance = FunctionDistanceEuclidean.ComputeStatic(element_coordinates, cluster_spatial_centroids[centroid_index]); if (distance < distance_image.GetElementValue(element_index)) { distance_image.SetElementValue(element_index, distance); region_image.SetElementValue(element_index, centroid_index); } } } } return(new Tuple <IImageRaster <IRaster3DInteger, int>, IImageRaster <IRaster3DInteger, float>, IList <int []>, IList <float []> >(region_image, distance_image, cluster_spatial_centroids, cluster_feature_centroids)); }
public static float ComputeGradientMasked(ImageRaster3D <float> image, ImageRaster3D <bool> mask, int index_0, int index_1, int index_2, int offset_0, int offset_1, int offset_2, float[] voxel_size) { if (mask.Raster.ContainsCoordinates(index_0 + offset_0, index_1 + offset_1, index_2 + offset_2) && mask.GetElementValue(index_0 + offset_0, index_1 + offset_1, index_2 + offset_2)) { if (mask.Raster.ContainsCoordinates(index_0 - offset_0, index_1 - offset_1, index_2 - offset_2) && mask.GetElementValue(index_0 - offset_0, index_1 - offset_1, index_2 - offset_2)) { return((0.5f * image.GetElementValue(index_0 + offset_0, index_1 + offset_1, index_2 + offset_2) - 0.5f * image.GetElementValue(index_0 - offset_0, index_1 - offset_1, index_2 - offset_2)) * voxel_size[0]); } else { return((image.GetElementValue(index_0 + offset_0, index_1 + offset_1, index_2 + offset_2) - image.GetElementValue(index_0, index_1, index_2)) * voxel_size[0]); } } else { if (mask.Raster.ContainsCoordinates(index_0 - offset_0, index_1 - offset_1, index_2 - offset_2) && mask.GetElementValue(index_0 - offset_0, index_1 - offset_1, index_2 - offset_2)) { return((image.GetElementValue(index_0, index_1, index_2) - image.GetElementValue(index_0 - offset_0, index_1 - offset_1, index_2 - offset_2)) * voxel_size[0]); } else { return(0); } } }
public void TestMorphologicalErosionRBA() { ImageRaster3D <float> source = new ImageRaster3D <float>(5, 5, 5); ImageRaster3D <float> target = new ImageRaster3D <float>(5, 5, 5); source.SetElementValue(2, 2, 2, 1); List <int[]> offsets = new List <int[]>(); offsets.Add(new int[] { 0, 0, 0 }); StructuringElement3D structure_0 = new StructuringElement3D(offsets); ToolsImageRaster.MorphologicalErosionRBA(source, structure_0, 0, target); Assert.AreEqual(1, target.GetElementIndexesWithValue(1).Count); offsets.Add(new int[] { 1, 0, 0 }); offsets.Add(new int[] { -1, 0, 0 }); offsets.Add(new int[] { 0, 1, 0 }); offsets.Add(new int[] { 0, -1, 0 }); offsets.Add(new int[] { 0, 0, 1 }); offsets.Add(new int[] { 0, 0, -1 }); StructuringElement3D structure_1 = new StructuringElement3D(offsets); ToolsImageRaster.MorphologicalErosionRBA(source, structure_1, 0, target); Assert.AreEqual(0, target.GetElementIndexesWithValue(1).Count); source.SetElementValue(1, 2, 2, 1); source.SetElementValue(3, 2, 2, 1); source.SetElementValue(2, 1, 2, 1); source.SetElementValue(2, 3, 2, 1); source.SetElementValue(2, 2, 1, 1); source.SetElementValue(2, 2, 3, 1); ToolsImageRaster.MorphologicalErosionRBA(source, structure_1, 0, target); Assert.AreEqual(1, target.GetElementIndexesWithValue(1).Count); }
public static void DilateRBA( ImageRaster3D <bool> source, ImageRaster3D <bool> structuring_element, int pivot_index_0, int pivot_index_1, int pivot_index_2, ImageRaster3D <bool> target) { List <int> shell_source = GetShell3D6C(source).GetElementIndexesWithValue(true); List <int[]> structure_element_offsets = new List <int[]>(); List <int[]> structure_element_offsets_shell = new List <int[]>(); // TODO compute the offsets in source space Parallel.For(0, source.ElementCount, element_index => { target[element_index] = source[element_index]; }); // First should be done in full // For the rest only the border is relevant Parallel.For(1, shell_source.Count, index_index => { throw new NotImplementedException(); }); }
/************************************************************************** * * Functions for calculating a fast 3D distance transform from binary data. * The function returns squared Euclidean distances. It supports * anisotropic voxels. * * This code is based on the chapter 'Separable Distance Transformation * and Its Applications' by Coeurjolly and Vacavant, in: Digital Geometry * Algorithms, Lecture Notes in Computational Vision and Biomechanics, Vol 2, * pp 189-214. DOI: 10.1007/978-94-007-4174-4_7 * * Copyright by Edwin Bennink, UMC Utrecht * [email protected] * September 2015 * * Addapted for c# by Jaap Oosterbroek, UMC Utrecht * [email protected] * December 2015 * *************************************************************************/ //public static ImageRaster3D<float> DistanceTransform(ImageRaster3D<bool> mask_image, float[] voxel_size) //{ // ImageRaster3D<float> distance_image = new ImageRaster3D<float>(mask_image.Raster); // DistanceTransformRBA(mask_image, voxel_size, distance_image); // return distance_image; //} public static ImageRaster3D <float> DistanceTransform3D(ImageRaster3D <bool> mask_image, float[] voxel_size) { ImageRaster3D <float> distance_image = new ImageRaster3D <float>(mask_image.Raster); DistanceTransform3DOosterbroekRBA(mask_image, voxel_size, distance_image); return(distance_image); }
public static void DistanceTransform2DOosterbroekRBA(ImageRaster2D <bool> mask_image, float[] voxel_size, ImageRaster2D <float> distance_image) { ImageRaster3D <bool> mask_image_3d = new ImageRaster3D <bool>(mask_image.Raster.Size0, mask_image.Raster.Size1, 1, mask_image.GetElementValues(false), false); ImageRaster3D <float> distance_image_3d = new ImageRaster3D <float>(mask_image.Raster.Size0, mask_image.Raster.Size1, 1, distance_image.GetElementValues(false), false); DistanceTransform3DOosterbroekRBA(mask_image_3d, voxel_size, distance_image_3d); }
private static int ComputeCurves(ImageRaster3D <float> distance_image_sqr, int index_0, int index_1, int index_2, int index_axis, float[] locations_axis, float[] curve_start, float[] locations, float[] offsets, int index) { float location = locations_axis[index_axis]; float offset = distance_image_sqr.GetElementValue(index_0, index_1, index_2); if (offset < float.PositiveInfinity) { index++; while ((index != 0) && (Collide(offsets[index - 1], offset, locations[index - 1], location) <= curve_start[index - 1])) { index--; } locations[index] = location; offsets[index] = offset; if (index == 0) { curve_start[index] = locations_axis[0]; } else { curve_start[index] = Collide(offsets[index - 1], offset, locations[index - 1], location); } } return(index); }
public static void MorphologicalDilationRBA <RangeType>(ImageRaster3D <RangeType> source, StructuringElement3D structure, RangeType default_value, ImageRaster3D <RangeType> target) where RangeType : IComparable <RangeType> { if (!source.Raster.Equals(target.Raster)) { throw new Exception("Raster Mismatch"); } IRaster3DInteger raster = source.Raster; //Parallel.For(0, source.ElementCount, source_element_index => for (int source_element_index = 0; source_element_index < source.ElementCount; source_element_index++) { int[] coordinates = raster.GetElementCoordinates(source_element_index); RangeType value = default_value; bool found = false; for (int offset_index = 0; offset_index < structure.FlippedOffsets.Count; offset_index++) { int[] offset = structure.FlippedOffsets[offset_index]; if (raster.ContainsCoordinates(coordinates[0] + offset[0], coordinates[1] + offset[1], coordinates[2] + offset[2])) { if (found) { value = ToolsMath.Max(value, source.GetElementValue(coordinates[0] + offset[0], coordinates[1] + offset[1], coordinates[2] + offset[2])); } else { value = source.GetElementValue(coordinates[0] + offset[0], coordinates[1] + offset[1], coordinates[2] + offset[2]); found = true; } } } target.SetElementValue(source_element_index, value); }//); }
public static void InvertIP(ImageRaster3D <bool> source) { Parallel.For(0, source.ElementCount, index => { source[index] = !source[index]; }); }
public IImageRaster3D <float> Filter(IImageRaster3D <float> source_normal) { IImageRaster3D <float> source_inverted = new ImageRaster3D <float>(source_normal); return(null); }
//internal static List<int> GetShell6List(ImageRaster3D<bool> image) //{ // ITopologyElement topology = new TopologyElementRaster3D6Connectivity(image.Raster); // int[] element_neigbour_array = new int[topology.MaximumConnectivity]; // List<int> shell_list = new List<int>(); // for (int element_index = 0; element_index < image.Raster.ElementCount; element_index++) // { // if (image.GetElementValue(element_index)) // { // bool is_shell = false; // topology.ElementNeighboursRBA(element_index, element_neigbour_array); // foreach (int other_element_index in element_neigbour_array) // { // if (other_element_index != -1) // { // if (!image.GetElementValue(other_element_index)) // { // is_shell = true; // } // } // } // if (is_shell) // { // shell_list.Add(element_index); // } // } // } // return shell_list; //} public static ImageRaster3D <bool> GetShell3D26C(ImageRaster3D <bool> source, bool border_is_shell = false) { ITopologyElement topology = new TopologyElementRaster3D26Connectivity(source.Raster); ImageRaster3D <bool> target = new ImageRaster3D <bool>(source.Raster); GetShellRBA(source, topology, target, border_is_shell); return(target); }
public void TestDefaultBuilderTrivial4(IMaxTreeBuilder <int> builder) { int[] data = new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; IImageRaster3D <int> image = new ImageRaster3D <int>(3, 3, 1, data, false); ITopologyElement topology = new TopologyElementRaster3D6Connectivity(image.Raster); IMaxTree <int> maxtree = builder.BuildMaxTree(data, new ComparerNatural <int>(), topology, data.Length); maxtree.GetDisplayValues(); }
public static ImageRaster3D <RangeType> MorphologicalOpening <RangeType>(ImageRaster3D <RangeType> source, StructuringElement3D structure, RangeType default_value) where RangeType : IComparable <RangeType> { ImageRaster3D <RangeType> temp = new ImageRaster3D <RangeType>(source.Raster); ImageRaster3D <RangeType> target = new ImageRaster3D <RangeType>(source.Raster); MorphologicalOpeningRBA(source, structure, default_value, temp, target); return(target); }
public static ImageRaster3D <bool> Invert(ImageRaster3D <bool> source) { bool [] values_source = source.GetElementValues(false); bool [] values_inverted = new bool[values_source.Length]; Parallel.For(0, values_source.Length, index => { values_inverted[index] = !values_source[index]; }); return(new ImageRaster3D <bool>(source.Raster, values_inverted, true)); }
public static ImageRaster3D <bool> Union(ImageRaster3D <bool> source_0, ImageRaster3D <bool> source_1) { ImageRaster3D <bool> target = new ImageRaster3D <bool>(source_0.Raster); Parallel.For(0, source_0.ElementCount, index => { target[index] = source_0[index] || source_1[index]; }); return(target); }
public void TestTrivial0(IAlphaPartitionTreeBuilder <float, float> builder) { ImageRaster3D <float> image = new ImageRaster3D <float>(); ITopologyElementEdge element_topology = new TopologyElementRaster3D6Connectivity(image.Raster).GetElementEdgeRasterTopology(); IFunctionDissimilarity <float, float> edge_function = new FunctionDistanceAbsoluteDifference(); IAlphaPartitionTree <float> tree = builder.BuildAlphaPartitionTree(element_topology, edge_function, image.GetElementValues(false)); Assert.AreEqual(1, tree.GetRealElementsIndexesWithMaxAlfa(0, 0).Length); Assert.AreEqual(1, tree.GetFullElementsIndexesWithMaxAlfa(0, 0).Length); }
public static ImageRaster3D <bool> Intersect(ImageRaster3D <bool> image_0, ImageRaster3D <bool> image_1) { ImageRaster3D <bool> result = new ImageRaster3D <bool>(image_0.Raster); Parallel.For(0, image_0.Raster.ElementCount, element_index => { result.SetElementValue(element_index, image_0.GetElementValue(element_index) && image_1.GetElementValue(element_index)); }); return(result); }
public static Tuple <ImageRaster3D <float>, ImageRaster3D <float>, ImageRaster3D <float> > ComputeGradientMasked(ImageRaster3D <float> image, ImageRaster3D <bool> mask, float[] voxel_size) { IRaster3DInteger raster = image.Raster; List <int> mask_indexes = mask.GetElementIndexesWithValue(true); //DO gradient 0 ImageRaster3D <float> image_gradient_0 = new ImageRaster3D <float>(raster); Parallel.For(0, mask_indexes.Count, index_index => { int element_index = mask_indexes[index_index]; int index_0 = element_index % raster.Size0; int index_1 = (element_index % (raster.Size0 * raster.Size1)) / raster.Size0; int index_2 = element_index / (raster.Size0 * raster.Size1); int offset_0 = 1; int offset_1 = 0; int offset_2 = 0; float gradient = ComputeGradientMasked(image, mask, index_0, index_1, index_2, offset_0, offset_1, offset_2, voxel_size); image_gradient_0.SetElementValue(element_index, gradient); }); //DO gradient 1 ImageRaster3D <float> image_gradient_1 = new ImageRaster3D <float>(raster); Parallel.For(0, mask_indexes.Count, index_index => { int element_index = mask_indexes[index_index]; int index_0 = element_index % raster.Size0; int index_1 = (element_index % (raster.Size0 * raster.Size1)) / raster.Size0; int index_2 = element_index / (raster.Size0 * raster.Size1); int offset_0 = 0; int offset_1 = 1; int offset_2 = 0; float gradient = ComputeGradientMasked(image, mask, index_0, index_1, index_2, offset_0, offset_1, offset_2, voxel_size); image_gradient_1.SetElementValue(element_index, gradient); }); //DO gradient 2 ImageRaster3D <float> image_gradient_2 = new ImageRaster3D <float>(raster); Parallel.For(0, mask_indexes.Count, index_index => { int element_index = mask_indexes[index_index]; int index_0 = element_index % raster.Size0; int index_1 = (element_index % (raster.Size0 * raster.Size1)) / raster.Size0; int index_2 = element_index / (raster.Size0 * raster.Size1); int offset_0 = 0; int offset_1 = 0; int offset_2 = 1; float gradient = ComputeGradientMasked(image, mask, index_0, index_1, index_2, offset_0, offset_1, offset_2, voxel_size); image_gradient_2.SetElementValue(element_index, gradient); }); return(new Tuple <ImageRaster3D <float>, ImageRaster3D <float>, ImageRaster3D <float> >(image_gradient_0, image_gradient_1, image_gradient_2)); }
public static ImageRaster3D <bool> CreateTestMask3D0() { ImageRaster3D <bool> mask = new ImageRaster3D <bool>(5, 5, 5); mask.SetElementValue(0, 0, 0, true); mask.SetElementValue(1, 1, 0, true); mask.SetElementValue(2, 2, 0, true); mask.SetElementValue(3, 2, 0, true); mask.SetElementValue(4, 3, 0, true); return(mask); }
private static int ComputeDistance(ImageRaster3D <float> distance_image_sqr, int index_0, int index_1, int index_2, int index_axis, float[] locations_axis, float[] start, float[] locations, float[] offsets, int curve_index) { float location = locations_axis[index_axis]; while ((curve_index != 0) && (location < start[curve_index])) { curve_index--; } distance_image_sqr.SetElementValue(index_0, index_1, index_2, offsets[curve_index] + ToolsMath.Sqr(location - locations[curve_index])); return(curve_index); }
public void TestDefaultBuilderVeryBig(IMaxTreeBuilder <int> builder) { Random random = new Random(0); int[] data = new int[512 * 512 * 10]; for (int index = 1; index < data.Length; index++) { data[index] = (int)(random.NextDouble() * 100.0); } IImageRaster3D <int> image = new ImageRaster3D <int>(512, 512, 10, data, false); ITopologyElement topology = new TopologyElementRaster3D6Connectivity(image.Raster); IMaxTree <int> maxtree = builder.BuildMaxTree(data, new ComparerNatural <int>(), topology, data.Length); }
public void TestTrivial1(IAlphaPartitionTreeBuilder <float, float> builder) { ImageRaster3D <float> image = new ImageRaster3D <float>(10, 10, 10); ITopologyElementEdge element_topology = new TopologyElementRaster3D6Connectivity(image.Raster).GetElementEdgeRasterTopology(); IFunctionDissimilarity <float, float> edge_function = new FunctionDistanceAbsoluteDifference(); IAlphaPartitionTree <float> tree = builder.BuildAlphaPartitionTree(element_topology, edge_function, image.GetElementValues(false)); Assert.AreEqual(1000, tree.GetRealElementsIndexesWithMaxAlfa(0, 0).Length); Assert.AreEqual(3700, tree.GetFullElementsIndexesWithMaxAlfa(0, 0).Length); ToolsIOSerialization.SerializeToFile(@"E:\Data\Dropbox\Dropbox\TestData\Tree.blb", tree); }
public static ImageRaster3D <bool> MorphologicalErosion(ImageRaster3D <bool> mask, float[] voxel_size, float erosion_size) { ImageRaster3D <float> distance = ToolsDistance.DistanceTransform3D(mask, voxel_size); ImageRaster3D <bool> eroded = new ImageRaster3D <bool>(mask.Raster); Parallel.For(0, eroded.ElementCount, index => { if (distance[index] < erosion_size) { eroded[index] = true; } }); return(eroded); }
public void TestDistance3DOosterbroek0() { ImageRaster3D <bool> mask = CreateTestMask3D0(); ImageRaster3D <float> distance_true = new ImageRaster3D <float>(mask.Raster); ImageRaster3D <float> distance_test = new ImageRaster3D <float>(mask.Raster); float[] voxel_size = new float[] { 1, 1, 1 }; ToolsDistance.DistanceTransform3DMediumRBA(mask, voxel_size, distance_true); ToolsDistance.DistanceTransform3DOosterbroekRBA(mask, voxel_size, distance_test); for (int index = 0; index < distance_test.ElementCount; index++) { Assert.AreEqual(distance_true[index], distance_test[index]); } }
public static ImageRaster3D <bool> CreateTestMask3D1() { ImageRaster3D <bool> mask = new ImageRaster3D <bool>(75, 75, 75); mask.SetElementValue(50, 50, 50, true); mask.SetElementValue(51, 51, 50, true); mask.SetElementValue(52, 52, 50, true); mask.SetElementValue(53, 52, 50, true); mask.SetElementValue(54, 53, 50, true); mask.SetElementValue(57, 57, 54, true); mask.SetElementValue(58, 58, 56, true); mask.SetElementValue(50, 60, 50, true); return(mask); }
public void TestDistance1D() { ImageRaster3D <bool> mask = new ImageRaster3D <bool>(5, 1, 1); mask[0] = true; mask[3] = true; ImageRaster3D <float> distance = ToolsDistance.DistanceTransform3D(mask, new float[] { 1.5f, 1.5f, 1.5f }); Assert.AreEqual(0.0f, distance[0]); Assert.AreEqual(1.5f, distance[1]); Assert.AreEqual(1.5f, distance[2]); Assert.AreEqual(0.0f, distance[3]); Assert.AreEqual(1.5f, distance[4]); }
//TODO speed up public static void MorphologicalOpeningRBA <RangeType>(ImageRaster3D <RangeType> source, StructuringElement3D structure, RangeType default_value, ImageRaster3D <RangeType> temp, ImageRaster3D <RangeType> target) where RangeType : IComparable <RangeType> { if ((!source.Raster.Equals(temp.Raster)) || (!source.Raster.Equals(target.Raster))) { throw new Exception("Raster Mismatch"); } IRaster3DInteger raster = source.Raster; //Do erosion MorphologicalErosionRBA(source, structure, default_value, temp); //Do dilation MorphologicalDilationRBA(temp, structure, default_value, target); }
public void TestDistance3DMedium() { ImageRaster3D <bool> mask = CreateTestMask3D0(); ImageRaster3D <float> distance = new ImageRaster3D <float>(mask.Raster); ToolsDistance.DistanceTransform3DMediumRBA(mask, new float[] { 1.0f, 1.0f, 1.0f }, distance); Assert.AreEqual(0.0f, distance[0]); Assert.AreEqual(1.0f, distance[1]); Assert.AreEqual(ToolsMath.Sqrt(2.0f), distance[2]); Assert.AreEqual(2.0f, distance[3]); Assert.AreEqual(ToolsMath.Sqrt(5.0f), distance[4]); Assert.AreEqual(ToolsMath.Sqrt(8.0f), distance[20]); Assert.AreEqual(ToolsMath.Sqrt(24.0f), distance[120]); Assert.AreEqual(ToolsMath.Sqrt(17.0f), distance[124]); }
public void TestDistance3DOosterbroek1() { ImageRaster3D <bool> mask = CreateTestMask3D1(); ImageRaster3D <float> distance_true = new ImageRaster3D <float>(mask.Raster); ImageRaster3D <float> distance_test = new ImageRaster3D <float>(mask.Raster); float[] voxel_size = new float[] { 0.31f, 0.31f, 1.25f }; ToolsDistance.DistanceTransform3DMediumRBA(mask, voxel_size, distance_true); ToolsDistance.DistanceTransform3DOosterbroekRBA(mask, voxel_size, distance_test); float Tol = 0.1f; for (int index = 0; index < distance_test.ElementCount; index++) { Assert.IsTrue(Math.Abs(distance_true[index] - distance_test[index]) < Tol); } }
public void TestTrival0() { IMaxTreeBuilder <float> builder_max = new MaxTreeBuilderSingleQueue <float>(); IAlphaPartitionTreeBuilder <float, float> builder_alfa_partition = new AlphaPartitionTreeBuilderMinTree <float, float>(new AlgebraRealFloat32(), builder_max); ImageRaster3D <float> image = new ImageRaster3D <float>(); ITopologyElementEdge element_topology = new TopologyElementRaster3D6Connectivity(image.Raster).GetElementEdgeRasterTopology(); IFunctionDissimilarity <float, float> edge_function = new FunctionDistanceAbsoluteDifference(); IAlphaPartitionTree <float> tree = builder_alfa_partition.BuildAlphaPartitionTree(element_topology, edge_function, image.GetElementValues(false)); float [] values_input = new float [] { 555 }; FilterAlfaPartitionMean <float> filter = new FilterAlfaPartitionMean <float>(new AlgebraRealFloat32()); float[] values_filtered = filter.Filter(tree, values_input, 0, 0); Assert.AreEqual(555, values_filtered[0]); }