public void water_test() { Bitmap water = Accord.Imaging.Image.Clone(Resources.water); var dt = new DistanceTransform(); Bitmap result = dt.Apply(water); Assert.AreEqual(111.364265, dt.MaximumDistance, 1e-5); Assert.AreEqual(new IntPoint(436, 310), dt.UltimateErodedPoint); Assert.IsNotNull(result); float[] distance1D; new ImageToArray().Convert(result, out distance1D); float[][] distance; new ImageToMatrix().Convert(result, out distance); Assert.AreEqual(distance1D.Sum(), distance.Sum()); float[][] distances2 = Jagged.Reshape(dt.Pixels, result.Height, result.Width); float actual = distances2[84][533]; float expected = 1.4142135f; Assert.AreEqual(expected, actual); }
/// <summary> /// Processes the filter. /// </summary> /// <param name="image">The image.</param> protected override void ProcessFilter(UnmanagedImage image) { if (image.PixelFormat != PixelFormat.Format8bppIndexed) { throw new UnsupportedImageFormatException("Binary Watershed only works in grayscale (binary) images"); } int width = image.Width; int height = image.Height; DistanceTransform dt = new DistanceTransform(this.distance); UnmanagedImage d = dt.Apply(image); // Convert 2D to 1D - ImageJ Compatibility float[] distance1D = dt.Pixels; float[][] distance = Jagged.Reshape(distance1D, height, width); Debug.Assert(distance1D.Length == d.Size); Debug.Assert(distance.GetTotalLength() == d.Size); // Make directions offsets makeDirectionOffsets(width); byte[] back = new byte[width * height]; // Find the maxima long[] maxPoints = getSortedMaxPoints(distance, distance1D, back, 0, dt.MaximumDistance, -808080.0); // Mark the maxima locations float maxSortingError = 1.1f * SQRT2 / 2f; this.maxPoints = analyseAndMarkMaxima(distance1D, back, maxPoints, tolerance, maxSortingError, width, height); // Transform em 8bit 0..255 byte[] outImage = make8Bit(distance, back, dt.MaximumDistance, -808080.0, width, height); cleanupMaxima(outImage, back, maxPoints, width, height); watershedSegment(outImage, width, height); watershedPostProcess(outImage); unsafe { int offset = image.Offset; byte *dst = (byte *)image.ImageData; for (int y = 0, k = 0; y < height; y++) { for (int x = 0; x < width; x++, dst++, k++) { *dst = outImage[k]; } dst += offset; } } }