예제 #1
0
 public ImageRaster3D <RangeType> GetSubImage(
     int x_offset, int x_size,
     int y_offset, int y_size,
     int z_offset, int z_size,
     bool copy_values)
 {
     //TODO check if it even fits
     if (copy_values)
     {
         IRaster3DInteger          raster    = new Raster3DInteger(x_size, y_size, z_size);
         ImageRaster3D <RangeType> sub_image = new ImageRaster3D <RangeType>(raster);
         for (int z_index = 0; z_index < z_size; z_index++)
         {
             for (int y_index = 0; y_index < y_size; y_index++)
             {
                 for (int x_index = 0; x_index < x_size; x_index++)
                 {
                     RangeType value = GetElementValue(x_index + x_offset, y_index + y_offset, z_index + z_offset);
                     sub_image.SetElementValue(x_index, y_index, z_index, value);
                 }
             }
         }
         return(sub_image);
     }
     else
     {
         //TODO this is buggy as f**k
         IRaster3DInteger raster = this.Raster.GetSubRaster(
             x_offset, x_size,
             y_offset, y_size,
             z_offset, z_size);
         return(new ImageRaster3D <RangeType>(raster, GetElementValues(false), false));
     }
 }
예제 #2
0
 public ImageRaster3D(
     IRaster3DInteger raster,
     RangeType[] image,
     bool copy_array)
     : base(raster, image, copy_array)
 {
 }
예제 #3
0
        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);
            }//);
        }
예제 #4
0
 public Raster3DIntegerSub(IRaster3DInteger parent, int offset_x, int size_x, int offset_y, int size_y, int offset_z, int size_z)
     : base(new int[] { size_x, size_y, size_z })
 {
     this.parent   = parent;
     this.offset_x = offset_x;
     this.offset_y = offset_y;
     this.offset_z = offset_z;
 }
예제 #5
0
        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));
        }
예제 #6
0
 public MaxTreeFloat3DFeaturesDouble(IImageRaster <IRaster3DInteger, float> image, FeatureGeneratorElementNode3DDouble generator, IProgressReporter reporter)
 {
     this.raster         = image.Raster;
     this.inner_max_tree = new MaxTreeBuilderSingleQueue <float>().BuildMaxTree(image.GetElementValues(false), new ComparerNatural <float>(), new TopologyElementRaster3D6Connectivity(image.Raster), image.Raster.ElementCount);
     if (generator != null)
     {
         this.features = new double[inner_max_tree.NodeCount, generator.FeatureCount];
         generator.GenerateFeaturesTree(raster, inner_max_tree.BottomLevelNode, features);
     }
     else
     {
         this.features = null;
     }
 }
예제 #7
0
        //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);
        }
