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)); } }
public ImageRaster3D( IRaster3DInteger raster, RangeType[] image, bool copy_array) : base(raster, image, copy_array) { }
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 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; }
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 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; } }
//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 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); }
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)); }
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; }
//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])); } }); }
public ImageRaster3D(IRaster3DInteger raster, RangeType value) : this(raster.Size0, raster.Size1, raster.Size2, value) { }
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]); }); }
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; }