//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 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); }