예제 #8
0
        public Bitmap Render(IImageRaster <IRaster3DInteger, ElementType> source_image)
        {
            IRaster3DInteger raster            = source_image.Raster;
            Bitmap           destination_image = new Bitmap(raster.Size0, raster.Size1);

            for (int index_y = 0; index_y < raster.Size1; index_y++)
            {
                for (int index_x = 0; index_x < raster.Size0; index_x++)
                {
                    ElementType value = source_image.GetElementValue(raster.GetElementIndex(index_x, index_y, index_z));
                    destination_image.SetPixel(index_x, index_y, this.converter.Compute(value));
                }
            }
            return(destination_image);
        }
        public IImageRaster <IRaster2DInteger, bool> Render(Tuple <List <int>, IRaster3DInteger> render_source)
        {
            List <int>       elements_true = render_source.Item1;
            IRaster3DInteger source_raster = render_source.Item2;

            float[,] coordinates_image   = new float[elements_true.Count, 3];
            float[,] elements_projection = new float[elements_true.Count, 3];
            int [] coordinates = new int [3];

            for (int element_index_index = 0; element_index_index < elements_true.Count; element_index_index++)
            {
                source_raster.GetElementCoordinatesRBA(elements_true[element_index_index], coordinates);
                coordinates_image[element_index_index, 0] = coordinates[0];
                coordinates_image[element_index_index, 1] = coordinates[1];
                coordinates_image[element_index_index, 2] = coordinates[2];
            }

            for (int element_index = 0; element_index < elements_true.Count; element_index++)
            {
                elements_projection[element_index, 0] = ((coordinates_image[element_index, 0] - image_focus[0]) * projection_vector_x[0]) +
                                                        ((coordinates_image[element_index, 1] - image_focus[1]) * projection_vector_x[1]) +
                                                        ((coordinates_image[element_index, 2] - image_focus[2]) * projection_vector_x[2]);

                elements_projection[element_index, 1] = ((coordinates_image[element_index, 0] - image_focus[0]) * projection_vector_y[0]) +
                                                        ((coordinates_image[element_index, 1] - image_focus[1]) * projection_vector_y[1]) +
                                                        ((coordinates_image[element_index, 2] - image_focus[2]) * projection_vector_y[2]);

                elements_projection[element_index, 2] = ((coordinates_image[element_index, 0] - image_focus[0]) * projection_vector_z[0]) +
                                                        ((coordinates_image[element_index, 1] - image_focus[1]) * projection_vector_z[1]) +
                                                        ((coordinates_image[element_index, 2] - image_focus[2]) * projection_vector_z[2]);
            }

            Raster2DInteger      bitmap_raster     = new Raster2DInteger(bitmap_size_x, bitmap_size_y);
            ImageRaster2D <bool> destination_image = new ImageRaster2D <bool>(bitmap_size_x, bitmap_size_y);

            for (int element_index = 0; element_index < elements_true.Count; element_index++)
            {
                int x_target = (int)elements_projection[element_index, 0] + (bitmap_raster.Size0 / 2);
                int y_target = (int)elements_projection[element_index, 1] + (bitmap_raster.Size1 / 2);

                if (bitmap_raster.ContainsCoordinates(x_target, y_target))
                {
                    destination_image.SetElementValue(x_target, y_target, true);
                }
            }
            return(destination_image);
        }
예제 #10
0
        public static StructuringElement3D CreateElement3DDisk(IRaster3DInteger raster, double[] voxel_size, double disk_radius)
        {
            int disk_radius_0_voxels = 1 + (2 * ((int)(disk_radius / voxel_size[0])));
            int disk_radius_1_voxels = 1 + (2 * ((int)(disk_radius / voxel_size[1])));


            List <int[]> element_offsets = new List <int[]>();

            for (int offset_0 = -disk_radius_0_voxels; offset_0 <= disk_radius_0_voxels; offset_0++)
            {
                for (int offset_1 = -disk_radius_1_voxels; offset_1 <= disk_radius_1_voxels; offset_1++)
                {
                    element_offsets.Add(new int[] { offset_0, offset_1, 0 });
                }
            }
            return(new StructuringElement3D(element_offsets));
        }
