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 IImageRaster3D <bool> FindMedialAxes(IImageRaster3D <bool> image) { ImageRaster3D <bool> skeleton_image = ToolsImageRaster.Pad(image, false, 1, 1, 1); ITopologyElement topology = new TopologyElementRaster3D26Connectivity(skeleton_image.Raster); int[] euler_table = BuildEulerLookupTable(); bool changes = true; while (changes) { changes = false; List <int> candidates = ToolsImageRaster.GetShell3D6C(skeleton_image).GetElementIndexesWithValue(true); if (candidates.Count != 0) { // get 26 - neighbourhoods of candidates in volume List <int[]> neigbourhoods = new List <int[]>(); List <int> end_point_indexes = new List <int>(); for (int candidate_index = 0; candidate_index < candidates.Count; candidate_index++) { int[] element_neigbour_array = new int[26]; bool[] element_neigbour_true_array = new bool[26]; topology.ElementNeighboursRBA(candidates[candidate_index], element_neigbour_array); //int count = 0; for (int neigbour_index = 0; neigbour_index < topology.MaximumConnectivity; neigbour_index++) { //TODO something here } } // remove all endpoints (exactly one nb) from list neigbourhoods.RemoveAt(end_point_indexes); candidates.RemoveAt(end_point_indexes); // remove all non-Euler - invariant points from list List <int> euler_variate_indexes = new List <int>(); for (int candidate_index = 0; candidate_index < candidates.Count; candidate_index++) { if (compute_euler_characteristic(neigbourhoods[candidate_index], euler_table)) { euler_variate_indexes.Add(candidate_index); } } neigbourhoods.RemoveAt(euler_variate_indexes); candidates.RemoveAt(euler_variate_indexes); List <int> is_simple_indexes = new List <int>(); for (int candidate_index = 0; candidate_index < candidates.Count; candidate_index++) { if (is_simple(neigbourhoods[candidate_index])) { is_simple_indexes.Add(candidate_index); } } // remove all non-simple points from list candidates.RemoveAt(is_simple_indexes); //get subscript indices of remaining candidates //TODO [x, y, z] = ind2sub(padded_image_size, candidates); // if any candidates left: divide into 8 independent subvolumes TODO this is silly if (candidates.Count != 0) { // do re-checking for all points in each subvolume List <int> removal_indexes = new List <int>(); //sub2ind(padded_image_size, x(idx), y(idx), z(idx)); skeleton_image.SetElementValues(removal_indexes, false); // remove points List <int[]> nh = GetNeigbourhoods(skeleton_image, removal_indexes); List <int> di_rc = new List <int>(); for (int index = 0; index < nh.Count; index++) { if (!is_simple(nh[index])) { di_rc.Add(index); } } if (di_rc.Count != 0) { changes = true; //% at least one voxel removed skeleton_image.SetElementValues(di_rc, true); // TODO this seems weird } } } } return(skeleton_image); }