Example #1
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);
        }
Example #2
0
        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);
        }