예제 #11
0
        public Bitmap Render(IImageRaster <IRaster3DInteger, ElementType> source_image)
        {
            IRaster3DInteger raster            = source_image.Raster;
            Bitmap           destination_image = new Bitmap(raster.Size0, raster.Size1);

            for (int index_y = 0; index_y < raster.Size1; index_y++)
            {
                for (int index_x = 0; index_x < raster.Size0; index_x++)
                {
                    ElementType mean_value = source_image.GetElementValue(raster.GetElementIndex(index_x, index_y, 0));
                    for (int index_z = 1; index_z < raster.Size2; index_z++)
                    {
                        mean_value = this.algebra.Add(mean_value, source_image.GetElementValue(raster.GetElementIndex(index_x, index_y, index_z)));
                    }
                    mean_value = algebra.Divide(mean_value, this.algebra.ToDomain(raster.Size2));
                    destination_image.SetPixel(index_x, index_y, this.converter.Compute(mean_value));
                }
            }
            return(destination_image);
        }
        public void GenerateFeaturesTree(IRaster3DInteger raster, IMaxTreeNode <float> bottom_level_node, float[,] features)
        {
            //Generate from the leafs downwards
            Queue <IMaxTreeNode <float> > queue      = new Queue <IMaxTreeNode <float> >();
            Stack <IMaxTreeNode <float> > node_stack = new Stack <IMaxTreeNode <float> >();

            queue.Enqueue(bottom_level_node);
            while (queue.Count != 0)
            {
                IMaxTreeNode <float> node = queue.Dequeue();
                node_stack.Push(node);
                foreach (IMaxTreeNode <float> child_node in node.GetNodeChildren())
                {
                    queue.Enqueue(child_node);
                }
            }

            while (node_stack.Count != 0)
            {
                IMaxTreeNode <float> node = node_stack.Pop();
                GenerateFeaturesNode(raster, node, features);
            }
        }
 public ImageRaster3DArrayWrapper(IImageRaster4D <RangeType> inner)
 {
     this.Raster = new Raster3DInteger(inner.Raster.Size0, inner.Raster.Size1, inner.Raster.Size2);
     this.inner  = inner;
 }
예제 #14
0
        //public static void DistanceTransformRBA(ImageRaster3D<bool> mask_image, ImageRaster3D<float> distance_image, float[] voxel_size)
        //{
        //    int size_x = mask_image.Raster.SizeX;
        //    int size_y = mask_image.Raster.SizeY;
        //    int size_z = mask_image.Raster.SizeZ;
        //    /* Apply the transform in the x-direction. */
        //    Parallel.For(0, size_z * size_y, plane_index =>
        //    {

        //        int z_index = plane_index / size_y;
        //        int y_index = plane_index - z_index * size_y;
        //        int element_index = size_x * ((size_y * z_index) + y_index);

        //        /* Project distances forward. */
        //        float distance = float.MaxValue;
        //        for (int x_index = 0; x_index < size_x; x_index++)
        //        {
        //            distance += voxel_size[0];
        //            /* The voxel value is true; the distance should be 0. */
        //            if (mask_image[element_index + x_index])
        //            {
        //                distance = 0.0f;
        //            }
        //            distance_image[element_index + x_index] = distance;
        //        }

        //        /* Project distances backward. From this point on we don't have to
        //         * read the source data anymore, since all object voxels now have a
        //         * distance assigned. */
        //        distance = float.MaxValue;
        //        for (int x_index = size_x - 1; x_index >= 0; x_index--)
        //        {
        //            distance += voxel_size[0];
        //            /* The voxel value is 0; the distance should be 0 too. */
        //            if (distance_image[element_index + x_index] == 0.0f)
        //            {
        //                distance = 0.0f;
        //            }
        //            /* Calculate the shortest distance in the row. */
        //            distance_image[element_index + x_index] = Math.Min(distance_image[element_index + x_index], distance);
        //        }
        //    });

        //    /* Apply the transform in the y-direction. */
        //    float size_1_sqr = ToolsMath.Sqr(voxel_size[1]);
        //    float size_1_inv = 1.0f / voxel_size[1];

        //    Parallel.For(0, size_z * size_x, plane_index =>
        //    {
        //        int z_index = plane_index / size_x;
        //        int x_index = plane_index - z_index * size_x;
        //        int element_index = z_index * size_y * size_x + x_index;
        //        float[] temp_1 = new float[size_y];
        //        /* Copy the column and square the distances. */
        //        for (int y_index = 0; y_index < size_y; y_index++)
        //        {
        //            temp_1[y_index] = ToolsMath.Sqr(distance_image[element_index + y_index * size_x]);
        //        }

        //        /* Calculate the smallest squared distance in 2D. */
        //        for (int y_index = 0; y_index < size_y; y_index++)
        //        {

        //            /* Calculate the smallest search range, i.e. y-im to y+im. */
        //            float distance = temp_1[y_index];
        //            if (distance == 0)
        //            {
        //                continue;
        //            }
        //            int im = (int)(size_1_inv * ToolsMath.Sqrt(distance));
        //            if (im == 0)
        //            {
        //                continue;
        //            }

        //            for (int j = Math.Max(0, y_index - im); j < Math.Min(size_y, y_index + im); j++)
        //            {
        //                if (temp_1[j] < distance) distance = Math.Min(distance, temp_1[j] + size_1_sqr * ToolsMath.Sqr(j - y_index));
        //            }

        //            distance_image[element_index + y_index * size_x] = distance;
        //        }
        //    });


        //    /* Apply the transform in the z-direction. */
        //    float size_2_sqr = ToolsMath.Sqr(voxel_size[2]);
        //    float size_2_inv = 1.0f / voxel_size[2];

        //    Parallel.For(0, size_y * size_x, plane_index =>
        //    {
        //        float[] temp_2 = new float[size_z];
        //        int y_index = plane_index / size_x;
        //        int x_index = plane_index - (y_index * size_x);
        //        int element_index = y_index * size_x + x_index;

        //        /* Copy the column. */
        //        for (int z_index = 0; z_index < size_z; z_index++)
        //        {
        //            temp_2[z_index] = distance_image[element_index + z_index * size_y * size_x];
        //        }

        //        /* Calculate the smallest squared distance in 3D. */
        //        for (int z_index = 0; z_index < size_z; z_index++)
        //        {
        //            /* Calculate smallest search range, i.e. z-im to z+im. */
        //            float distance = temp_2[z_index];
        //            if (distance == 0)
        //            {
        //                continue;
        //            }
        //            int im = (int)(size_2_inv * ToolsMath.Sqrt(distance));
        //            if (im == 0)
        //            {
        //                continue;
        //            }

        //            for (int j = Math.Max(0, z_index - im); j < Math.Min(size_z, z_index + im); j++)
        //            {
        //                if (temp_2[j] < distance) distance = Math.Min(distance, temp_2[j] + size_2_sqr * ToolsMath.Sqr(j - z_index));
        //            }

        //            distance_image[element_index + z_index * size_x * size_y] = distance;
        //        }
        //    });
        //}

        public static void DistanceTransform3DMediumRBA(ImageRaster3D <bool> mask_image, float[] voxel_size, ImageRaster3D <float> distance_image)
        {
            IRaster3DInteger raster = mask_image.Raster;
            int size_0 = mask_image.Raster.Size0;
            int size_1 = mask_image.Raster.Size1;
            int size_2 = mask_image.Raster.Size2;

            float[] locations_0 = new float[size_0];
            float[] locations_1 = new float[size_1];
            float[] locations_2 = new float[size_2];

            Parallel.For(0, size_0, index_0 =>
            {
                locations_0[index_0] = index_0 * voxel_size[0];
            });
            Parallel.For(0, size_1, index_1 =>
            {
                locations_1[index_1] = index_1 * voxel_size[1];
            });
            Parallel.For(0, size_2, index_2 =>
            {
                locations_2[index_2] = index_2 * voxel_size[2];
            });

            // Apply the transform in the x-direction
            //for (int plane_index = 0; plane_index < size_z * size_y; plane_index++)
            //{
            Parallel.For(0, size_2 * size_1, plane_index =>
            {
                int index_2 = plane_index / size_1;
                int index_1 = plane_index % size_1;

                // Upwards pass
                float added_distance = float.PositiveInfinity;
                for (int index_0 = 0; index_0 < size_0; index_0++)
                {
                    int element_index = raster.GetElementIndex(index_0, index_1, index_2);
                    added_distance   += voxel_size[0];
                    /* The voxel value is true; the distance should be 0. */
                    if (mask_image[element_index])
                    {
                        added_distance = 0.0f;
                    }
                    distance_image[element_index] = ToolsMath.Sqr(added_distance);
                }


                if (distance_image.GetElementValue(size_0 - 1, index_1, index_2) < float.PositiveInfinity)
                {
                    // Downwards pass
                    added_distance = float.PositiveInfinity;
                    for (int index_0 = size_0 - 1; index_0 >= 0; index_0--)
                    {
                        int element_index = raster.GetElementIndex(index_0, index_1, index_2);
                        added_distance   += voxel_size[0];
                        /* The voxel value is 0; the distance should be 0 too. */
                        if (distance_image[element_index] == 0.0f)
                        {
                            added_distance = 0.0f;
                        }
                        /* Calculate the shortest distance in the row. */
                        distance_image[element_index] = Math.Min(distance_image[element_index], ToolsMath.Sqr(added_distance));
                    }
                }
            });


            // Apply the transform in the y-direction
            //for (int plane_index = 0; plane_index < size_0 * size_2; plane_index++)
            //{
            Parallel.For(0, size_2 * size_0, plane_index =>
            {
                int index_0 = plane_index % size_0;
                int index_2 = plane_index / size_0;

                float[] temp_1 = new float[size_1];
                for (int index_1 = 0; index_1 < size_1; index_1++)
                {
                    temp_1[index_1] = distance_image.GetElementValue(index_0, index_1, index_2);
                }

                // Upwards pass
                for (int index_1 = 0; index_1 < size_1; index_1++)
                {
                    int element_index = raster.GetElementIndex(index_0, index_1, index_2);
                    for (int index_1_inner = index_1 + 1; index_1_inner < size_1; index_1_inner++)
                    {
                        if (distance_image.GetElementValue(index_0, index_1_inner, index_2) <= distance_image[element_index])
                        {
                            break;
                        }
                        float distance = distance_image[element_index] + ToolsMath.Sqr((index_1_inner - index_1) * voxel_size[1]);
                        if (distance < temp_1[index_1_inner])
                        {
                            temp_1[index_1_inner] = distance;
                        }
                    }
                }

                //Downwards pass
                for (int index_1 = size_1 - 1; index_1 >= 0; index_1--)
                {
                    int element_index = raster.GetElementIndex(index_0, index_1, index_2);
                    for (int index_1_inner = index_1 - 1; index_1_inner >= 0; index_1_inner--)
                    {
                        if (distance_image.GetElementValue(index_0, index_1_inner, index_2) <= distance_image[element_index])
                        {
                            break;
                        }
                        float distance = distance_image[element_index] + ToolsMath.Sqr((index_1 - index_1_inner) * voxel_size[1]);
                        if (distance < temp_1[index_1_inner])
                        {
                            temp_1[index_1_inner] = distance;
                        }
                    }
                }

                for (int index_1 = 0; index_1 < size_1; index_1++)
                {
                    distance_image.SetElementValue(index_0, index_1, index_2, temp_1[index_1]);
                }
            });



            // Apply the transform in the z-direction. */
            //for (int plane_index = 0; plane_index < size_x * size_y; plane_index++)
            //{
            Parallel.For(0, size_1 * size_0, plane_index =>
            {
                int index_0    = plane_index % size_0;
                int index_1    = plane_index / size_0;
                float[] temp_2 = new float[size_2];
                for (int index_2 = 0; index_2 < size_2; index_2++)
                {
                    temp_2[index_2] = distance_image.GetElementValue(index_0, index_1, index_2);
                }

                // Upwards_pass
                for (int index_2 = 0; index_2 < size_2; index_2++)
                {
                    int element_index = raster.GetElementIndex(index_0, index_1, index_2);
                    for (int index_2_inner = index_2 + 1; index_2_inner < size_2; index_2_inner++)
                    {
                        if (distance_image.GetElementValue(index_0, index_1, index_2_inner) <= distance_image[element_index])
                        {
                            break;
                        }
                        float distance = distance_image[element_index] + ToolsMath.Sqr((index_2_inner - index_2) * voxel_size[2]);
                        if (distance < temp_2[index_2_inner])
                        {
                            temp_2[index_2_inner] = distance;
                        }
                    }
                }

                // Downwards pass
                for (int index_2 = size_2 - 1; index_2 >= 0; index_2--)
                {
                    int element_index = raster.GetElementIndex(index_0, index_1, index_2);
                    for (int index_2_inner = index_2 - 1; index_2_inner >= 0; index_2_inner--)
                    {
                        if (distance_image.GetElementValue(index_0, index_1, index_2_inner) <= distance_image[element_index])
                        {
                            break;
                        }
                        float distance = distance_image[element_index] + ToolsMath.Sqr((index_2 - index_2_inner) * voxel_size[2]);
                        if (distance < temp_2[index_2_inner])
                        {
                            temp_2[index_2_inner] = distance;
                        }
                    }
                }

                //Fill and root
                for (int index_2 = 0; index_2 < size_2; index_2++)
                {
                    distance_image.SetElementValue(index_0, index_1, index_2, ToolsMath.Sqrt(temp_2[index_2]));
                }
            });
        }
예제 #15
0
 public ImageRaster3D(IRaster3DInteger raster, RangeType value)
     : this(raster.Size0, raster.Size1, raster.Size2, value)
 {
 }
예제 #16
0
        public static void DistanceTransform3DOosterbroekRBA(ImageRaster3D <bool> mask_image, float[] voxel_size, ImageRaster3D <float> distance_image_sqr)
        {
            // fetch some initial data
            IRaster3DInteger raster = mask_image.Raster;
            int size_0 = mask_image.Raster.Size0;
            int size_1 = mask_image.Raster.Size1;
            int size_2 = mask_image.Raster.Size2;

            float [] locations_0 = new float[size_0];
            float [] locations_1 = new float[size_1];
            float [] locations_2 = new float[size_2];
            Parallel.For(0, size_0, index_0 =>
            {
                locations_0[index_0] = index_0 * voxel_size[0];
            });
            Parallel.For(0, size_1, index_1 =>
            {
                locations_1[index_1] = index_1 * voxel_size[1];
            });
            Parallel.For(0, size_2, index_2 =>
            {
                locations_2[index_2] = index_2 * voxel_size[2];
            });

            //Initials pass for zeros and infs
            Parallel.For(0, distance_image_sqr.ElementCount, element_index =>
            {
                if (mask_image[element_index])
                {
                    distance_image_sqr[element_index] = 0;
                }
                else
                {
                    distance_image_sqr[element_index] = float.PositiveInfinity;
                }
            });

            // Apply the transform in the x-direction
            Parallel.For(0, size_2 * size_1, plane_index =>
            {
                int index_1 = plane_index % size_1;
                int index_2 = plane_index / size_1;

                float[] start     = new float[size_0];
                float[] locations = new float[size_0];
                float[] offsets   = new float[size_0];

                int curve_index = -1;

                //Curve pass
                for (int index_0 = 0; index_0 < size_0; index_0++)
                {
                    curve_index = ComputeCurves(distance_image_sqr, index_0, index_1, index_2, index_0, locations_0, start, locations, offsets, curve_index);
                }

                if (curve_index != -1)
                {
                    //if index == -1 then no curves were build and all are positive infinity
                    for (int index_0 = size_0 - 1; index_0 >= 0; index_0--)
                    {
                        // Compute pass (backwards)
                        curve_index = ComputeDistance(distance_image_sqr, index_0, index_1, index_2, index_0, locations_0, start, locations, offsets, curve_index);
                    }
                }
            });

            // Apply the transform in the y-direction
            Parallel.For(0, size_2 * size_0, plane_index =>
            {
                int index_0 = plane_index % size_0;
                int index_2 = plane_index / size_0;

                float[] start     = new float[size_1];
                float[] locations = new float[size_1];
                float[] offsets   = new float[size_1];

                int curve_index = -1;

                //Curve pass
                for (int index_1 = 0; index_1 < size_1; index_1++)
                {
                    curve_index = ComputeCurves(distance_image_sqr, index_0, index_1, index_2, index_1, locations_1, start, locations, offsets, curve_index);
                }

                if (curve_index != -1)
                {
                    //if index == -1 then no curves were build and all are positive infinity
                    for (int index_1 = size_1 - 1; index_1 >= 0; index_1--)
                    {
                        // Compute pass (backwards)
                        curve_index = ComputeDistance(distance_image_sqr, index_0, index_1, index_2, index_1, locations_1, start, locations, offsets, curve_index);
                    }
                }
            });

            // Apply the transform in the z-direction. */
            Parallel.For(0, size_1 * size_0, plane_index =>
            {
                int index_0 = plane_index % size_0;
                int index_1 = plane_index / size_0;

                float[] start     = new float[size_2];
                float[] locations = new float[size_2];
                float[] offsets   = new float[size_2];

                int curve_index = -1;

                //Curve pass
                for (int index_2 = 0; index_2 < size_2; index_2++)
                {
                    curve_index = ComputeCurves(distance_image_sqr, index_0, index_1, index_2, index_2, locations_2, start, locations, offsets, curve_index);
                }

                if (curve_index != -1)
                {
                    //if index == -1 then no curves were build and all are positive infinity
                    // Compute pass (backwards)
                    for (int index_2 = size_2 - 1; index_2 >= 0; index_2--)
                    {
                        // Compute pass (backwards)
                        curve_index = ComputeDistance(distance_image_sqr, index_0, index_1, index_2, index_2, locations_2, start, locations, offsets, curve_index);
                    }
                }
            });

            //Faniak pass for rooting
            Parallel.For(0, distance_image_sqr.ElementCount, element_index =>
            {
                distance_image_sqr[element_index] = ToolsMath.Sqrt(distance_image_sqr[element_index]);
            });
        }
예제 #17
0
 public ImageRaster3D(IRaster3DInteger raster)
     : base(raster)
 {
 }
        /** Scale and rotation invariant 3D features
         * As in disertation Fred Kawanuka page 79 & Wilkinson Roerding for scale invariant matrix
         */
        private void GenerateFeaturesNode(
            IRaster3DInteger raster,
            IMaxTreeNode <float> node,
            float [,] features)
        {
            int node_index = node.NodeIndex;
            // 1 get_size
            float size = node.CulmativeRealSize;

            // 2 compute geometric moments
            int [] elements = node.GetElementIndexArrayNodeReal();
            foreach (int element_index in elements)
            {
                raster.GetElementCoordinatesRBA(element_index, element_coordinates);
                features[node_index, IndexSX] += element_coordinates[0];
                features[node_index, IndexSY] += element_coordinates[1];
                features[node_index, IndexSZ] += element_coordinates[2];

                features[node_index, IndexSXX] += element_coordinates[0] * element_coordinates[0];
                features[node_index, IndexSYY] += element_coordinates[1] * element_coordinates[1];
                features[node_index, IndexSZZ] += element_coordinates[2] * element_coordinates[2];

                features[node_index, IndexSXY] += element_coordinates[0] * element_coordinates[1];
                features[node_index, IndexSXZ] += element_coordinates[0] * element_coordinates[2];
                features[node_index, IndexSYZ] += element_coordinates[1] * element_coordinates[2];
            }

            foreach (IMaxTreeNode <float> child in node.GetNodeChildren())
            {
                int child_node_index = child.NodeIndex;
                features[node_index, IndexSX] += features[child_node_index, IndexSX];
                features[node_index, IndexSY] += features[child_node_index, IndexSY];
                features[node_index, IndexSZ] += features[child_node_index, IndexSY];

                features[node_index, IndexSXX] += features[child_node_index, IndexSXX];
                features[node_index, IndexSYY] += features[child_node_index, IndexSYY];
                features[node_index, IndexSZZ] += features[child_node_index, IndexSZZ];

                features[node_index, IndexSXY] += features[child_node_index, IndexSXY];
                features[node_index, IndexSXZ] += features[child_node_index, IndexSXZ];
                features[node_index, IndexSYZ] += features[child_node_index, IndexSYZ];
            }

            // 2 compute covariance matrix (only the parts we will use note tha)
            float x_mean = features[node_index, IndexSX] / size;
            float y_mean = features[node_index, IndexSY] / size;
            float z_mean = features[node_index, IndexSZ] / size;

            covariance_matrix[0] = features[node_index, IndexSXX] - 2 * features[node_index, IndexSX] * x_mean + x_mean * x_mean * size;
            covariance_matrix[4] = features[node_index, IndexSYY] - 2 * features[node_index, IndexSY] * y_mean + y_mean * y_mean * size;
            covariance_matrix[8] = features[node_index, IndexSZZ] - 2 * features[node_index, IndexSZ] * z_mean + z_mean * z_mean * size;

            covariance_matrix[1] = features[node_index, IndexSXY] - features[node_index, IndexSX] * y_mean - features[node_index, IndexSY] * x_mean + x_mean * y_mean
                                   * size;
            covariance_matrix[2] = features[node_index, IndexSXZ] - features[node_index, IndexSX] * z_mean - features[node_index, IndexSZ] * x_mean + x_mean * z_mean
                                   * size;
            covariance_matrix[5] = features[node_index, IndexSYZ] - features[node_index, IndexSY] * z_mean - features[node_index, IndexSZ] * y_mean + y_mean * z_mean
                                   * size;
            ;

            covariance_matrix[0] = (covariance_matrix[0] + size / 12.0f) / (float)Math.Pow(size, 5.0 / 3.0);
            covariance_matrix[4] = (covariance_matrix[4] + size / 12.0f) / (float)Math.Pow(size, 5.0 / 3.0);
            covariance_matrix[8] = (covariance_matrix[8] + size / 12.0f) / (float)Math.Pow(size, 5.0 / 3.0);

            covariance_matrix[1] = covariance_matrix[1] / (float)Math.Pow(size, 5.0 / 3.0);
            covariance_matrix[2] = covariance_matrix[2] / (float)Math.Pow(size, 5.0 / 3.0);
            covariance_matrix[5] = covariance_matrix[5] / (float)Math.Pow(size, 5.0 / 3.0);

            // CollectionTools.print(covariance_matrix);
            // 3 compute eigenvalues
            ToolsMathMatrix3Float32.EigenvaluesSymetricRBA(covariance_matrix, eigenvalues);

            // compute non-compactness
            features[node_index, IndexNonCompactness] = eigenvalues[0] + eigenvalues[1] + eigenvalues[2];

            // 4 sort so that e_abs[0] < e_abs[1] < e_abs[2]
            eigenvalues[0] = Math.Abs(eigenvalues[0]);
            eigenvalues[1] = Math.Abs(eigenvalues[1]);
            eigenvalues[2] = Math.Abs(eigenvalues[2]);
            Array.Sort(eigenvalues);

            // 5 compute d values
            float d0 = (float)Math.Sqrt((eigenvalues[0] * 20));
            float d1 = (float)Math.Sqrt((eigenvalues[1] * 20));
            float d2 = (float)Math.Sqrt((eigenvalues[2] * 20));

            // 6 Compute features:

            // compute elongation differ
            features[node_index, IndexElongation] = eigenvalues[2] / eigenvalues[1];
            // compute flasness
            features[node_index, IndexFlatness] = eigenvalues[1] / eigenvalues[0];
            // compute sparceness
            features[node_index, IndexSparceness] = d0 * d1 * d2;

            features[node_index, IndexSize] = size;
        }
 public MaxTree3DAutoDualFloat(IImageRaster <IRaster3DInteger, float> image)
     : base(new AlgebraRealFloat32(), new MaxTreeBuilderSingleQueue <float>(), new TopologyElementRaster3D6Connectivity(image.Raster), image.GetElementValues(true), null)
 {
     this.raster = image.Raster;
 }